Contador de pulsos PIC16F628A LCD PBP Pro

Buenas, buenas, este es mi primer post así que voy al grano.

Diseñe un contador de pulsos con un pic 16f628a + un LCD, para una maquina que tiene que cortar etiquetas, (Programado en su totalidad con pic basic pro) la consigna es que del eje del bobinador se van a tomar 6 pulsos cada 1 metro.
Les comento que el proyecto lo tengo prácticamente terminado salvo un pequeño detalle, al final lo cuento...

Código:
cmcon = 7

DEFINE  OSC         4       ; Definir que se trabajará con 4MHz. (Osc. Interno)
define  LCD_DREG    PORTA
define  LCD_DBIT    0
define  LCD_RSREG   PORTB
define  LCD_RSBIT   1
define  LCD_EREG    PORTB
define  LCD_EBIT    3

sube var portb.5                   'Prog = portb 5 entrada sube
baja var portb.6                   'Prog = portb 6 entrada sube
sensor var porta.4                 'Sensor = porta 4 entrada sensor
rele var portb.2                   'Para = portb 2 salida rele
xcien var porta.6                  'Inicia = porta 6 inicia toda la secuencia
xuno var porta.7                   'Sube = porta 7 entrada pulsador

metro var word                     'Convierto a metro en una variable word
metrop var word                    'Convierto a metrop en una variable word
cantidad var word                  'Convierto a cantidad en una variable word
cantidadp var word                 'Convierto a cantidadp en una variable word
metrom var word

metro=0                            'Seteo la variable metro en 0
cantidad=0                         'Seteo la variable cantidad en 0

Principio:
    INTCON = %11100000             'Modifico las opciones del timer0 y lo 
    OPTION_REG = %00111000         'configuro como contador. Tomo los pulsos del 
    TMR0 = 0                       'PortA4. Seteo el registro TMR0 en "0" 
    call retardo                   'retardo para esperar que funcione el LCD
    LCDOUT $FE, 1,"Contador"       'limpiar pantalla y sacar el texto Contador
    call retardo2
    LCDOUT $FE, 1
    goto Inicio

Inicio:
    metro = TMR0      
    metrop = metro / 6 
    lcdout $FE, $C0, dec metrop
    lcdout $FE, $C5,"Mts"
    lcdout $FE, $85,"Mts"
    low rele
    if sube = 1 then subir
    if baja = 1 then bajar
    goto comparar

Comparar:
    if cantidadp = metrop then
        TMR0 = 0
        lcdout $FE, $Cc,"Para"
        high rele
        call retardo2
        lcdout $FE, $Cc,"    "
        lcdout $FE, $C0,"     "
        goto Inicio
    endif

Subir:
    if xuno = 1 then
        call retardo
        cantidad = cantidad + 6
        cantidadp = cantidad / 6
        call escribir              'pasar al comienzo de la segunda línea
    else
        if xcien = 1 then
            call retardo
            cantidad = cantidad + 600
            cantidadp = cantidad / 6
            call escribir
        endif
    endif
    goto inicio

Bajar:
    if xuno = 1 then
        call retardo
            cantidad = cantidad - 6
            cantidadp = cantidad / 6
        call escribir              'pasar al comienzo de la segunda línea
    else
        if xcien = 1 then
            call retardo
                cantidad = cantidad - 600
                cantidadp = cantidad / 6
            call escribir
        endif
    endif
    goto inicio

retardo:
    pause 250
    return

retardo2:
    pause 3000
    return

Escribir:
    LCDOUT $FE, 1, dec cantidadp
    return

end

Primero, para leer los pulsos use la función If con pésimos resultados ya que perdía muchos pulsos cuando probaba con velocidades de +/-3000 revoluciones (50Hz) lo que hacia el programa totalmente impreciso, sirvió para probar mi proyecto pero lo descarte porque no era lo que necesitaba.

Segundo, aprendí a usar las interrupciones si bien la precisión mejoro tenia el problema de que a veces contaba pulsos de mas, mas que nada cuando variaba la velocidad de los pulsos, así que también lo tuve que descartar

Tercero, gracias a este foro aprendí a usar el timer0 con el que logre la cuenta perfecta y el proyecto funciono de 10

Ahora viene el pequeño detalle feliz de la vida por que el proyecto había funcionado perfecto lo pruebo, cuento 1 metro cuento 2 metros cuento 12 metros y digo ya fue, le voy a dar la cuenta máxima que me permitía la variable de comparación que para la maquina es 10992 metros (variable de 16 bit) (Acuérdense que cada 6 pulsos es 1 metro) pero acá volví a tener problemas ya que el contador me cuenta únicamente hasta 42 metros (timer0 = 8 bit).

Ahora, ¿que intente? Hacer desbordar el timer0 cada 6 pulsos. No pude
trate de usar el timer1 que es de 16 bit y tampoco pude, es mas leyendo acá en el foro lo único que Yo encontré fue para usarlo con el contador interno nunca externo. Así que hasta acá llegue. Si alguien me da una mano con este problemilla le voy a estar muy agradecido, ya que no use los divisores del timer0 porque quiero que el proyecto sea totalmente adaptable a los pulsos que yo quiero contar por vuelta como en este caso 6.

Desde ya muchas gracias y voy a estar atento a sus sugerencias y dudas con respecto a lo que escribí.
 

Adjuntos

  • contador-de-metros.jpg
    contador-de-metros.jpg
    49 KB · Visitas: 70
Me parece que te las estás complicado mucho con los timers.
En realidad son muy sencillos de utilizar, sólo es leer la hoja de datos.

Mira este sencillo programa usando el contador por el pin T0CKI (Timer 0 Clock Input)
PHP:
; Definición de pines para la pantalla.
Define LCD_DREG PORTA        ; Puerto de datos.
Define LCD_DBIT     0        ; Bit de inicio de datos.
Define LCD_RSREG PORTB       ; Puerto de RS (Register Select)
Define LCD_RSBIT    1        ; Pin para RS
Define LCD_EREG PORTB        ; Puerto de E (Enable)
Define LCD_EBIT     3        ; Pin para E

; Declaración de variables.
Ticks       Var Byte
Contador    Var Word

Inicio:
    CMCON = 7                ; Comparadores analógicos OFF
    OPTION_REG = %10110000   ; RBPU = OFF, T0CKI, Falling Edge, Prescaler: 1:2
    
    Clear
    LCDOut $FE,$84,"Contador"
    TMR0 = 0
    
    
Programa:
    Ticks = TMR0                        ; Leer el valor del Timer 0
    If PORTB.5 = 0 Then                 ; Si RB5 = 0, el conteo será ascendente.
        If Ticks = 3 Then               ; Si "Ticks" llega a 3 (Pre: 1:2 = 6 Pulsos)
            TMR0 = 0                    ; Resetear el Timer 0
            Contador = Contador + 1     ; Incrementar "Contador"
        EndIf
    Else                                ; Si RB5 = 1, el conteo será descendente.
        If Ticks = 3 Then
            TMR0 = 0
            Contador = Contador - 1
        EndIf
    EndIf
    LCDOut $FE,$C3,Dec5 Contador," Mts."
    GoTo Programa
    
    End
Como se usa una variable tipo Word, el conteo máximo será de 65535
Como el prescaler es de 1:2, el incremento se realiza cuando la variable "Ticks" llega a 3.

Este programa no tiene detección de desbordamiento, así que cuando la variable "Contador" se desborde, se reiniciará el conteo desde cero.
Y si el conteo se inicia de forma descendente, ocurrirá un desborde y el conteo se realizará desde 65535 hasta 0.

Tal vez te sirva.

Suerte.
 
Última edición:
yo no se programar en basic para pic

pero lo que yo hago para contar pulsos es con la interrupcion del CCP

variable contador
variable tiempo

interrupcion CCP
{
contador++;
}

timer 0
{
if (tiempo >= 1000) //cuando pasa 1 segundo "puse 1000 milisegundos"
{
imprimir en la LCD el contador en HZ

limpio mi contador con un 0
contador =0;
}
tiempo++;
}
 
Gracias por la ayuda, por mi cuenta probe lo que plantie de las interrupciones y no llegue al punto. Voy a probar tu ejemplo D@rkbytes.



If Ticks = 3 Then ; Si "Ticks" llega a 3 (Pre: 1:2 = 6 Pulsos)
TMR0 = 0 ; Resetear el Timer 0
Contador = Contador + 1 ; Incrementar "Contador"
EndIf
Perfecto la solucion de todos mis problemas, ahora lo unico que me queda es pulir mi codigo.
Muchas gracias a todos los que respondieron.
 
Última edición:
Atrás
Arriba