Contador con TMR0 mayor a 256.... es posible?

Hola gente buenas a todos, esperando que me puedan ayudar con un problema que tengo. Quiero hacer un contador con el TMR0 de mi pic 16f84a y visualizar este conteo en un lcd 16x2 pero quiero contar como 50,000 pulsos entonces diseñe un programa el cual separo en diferentes variables como miles,decenes,centena,unidades despues las juntos para poder manejar dicha cantidad pero solo me llega a 256 los 8bites(bytes):confused:
aqui el codigo me podria decir si lo que quiero es posible y si lo que hago es correcto.


Código:
unsigned int unid,dec,centenas,miles,cantidad,cnt[4],conteo[4];
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections

void main() {
OPTION_REG=0X38;
T0IF_BIT=0;
TMR0=0;
trisa=0;
TRISB=0X00;
PORTB=0X00;
Lcd_Init();
Lcd_Cmd(_LCD_CLEAR);               // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF);
centenas=0;
miles=0;
while(1){
       while(TMR0<=99)
         {
         dec=tmr0/10;
         unid=tmr0-(dec*10);
         cantidad=(miles*1000)+(centenas*100)+(dec*10)+unid;
         bytetostr(tmr0,cnt);
         bytetostr(cantidad, conteo);
         Lcd_Out(1,1,"inicio");
         Lcd_out(1,10,conteo);
         lcd_out(2, 2,cnt);
         }
         TMR0=0;
         unid=0;
         dec=0;
         if(centenas<9)
            {
            centenas=centenas+1;
            }
         else
           {
           centenas=0;
           miles=miles+1;
           }
        }
}
gracias de antemano.
 
El Timer 0 del PIC16F84, es de 8 bits. Desborda al llegar a 255.
Lo que se hace es usar una división con el prescaler para aumentar el factor de desborde.
Con cada desborde puedes incrementar las variables en el servicio de interrupción.
 
Quiero detallar un poco el comentario de D@rkbytes: cada vez que TMR0 desborde, se puede activar una interrupción que se encargue de incrementar registros de usuario. Es ahí donde puedes llevar la cuenta de los cinco dígitos (por separado) o dos bytes (como un entero de 16 bits, capaz de contar hasta los 65535).

Desde fuera, puedes reiniciar los contadores cuando quieras. Si quieres precisión absoluta, primero paras TMR0, reinicias contadores, y pones en marcha TMR0 cuando quieras volver a contar.

Y la rutina de presentación accede a los contadores y hace las transformaciones para pasarlos a decimal/BCD/displays. Esto también se podría hacer de forma periódica, con otro temporizador.

Y... hay otra solución... usar TMR1 para que la cuenta se lleve con 16 bits ;)
 
El detalle es que el PIC16F84 solo tiene un timer de 8 bits, si fuera un PIC16F628A podría usar el de 16bit.

Por otra parte no entiendo que quiere hacer, tendría que ver la hoja de datos para ver como corre el timer con esa configuración (si es que corre). Y estas indicando un while(<=99), ¿Qué pasará cuando el temporizador pase ese valor? Nada, perderás 156 pulsos hasta que desborde. Y por ultimo, ¿A qué frecuencia quieres cobrar los pulsos?

Ok, ya leí la datasheet, por lo que vi estas usando reloj externo sin prescaler, pero un error, tienes el puerto A declarado como todo salida, debes asignar RA4 como entrada o no tendrás reloj.

TRISA = TRISA4;

Esto unid=tmr0-(dec*10); es más bonito escrito unid=tmr0%10;

Luego el if está mal, y seria conveniente primero realizar los cálculos y luego convertir en string.

Por otra parte puedes simplemente tomar el valor del contador y sumarlo a un entero de 16 bits sin hacer separación, dejas que el compilador se encargue de ello, y después reinicias el contador, no se para que necesitarías los números separados.
 
Última edición:
Coincido con JoaquinFerrero pero creo que el pic16f84a no tiene timer1 no me acuerdo ya que me canse de los pic y me pase a arduino tardas muchisimo menos en ve resultados si es ue los necesitas rapido, utiliza el preescaler por 16 con un crystal de 4MHz ,no se que compilador estas usando pero no es CCS...no me queda claro que quieres hacer lo que si es seguro es que aunque logres mandar al LCD la cuenta de 0 a 50000 como dices no vas a ver nada por que es rapidísimo,segundo utiliza la interrupción timer 0 y disparala cada una decena de pulsos por ej. cargando con 245 el timer 0 cada vez y despues desde el programa principal vas incrementando decenas ,centanas etc, etc al final utilizas una variable tipo long y listo para escribir en el LCD
 
El pic16f84 solo tiene un timer de 8bits, lo de mas es historia. Puede ser contador o temporizador y tiene sus correspondientes prescalares. Ya es cuestión de "beto peludo" quemar pestaña.
 
hola gracias a todos por la ayuda y los consejos, si el 16f84a solo tiene 8bites de contador, tambien se que desborda a 255 pero si le mete el preescaler no podre mostrar el numero real o no eh encontrado la manera de hacerlo, el while solo lo pongo hasta 99 para poder controlar las variables separadas, por que separadas? es la manera que se me ocurrio de que pudiera llegar a mas de 255 despues las uno para poder trabajar con dicha variable. Me dicen que el if esta mal pero no entiendo en que. Hice un programa hoy en el trabajo el cual no ocupo el contador si no que pregunto si una entrada esta en 1 si lo esta una bandera pasa de 0 a 1 y una variable tendra un incremento en 1 y para que la bandera pase a 0 la entrada tendra qeu pasar de 1 a 0 y asi mismo la bandera pasa a 0 para volver a contar uno mas.
el progrmaa qeu utilizo es Mikroc es con el que el profesor nos daba sus clases.
 
Hola beto_peludo, te comento que con un poco de artilugios se puede lograr el contador sin mayor problema.
Lo primero que se me ocurrió es usar la interrupción externa para el contador, pero luego lo pensé mejor y decidí hacer un ejemplo con el timer0 como contador.
Código:
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections
unsigned short contador=0;

void interrupciones() iv 0x0004 ics ICS_AUTO
{
   if(intcon.t0if)
   {
      contador++;
      intcon.t0if=0;
   }
}

void main()
{
   unsigned int conteo;
   char conteo_txt[6];
   tmr0=0;
   option_reg=0b11111111; //timer0 como contador de flancos de bajada
   intcon=0b10100000;     //interruocopn del timer0 habilitado
   Lcd_Init();
   Lcd_Cmd(_LCD_CLEAR);
   Lcd_Cmd(_LCD_CURSOR_OFF);
   lcd_out(1,1,"Conteo:");
   while(1)
   {
      conteo=contador<<8|tmr0;
      wordtostrwithzeros(conteo,conteo_txt);
      lcd_out(1,8,conteo_txt);
   }
}
Sin título.png
 
if(centenas<9) está mal por que en cada ciclo de cumple, y cuando no se cumple lo reinicias, así que siempre está contando en lugar de contar al desbordar las decenas. También espero que consideres el tiempo que le toma al PIC hacer todo y que se le escapen pulsos si la frecuencia es muy alta, aún no has dicho que medirás.

Yo recomendaba que directamente hicieras
unsigned int contador += tmr0;
tmr=0;

Así sumas lo del timer cada vez y solo lo usas como búfer para no perder pulsos
 
Última edición:
hola muchas gracias por sus respuestas perdón por la tardanza pero ni siquiera eh tenido contacto con el Internet de tanto trabajo, probare la programación santi muchas gracias.
Nuyel contare numero de vueltas que da un cilindro de cartón en el cual se va llenando con hilo, eso que comentas de tenerlo solo como bufer es interesante lo intentare muchas gracias
 
Atrás
Arriba