Autor Tema: Contar ciclos entre pulsos de sensores diferentes!  (Leído 2914 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Contar ciclos entre pulsos de sensores diferentes!
« en: 20 de Agosto de 2009, 08:01:31 »
Hola,

Estoy estoy intentando montar un asm para un 16f877, en el cual tengo dos sensores digitales. Uno es un hall effect de flanco descendente y otro un pulso de flanco ascendente de de un pequeño circuito con LM555.
Lo que intento es contar el tiempo entre el pulso descendente y pulso ascendente, pero no se cual es la mejor forma de hacer funcionar el contador. Me gustaría que me aconsejarais la mejor forma.

LOOP                    btfsc   SN1
                            goto    LOOP             ; Wait for Ignition Low
waitHigh                btfss   SN2            ;
                            goto    waitHigh         ; Wait for Ignition high

Normalmente suelo usar este codigo para contar pulsos, pero del mismo sensor.
Sugerencias serán bien recibidas, Gracias.


Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #1 en: 20 de Agosto de 2009, 09:08:57 »
Una manera puede ser la siguiente, habiendo establecido el timer1 en 1:1:

Código: ASM
  1. btfsc   SN1             ; Espereramos flanco descendente.-
  2.         goto    $-1
  3.         clrf    TMR1H           ; Borramos Timer
  4.         clrf    TMR1L
  5. ;       bcf     PIR1,TMR1IF     ; Si el timer1 no es suficiente para medir el pulso..
  6. ;       bsf     STATUS,RP0      ; ocurrira overflow. En este caso se puede usar..
  7. ;       bsf     PIE1,TMR1IE     ; la interrupción para contar la cantidad..
  8. ;       bsf     STATUS,RP0      ; de overflow.
  9. ;       clrf    OVERFLOW
  10.  
  11.         btfss   SN2             ; Esperamos flanco ascendente.-
  12.         goto    $-1
  13.         movfw   TMR1L           ; Capturamos valor del timer1
  14.         movwf   TIEMPO_L
  15.         movfw   TMR1H  
  16.         movwf   TIEMPO_H
  17. ;       bsf     STATUS,RP0      ; Deshabilitamos interrupción.
  18. ;       bcf     PIE1,TMR1IE     ;
  19. ;       bsf     STATUS,RP0      ;


La idea es por medio del timer1 registrar el tiempo transcurrido entre flancos. Si el tiempo entre flancos es tal que no alcanza con un solo ciclo del timer deberás utilizar interrupción por timer1 para incrementar un registro adicional que contará los overflow.  El tiempo final será:

Tiempo=(OVERFLOW*65536 + (TIEMPO_H*256+TIMEPO_L))*Tcy

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #2 en: 20 de Agosto de 2009, 17:32:04 »
Gracias por responder Suky,

Si, más o menos lo que estaba pensando yo. El overflow no hace falta porque no llegará usar los 16bits.
¿Si pretendiera además saber el periodo del SN1 sería posible?, esto si que no se como hacerlo.

Gracias.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #3 en: 20 de Agosto de 2009, 19:11:13 »
Hola,

Como me has comentado, según el simulador funciona. Ahora me gustaría añadir poder tener el valor del periodo del sensor1, porque lo necesito como referencia para hacer los calculos.

El codigo queda así, si ven algún error, comentenlo. Gracias.

   list      p=16f877a            ; list directive to define processor
   #include <p16f877a.inc>        ; processor specific variable definitions
   
   __CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

;*****************************************************************************
; Vars, constants and defines
;*****************************************************************************
      
   CBLOCK   0x20                 ; RAM START ADDRESS
         perl                     ; low counter
         perh                     ; high counter
     

    ENDC
   

    #define   SN1    PORTC,2      ; Hall Effect pulse input Descendent
    #define   SN2    PORTC,1      ; Pulse input lm555 ascendent


    ERRORLEVEL -302 ; Don't show message 302 while compiling.
;*****************************************************************************
; Program start
;*****************************************************************************
                        ORG     0          ; RESET vector location
RESET                   goto    START
;*****************************************************************************
; Interrupt vector
;*****************************************************************************
                        ORG     4              ; interrupt vector location
;*****************************************************************************
; Interrupt Routine.
;*****************************************************************************


;*****************************************************************************

;*****************************************************************************
; Program start
;*****************************************************************************
START 
         clrf   PORTB
           bcf      STATUS,RP1
         bsf      STATUS,RP0          ;switch to bank 1
         movlw   B'00000000'           
            movwf   TRISB             ;port B all output
         movlw   B'00000110'          ;
         movwf   TRISC            ;input RC1 and RC2
         movlw   B'00000110'         
         movwf   ADCON1            ;all ports digital
         movlw   B'00000000'         
         movwf   TRISA            ;port A all output
         bcf      STATUS,RP0         ;switch back to bank 0    
            movlw   B'00100001'         ; Prescaler=1:4(1us) TMR1=ON
            movwf   T1CON               ; config T1CON
            bsf     INTCON,GIE
            bsf     INTCON,PEIE
            bsf     STATUS, RP0         ; Select bank 1
            bsf     PIR1,TMR1IF         ; unmask the timer0 interrupt
            bsf     PIE1,TMR1IE         ; and enable interrupt.
            bcf     STATUS, RP0         ; Select bank 0   

                       
LOOP        btfsc   SN1
            goto    LOOP                ; Wait for Ignition Low
         clrf   TMR1H            ; Borramos Timer
         clrf   TMR1L
waitHigh    btfss   SN2                 ;
            goto    waitHigh            ; Wait for Ignition high

            movfw   TMR1L              ; Store TMR1L and
            clrf    TMR1L              ; clear TMR1L for now.
            movwf   perl               ; Store the timers
            movfw   TMR1H
            clrf    TMR1H
            movwf   perh
   
       
         goto   LOOP      
;***************************************************************************************************
          END                           ; directive 'end of program'

Desconectado mtristan

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 395
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #4 en: 20 de Agosto de 2009, 19:57:01 »
.

Para guardar los valores de TMR1L y TMR1H deberías usar el opcode MOVF en lugar de MOVWF:
Código: [Seleccionar]
           BCF      T1CON,TMR1ON
           MOVF     TMR1L,W
           MOVWF    perl
           MOVF     TMR1H
           MOVWF    perh
Así como también detener el temporizador antes de copiar sus valores, pues al ser 2 registros los que copias puede pasar que se incremente uno mientras copias el otro.
Otra cosita, creo que la bandera de interrupción del TMR1 (PIR1,TMRIF) debería estar en 0 desde un principio, no en 1 como la ponés ahí.
Y no se a qué te referías con el 'periodo' del sensor1... así que esto es todo lo que puedo aportar  por ahora :).
Saludos.

When you see a good move, look for a better one (Emanuel Lasker)

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #5 en: 20 de Agosto de 2009, 20:49:36 »
movf Registro,w es lo mismo que movfw. Después no creo que sea necesario detener el Timer, y por eso se lee el primero TMR1L que varia más rápido.

Para medir el periodo utilizarías el mismo método, esperarías el flanco ascendente, el flanco descendente y nuevamente el flanco ascendente para medir el timer. Capaz en este caso si necesites del overflow.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado mtristan

  • Colaborador
  • PIC18
  • *****
  • Mensajes: 395
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #6 en: 20 de Agosto de 2009, 23:44:07 »
.

Me asombro de mi tontería  :oops:
No sabía de la existencia del MOVFW, creí que decía MOVWF.
Y sí, si hay que seguir contando pulsos lo mejor será dejar correr el timer.
Resultó que no fui de mucha ayuda, jaja.

When you see a good move, look for a better one (Emanuel Lasker)

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #7 en: 21 de Agosto de 2009, 05:46:55 »
Hola,

Ahora mismo lo que haces es esperar el pulso descendente del sensor1, y empieza a contar hasta que llegue el sensor2(De hecho habría que añadirle 2 ciclos a ese contador no?, ya que al limpiar el timer1 perdemos dos ciclos). Lo que pretendo además es contan ciclos entre pulsos del sensor1 (que son descendentes).
Pero aunque luego le ponga esperar otro descendente, debería guardar el valor del contador una vez encuentra el pulso del sensor2 y despues guardar el valor del contador para el periodo del sensor1, no es asi?.

LOOP        btfsc   SN1
               goto    LOOP              ; Wait for Ignition Low
               clrf   TMR1H               ; Borramos Timer
               clrf   TMR1L
waitHigh   btfss   SN2                 ;
               goto    waitHigh          ; Wait for Ignition high
               movfw   TMR1L          ; Store TMR1L and
               movwf   perl              ; Store the timers
               movfw   TMR1H
               movwf   perh
LOOP2      btfsc   SN1
               goto    LOOP2              ; Wait for Ignition Low
               movfw   TMR1L              ; Store TMR1L and
               clrf    TMR1L              ; clear TMR1L for now.
               movwf   perl1              ; Store the timers
               movfw   TMR1H
               clrf    TMR1H
               movwf   perh1
   
  Sería algo asi?, pero creo que así siempre se pierde el conteo de un pulso, no es así?. Llegaría uno negativo se empieza a contar hasta que llegue el positivo del sensor2, se guarda, se sigue contando hasta que llegue el segundo negativo y se guarda, pero del segundo al tercero no se sacan valores. no es así?.



movf Registro,w es lo mismo que movfw. Después no creo que sea necesario detener el Timer, y por eso se lee el primero TMR1L que varia más rápido.

Para medir el periodo utilizarías el mismo método, esperarías el flanco ascendente, el flanco descendente y nuevamente el flanco ascendente para medir el timer. Capaz en este caso si necesites del overflow.


Saludos!




Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #8 en: 21 de Agosto de 2009, 11:28:29 »
Esa es la idea, pero hay un  problemas. Si es seguro que S1 experimenta un flanco ascendente antes que S2 así como lo haces esta bien, pero sino debes esperarlo y después esperar el flanco descendente. Eso si los Clrf que colocas en el medio no lo hagas:
Código: ASM
  1. movfw   TMR1L              ; Store TMR1L and
  2.                movwf   perl1              ; Store the timers
  3.                movfw   TMR1H
  4.                movwf   perh1

Si para ninguno de los 2 periodos necesitas el overflow seria así:

T_entre_S1S2=((perh*256+perl)+2)*tcy

Per_S1=((perh1*256+perl1)+2)*tcy

Intentando ser lo más preciso agregando los 2 ciclos que no cuenta cuando se escribe el Timer segun datasheet.

Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #9 en: 21 de Agosto de 2009, 20:01:07 »
Hola,
Si, en principio no hay ningún problema con el overflow. No desbordará. Los sensores están fijados a unos 115º uno del otro, unicamente el sensor2 se mueve unos 10-15º, asi que siempre habrá un pulso negativo (sensor1), uno positivo (Sensor2) y otro negativo(Sensor1).
Probaré que tal va. Ya comentaré. Gracias por la ayuda.
Saludos.

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #10 en: 26 de Agosto de 2009, 11:24:31 »
Hola,

He estado probando el programa pero no me envia nada al serial. Puede ser que el problema este en el codigo de la configuracion del serial port y el envio de los datos. Los sensores funcionan, porque lo mire con el scope.

Cuelgo el programa, por si veis algun error.

Código: [Seleccionar]

list      p=16f877            ; list directive to define processor
#include <p16f877.inc>        ; processor specific variable definitions

__CONFIG _CP_OFF & _WDT_OFF & _BODEN_ON & _PWRTE_OFF & _HS_OSC & _LVP_OFF & _DEBUG_OFF & _CPD_OFF

; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.

;*****************************************************************************
; Vars, constants and defines
;*****************************************************************************
   
CBLOCK 0x20                ; RAM START ADDRESS
         perl                       ; low counter
         perh                       ; high counter
    perl2
perh2
    ENDC
   

    #define   SN1    PORTC,2        ; Hall Effect pulse input Descendent
    #define   SN2    PORTC,1        ; Pulse input lm555 ascendent


    ERRORLEVEL -302 ; Don't show message 302 while compiling.
;*****************************************************************************
; Program start
;*****************************************************************************
                        ORG     0 ; RESET vector location
RESET                   goto    START
;*****************************************************************************
; Interrupt vector
;*****************************************************************************
                        ORG     4   ; interrupt vector location
;*****************************************************************************
; Interrupt Routine.
;*****************************************************************************


;*****************************************************************************

;*****************************************************************************
; Program start
;*****************************************************************************
START 
clrf PORTB
  bcf STATUS,RP1
bsf STATUS,RP0 ; switch to bank 1
movlw B'00000000'      
            movwf TRISB ; port B all output
movlw B'00000110'    ;
movwf TRISC ; input RC1 and RC2
movlw B'00000110'
movwf ADCON1 ; all ports digital
movlw B'00000000'
movwf TRISA ; port A all output
bcf STATUS,RP0 ; switch back to bank 0
            movlw   B'00100001'     ; Prescaler=1:4(1us) TMR1=ON
            movwf   T1CON           ; config T1CON
            bsf     INTCON,GIE
            bsf     INTCON,PEIE
            bsf     STATUS, RP0     ; Select bank 1
            bsf     PIR1,TMR1IF     ; unmask the timer0 interrupt
            bsf     PIE1,TMR1IE     ; and enable interrupt.
            bcf     STATUS, RP0     ; Select bank 0

setbaud bcf STATUS,RP1 ; clear bank2,3
bsf STATUS,RP0 ; set bank 1
movlw D'51' ; brg val for 19200kbaud 16mhz xtal
movwf SPBRG
movlw B'00100100' ; snyc=0, brgh=1, enable Trans. txen,HighBaud
movwf TXSTA
bcf TRISC,6 ; set rc6 as output
bcf STATUS,RP0 ; switch to bank 0
movlw B'10000000' ; set spen bit of rcsta
movwf RCSTA
                       
loop        btfsc   SN1
            goto    loop            ; Wait for Ignition Low
            clrf    TMR1H           ; Clear Timer1
            clrf    TMR1L
waitHigh    btfss   SN2             ;
            goto    waitHigh        ; Wait for Ignition high
            movfw   TMR1L           ; Store TMR1L and
            movwf   perl            ; Store the timers
            movfw   TMR1H
            movwf   perh
loop2       btfsc   SN1
            goto    loop2           ; Wait for Ignition Low
            movfw   TMR1L           ; Store TMR1L and
            clrf    TMR1L           ; clear TMR1L for now.
            movwf   perl2           ; Store the timers
            movfw   TMR1H
            clrf    TMR1H
            movwf   perh2


sendpc movf perl,w ; Counter delay sensors low byte
call serial
movf perh,w ; Counter delay sensors high byte
call    serial
movf perl2,w      ; Counter period Hall Effect sensor low byte
call    serial
          movf perh2,w ; Counter period Hall Effect sensor high byte
call serial
goto loop

serial nop
          btfss PIR1,4 ; wait for txreg to empty
goto serial
movwf TXREG ; auto transmission
return
 
;***************************************************************************************************
    end                ; directive 'end of program'

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #11 en: 26 de Agosto de 2009, 12:00:07 »
Primero se debe borrar la bandera:
Código: ASM
  1. bcf     PIR1,TMR1IF     ; unmask the timer0 interrupt

Después veo que activaste la interrupción del timer1 pero no la tratas, si ocurre la interrupción el contador del programa apunta a 0x04 y si no encuentra nada que lo regrese sigue, y en tu caso reseta el programa.

Luego si vas a enviar y detectar el envío por poleo, utiliza en bit TRMT del registro TXSTA para saber si ya se ha enviado:
Código: ASM
  1. ;**** Se envia Dato ****
  2. Serial
  3.      bsf STATUS,RP0 ; Banco 1
  4.      btfss   TXSTA,TRMT   ; chequea si esta listo
  5.      goto $-1 ; Esperamos  a que se desocupe.-
  6.      bcf STATUS,RP0 ; Banco 0
  7.      movwf   TXREG ; envia Dato.-
  8.      return


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado josearrow

  • PIC10
  • *
  • Mensajes: 40
Re: Contar ciclos entre pulsos de sensores diferentes!
« Respuesta #12 en: 26 de Agosto de 2009, 13:34:52 »
Muchas gracias Suky!
Ahora funciona. Justamente tenia activada la interrupcion del timer1 y general  cuando no la estoy usando. Esto me ha pasado porque he copiado de otro proyecto que tenia.

Lo dicho, muchas gracias. :-/


 

anything