TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: jhozate en 09 de Julio de 2009, 17:30:50

Título: Entendiendo el TIMER0 en CCS
Publicado por: jhozate en 09 de Julio de 2009, 17:30:50
Bueno, resulta que me dispuse a entender el  manejo del TIMER0 en CCS, entonces como aun soy bastante novato pues todo lo hago a traves del PICwizard, el picwizard me arroja las opciones de poder configurar el prescaler:
(http://www.aquihayapuntes.com/images/stories/practicasPIC/recursos/tmr0Temp/prescalertmr0.png)
En donde entiendo que el timer se incrementará en "1 unidad" cada 2,4,8,16,32,64,128,256 y asi mismo el timer me muestra un overflow que seria el tiempo en que demoraria el TIMER0 en desbordarse.
Dicho lo anterior se tiene que:

prescaler     overflow
2                    512     uS
4                    1        mS aprox
8                    2        mS aprox
16                  4        mS aprox
32                  8.1     mS aprox
64                  16.3   mS aprox
128                32.7   mS aprox
256                65.5   mS aprox

ahora entonces para hacer la prueba de que todo lo que asumo es cierto hice el siguiente codigo, en donde configuré un prescaler de 8 con lo cual voy a obtener una interrupcion cada 2 mS aproximadamente, a partir de los 2 mS obtengo 1 Seg y muestro el incremento de una variable en el lcd
#INCLUDE "FLEX_LCD.C"

Código: CSS
  1. CHAR I=0;
  2. INT16 A;
  3.  
  4. #int_RTCC
  5. void  RTCC_isr(void)
  6. {
  7. A++;
  8. IF(A==500)                   // ha pasado 1 Seg?
  9.    {
  10.    A=0;                         //Si,repongo contador
  11.    I++;                         //incremento de variable a mostrar en lcd
  12.    }
  13. }
  14.  
  15. void main()
  16. {
  17.  
  18.    setup_adc_ports(NO_ANALOGS);
  19.    setup_adc(ADC_OFF);
  20.    setup_psp(PSP_DISABLED);
  21.    setup_spi(SPI_SS_DISABLED);
  22.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_8);
  23.    setup_timer_1(T1_DISABLED);
  24.    setup_timer_2(T2_DISABLED,0,1);
  25.    setup_comparator(NC_NC_NC_NC);
  26.    setup_vref(FALSE);
  27.    
  28.  
  29.    LCD_INIT();
  30.    enable_interrupts(INT_RTCC);
  31.    enable_interrupts(GLOBAL);
  32.    FOR(;;)
  33.     {
  34.     LCD_GOTOXY(1,1);
  35.     PRINTF(LCD_PUTC,"NUM %u",I);
  36.    
  37.     }
  38.  
  39.   }


simulando veo q funciona pero los tiempos no son muy exactos y al cabo de un tiempo el desfase puede ser considerable


ahora tambien hice otro programa cambiando el prescaler a 256, con lo cual obtendré un tiempo de overflow= 65.5 mS, entonces le cargo al timer el valor 195 y con esto obtengo un overflow de 49.92 mS aprox 50mS entonces lo unico que deberia hacer es cambiarle  el valor de la variable de control para saber si ya pasó un segundo, entonces seria asi:
Código: CSS
  1. #INCLUDE "FLEX_LCD.C"
  2.  
  3.  
  4. CHAR I=0;
  5. char A;
  6.  
  7. #int_RTCC
  8. void  RTCC_isr(void)
  9. {
  10. A++;
  11. IF(A==20)
  12.    {
  13.    A=0;
  14.    I++;
  15.    }
  16.      
  17. }
  18.  
  19.  
  20.  
  21. void main()
  22. {
  23.  
  24.    setup_adc_ports(NO_ANALOGS);
  25.    setup_adc(ADC_OFF);
  26.    setup_psp(PSP_DISABLED);
  27.    setup_spi(SPI_SS_DISABLED);
  28.    setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
  29.    setup_timer_1(T1_DISABLED);
  30.    setup_timer_2(T2_DISABLED,0,1);
  31.    setup_comparator(NC_NC_NC_NC);
  32.    setup_vref(FALSE);
  33.    
  34.  
  35.    LCD_INIT();
  36.    enable_interrupts(INT_RTCC);
  37.    enable_interrupts(GLOBAL);
  38.    SET_TIMER0(195);
  39.    FOR(;;)
  40.    {
  41.    LCD_GOTOXY(1,1);
  42.    PRINTF(LCD_PUTC,"NUM %u",I);
  43.    
  44.    }
  45.  
  46.   }

supongo q en teoria deberia ser lo mismo..?¿?¿..pero de esta forma en mas inexacto el tiempo...por qué? como puedo hacer para ajustar mejor estos tiempos?
Título: Re: Entendiendo el TIMER0
Publicado por: juansi en 09 de Julio de 2009, 18:46:54
amigo jhozate, en principio yo tamien soy novato, pero voy a intentar ayudarte un poco.

Hay q tener en cuenta el cristal q usas(el oscilador interno es impreciso), tambien q nuestro pic aumenta el preescaler en 1 cada cuatro ciclos de relog, te aconsejo q mires los ejemplos de vszener "Ejemplitos en C para 16F648A", yo aprendi con ellos, ademas tiene un ejemplo con ajuste fino de un segundo.
Título: Re: Entendiendo el TIMER0
Publicado por: jhozate en 09 de Julio de 2009, 18:52:23
si de hecho yo tambien voy aprendiendo con ese hilo, pero la verdad no entiendo q se debe hacer y que hace vszener para hacer el ajuste del timer0, yo hace ratico vengo del assembler y ahí los tiempos son muy precisos, entonces no se si esas perdidas se podrian deber a q el programa es en C
Título: Re: Entendiendo el TIMER0
Publicado por: Suky en 09 de Julio de 2009, 19:11:12
En el último ejemplo, antes de salir de la interrupción debes volver a cargar con 195 para que se interrumpa otra vez cada 50ms :wink:
Título: Re: Entendiendo el TIMER0
Publicado por: jhozate en 09 de Julio de 2009, 19:25:54
 :mrgreen: si, sin embargo  se pierde tiempo ...supongo q es un error acumulativo de ms q con el tiempo se puede volver importante
Título: Re: Entendiendo el TIMER0
Publicado por: juansi en 09 de Julio de 2009, 19:45:48
recuerda q dentro de la interrupcion puedes ingeniarte otra variable para recuperar ese tiempo,tambien creo q hay cristales con los hercios justos para ajustar el timer.
Título: Re: Entendiendo el TIMER0
Publicado por: reiniertl en 13 de Julio de 2009, 11:26:15
TIMER0 + Escritura en TIMER0 <> Precisión

No se puede pretender tener precisión en la medición de tiempo utilizando este TIMER y escribiendo en él un valor de recarga. Las razones son varias:

Escribir en el TIMER implica cometer varios errores, algunos de ellos, con valores de tiempo que no se pueden medir, ni siquiera estimar.  Desde que el TIMER se desborda y pide interrupción, hasta que esta es atendida, puede transcurrir un tiempo variable, que depende de muchos factores, como por ejemplo:

*Tipo de instrucción que se está ejecutando (cuantos ciclos consume), Si está siendo atendida otra interrupción y durante ese proceso están deshabilitadas el resto, por lo tanto, no habrá posibilidad de atender la al TIMER0 hasta que termine la otra ISR.
*Existen además otras fuentes de error asociadas y más controlables, como el tiempo que toma escribir en el registro, los dos ciclos que consume el TIMER luego de ser escrito para comenzar a contar nuevamente, y que pueden ser tenidos en cuenta en una corrección del valor de recarga.

Las razones son una cuantas, y no creo que valga la pena enumerarlas todas, con las expuestas es más que suficiente.

Mi recomendaciones son

*Utilice TIMER0 sin recarga, siempre que se pueda
*Si desea utilizar TIMER0 con recarga por software de su registro de conteo, no lo haga pensando que obtendrá precisión en la medida de tiempo. Utilice este método para sincronizar procesos a intervalos regulares donde la precisión a lo largo del tiempo no sea una restricción de diseño (evite hacer relojes y cronómetros con este método)
*Si desea precisión, busque soluciones de temporización que incluyan hardware como elemento de conteo, que le garantice la precisión necesaria, por ejemplo TIMER2 o TIMER1+CCP en modo comparación.

Saludos
Reinier
Título: Re: Entendiendo el TIMER0
Publicado por: jhozate en 14 de Julio de 2009, 00:30:59
ya.. :?...entonces no puedo esperear a q el Timer0 en CCS sea muy preciso, pero entonces, quisiera entender este (http://www.todopic.com.ar/foros/index.php?topic=4530.msg38880#msg38880) ejemplo donde se hace un ajuste fino con el uso de una variable...no tengo claro el concepto o la estrategia a seguir
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: reiniertl en 15 de Julio de 2009, 08:52:21
No puedes esperar que este TIMER te de temporizaciones precisas de ninguna forma, excepto la que él por su propia naturaleza puede ofrecerte, es decir, contar desde 0 a 255, y provocar una petición de interrupción en su desbordamiento, uses el lenguaje que uses para programarlo.

Si modificas el registro de conteo para que el TIMER0 cuente un poco menos, digamos desde 100 a 255, porque si lo hace así te dará un período de interrupción más apropiado para lo que intentas hacer, se cometerán errores en la temporización, errores debido a la latencia del proceso de interrupción (tiempo que le toma al procesador comenzar a atender la interrupción luego de que esta se activa).

La latencia de la interrupción es el peor dolor de cabeza para este método porque es muy difícil predecir cuanto tiempo demorará el procesador en atender la interrupción, sobre todo si cuando el TIMER0 pide interrupción se está atendiendo a otra interrupción, ya que la forma más frecuente de atender interrupciones en PIC es enmascarar las interrupciones dentro de una ISR, lo que evita que las interrupciones se puedan anidar (así lo hace CCS por defecto). también depende de si la instrucción que se está ejecutando cuando llega el pedido de interrupción es de 1 o dos ciclos (como las de salto), de lo que le tome al proceso de discriminación de interrupciones decidir que es la del TIMER0 la que será atendida(recordemos que en PIC las interrupciones no son individualmente vectorizadas, existe un solo vector de interrupción y allí hay que decidir cual atender). Suma a ello que una vez en la ISR deberías leer el TIMER0 para saber cuantos períodos se han contado, hacer un cálculo de ajuste del valor de recarga, escribir el contador y esperar dos ciclos de máquina para que este recomience el conteo.

Muchas complicaciones para intentar conseguir una precisión que no se consigue. Ahora, esto no implica que este método se inútil, sino que hay que saber donde utilizarlo y donde NO.

Donde NO utilizarlo:
En aplicaciones que requieran temporizaciones precisas en un período largo de tiempo (entiéndase de 1 hora en adelante). Ya que los errores serán acumulativos y la temporización se verá afectada.

Ejemplos de estas aplicaciones:
Relojes calendarios
Cronómetros
Contadores largos que requieran precisiones de segundos (1 hora o más)

Donde sí tulizarla
Aplicaciones que requieran de tiempos relativamente precisos, pero donde la precisión a lo largo del tiempo no sea esencial, no importa la acumulación del error.

Ejemplos:
Sincronización de procesos (seteo y encuesta de banderas)
Temporización para procesos de encuesta como por ejemplo. Escribir una lámpara de 7 segmentos multiplexada, lectura de teclados, procesos de conversión con el AD (no siempre sirve, pero la mayoría de las veces sí)

Saludos
Reinier
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: czeiss en 01 de Octubre de 2009, 13:14:13
Hola, a todos.
Cuando he tratado interrupciones para generar tiempo precisos lo he hecho con codigo en asm. Y dentro de la interrupcion solo ha dejado lo necesario para marcar que se produjo la interrupcion.
Para ajustar la base de tiempo, lo puedes hacer con el MPLAB que tiene un contador de tiempo de instruccion por instruccion watch .. algo no recuerdo bien.
En CCS es muy dificil que genere una base de tiempo precisa, ya que agrega codigo extra cual no esta contabilizado en el tiempo total de la interrupcion.
Recuerda que cuando se ingresa a la interrupcion se desabilita y por el ende el tiempo de las intrucciones que se ejecutan dentro no se ha contabilizado.
Título: Configuracion tmr0 18f452 en 16 bit
Publicado por: dieguez07 en 13 de Octubre de 2009, 08:10:22
Hola a todos. he intentado configurar el TMR0 y el TMR1 en 16 bit en un 18f452 y cuando lo simulo en el ISIS la parte alta del TMR no se incrementa y no se interrumpe en el tiempo calculado (si se interrumpe).
Alguno me podria dar una ayudita porque la verdad he intentado de varias maneras y sigue siempre igual. Sera problema del ISIS?
Bueno desde ya muchas gracias y espero una respuestita.
Saludos.
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: Suky en 13 de Octubre de 2009, 09:28:10
Por lo que veo CCS el timer1 siempre lo va a usar en 16 bits:
Cita de: 18F452.h
////////////////////////////////////////////////////////////////// Timer 1
// Timer 1 Functions: SETUP_TIMER_1, GET_TIMER1, SET_TIMER1
// Constants used for SETUP_TIMER_1() are:
//      (or (via |) together constants from each group)
#define T1_DISABLED         0
#define T1_INTERNAL         0x85
#define T1_EXTERNAL         0x87
#define T1_EXTERNAL_SYNC    0x83

#define T1_CLK_OUT          8

#define T1_DIV_BY_1         0
#define T1_DIV_BY_2         0x10
#define T1_DIV_BY_4         0x20
#define T1_DIV_BY_8         0x30

Y al timer0 si no se le agrega la linea RTCC_8_BIT trabaja en 16 bits. Muéstranos como has realizado la temporización para poder detectar el error
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: dieguez07 en 13 de Octubre de 2009, 14:32:21
Gracias por su respuesta, lo he echo en basic de esta manera.

    Device 18F452                                                                                                                                                                                 
    XTAL 16

    ON_Interrupt GoTo Interrupcion
 
;---Congiguracion de la registros de config (para el 18F452)------------------------------------------------------------------------------------

    @CONFIG_REQ
    @__CONFIG config1h, HS_OSC_1 &  OSCS_OFF_1                                                         
    @__CONFIG config2l, BOR_OFF_2 & PWRT_ON_2                                                         
    @__CONFIG config2h, WDT_OFF_2 & WDTPS_1_2                                                         
    @__CONFIG config3h, CCP2MX_OFF_3                                                                   
    @__CONFIG config4l, DEBUG_OFF_4 & LVP_OFF_4 & STVR_OFF_4                                           
    @__CONFIG config5l, CP0_off_5 & CP1_OFF_5 & CP2_off_5 & CP3_OFF_5 ; si deseo protejer debo poner en ON esta linea                                                         
    @__CONFIG config5h, CPB_OFF_5 & CPD_off_5        ; protejo eeprom                                                 
    @__CONFIG config6l, WRT0_OFF_6 & WRT1_OFF_6                                                       
    @__CONFIG config6h, WRTB_OFF_6 & WRTC_OFF_6 & WRTD_OFF_6                                           
    @__CONFIG config7l, EBTR0_OFF_7 & EBTR1_OFF_7                                                     
    @__CONFIG config7h, EBTRB_OFF_7                                                                   
 
    OSCCON = 0                      ; Oscilador principal                                             
    RCON.7 = 0                      ; Prioridad de interrupciones deshabilitadas                       
    WDTCON.0=0                      ; El oscilador del wdt esta deshabilitado                         
    TMR0L = 0                       ; Borro el registro timer 0                                       
    TMR0H = 0                       ; Borro el registro timer 0                                       
    T0CON = %10000111               ; Timer 0 habilitado en modo 8 bit preescaler 256                 
    INTCON2.2=1                     ; Timer 0 de baja prioridad                                       
;-----------------------------------------------------------------------------------------------------------------------------------------------
 
    TRISA       =   %11010000       ; PA0 Reset_LCD, PA1_RS,PA2 CC1, PA3 RW, PA5 CC1                                                               
    TRISB       =   %11111110       ; PORTB 1-7  Entradas de teclado, PB0 salida Teclado                                           
    TRISC       =   %10011000       ; 0: Hab_D1, 1: ENABLE, 2: Hab_D2,3-4: I2C Ent, 5: Sal BKL, 6: Sal Tx , 7: Ent. Rx                                              
    TRISD       =   %00000000       ; Salidas de datos hacia el LCD                                                                 
    TRISE       =   %00000000       ; Puerto E como salidas                                                                         
    INTCON      =   %11111000        ; Configur las interrupciones y la interrupcion del timer0                                     
    PIE1        =   %00000000       
   
    TMR0H = %00010100
    TMR0L = %01010011 
       
    LCD_DTPORT = PORTD       
    LCD_RSPIN = PORTA.1
    LCD_ENPIN = PORTC.1
    LCD_RWPIN = PORTA.3
    LCD_CS1PIN = PORTA.5                                                                                   
    LCD_CS2PIN = PORTA.2
    LCD_TYPE = GRAPHIC
    INTERNAL_FONT = On
    FONT_ADDR = 0
    Declare GLCD_CS_INVERT On
    Declare GLCD_EXTERNAL_PRINT = PPRINT
    CCP1_PIN = PORTC.2
    CCP2_PIN = PORTC.1
    ALL_DIGITAL = True
   
    Symbol  BKL         PORTC.5 


Main:   
        BKL = 0   
        goto main


Interrupcion:
        If intcon.2 = 1 Then
            BKL = 1   
            intcon.2 = 0         
            TMR0H = %00010100
            TMR0L = %01010011
        endif               
        Context Restore
         
End

Si me puede decir cual es el error se lo agradeceria.
Seguire investigando.
Saludos y muchas gracias.
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: Suky en 13 de Octubre de 2009, 14:39:49
Estas en el subforo equivocado.-
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: lopb en 23 de Diciembre de 2010, 11:54:37
hola, alquien me puede ayudar?
estoy haciendo un segundero para usar en otras funciones con el timer0 y me esta devolviendo cada 2.x segundos, lo veo en una terminal segun un delay_ms(1000) imprime dos veces lo mismo, a veces 3, entonces estimo que estara en 2 segundos y pico desbordando.
les dejo el codigo a ver si hay algun error. Gracias:
Código: C
  1. #include <18F452.h>
  2. //////// Fuses: LP,XT,HS,RC,EC,EC_IO,H4,RC_IO,PROTECT,NOPROTECT,OSCSEN
  3. //////// Fuses: NOOSCSEN,NOBROWNOUT,BROWNOUT,WDT1,WDT2,WDT4,WDT8,WDT16,WDT32
  4. //////// Fuses: WDT64,WDT128,WDT,NOWDT,BORV20,BORV27,BORV42,BORV45,PUT,NOPUT
  5. //////// Fuses: CCP2C1,CCP2B3,NOSTVREN,STVREN,NODEBUG,DEBUG,NOLVP,LVP,WRT
  6. //////// Fuses: NOWRT,NOWRTD,WRTD,NOWRTB,WRTB,WRTC,NOWRTC,CPD,NOCPD,CPB
  7. //////// Fuses: NOCPB,EBTR,NOEBTR,EBTRB,NOEBTRB
  8. #FUSES NOWDT                    //No Watch Dog Timer
  9. #FUSES HS                       //High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
  10. #FUSES NOPUT                    //No Power Up Timer
  11. #FUSES NOPROTECT                //Code not protected from reading
  12. #FUSES NODEBUG                  //No Debug mode for ICD
  13. #FUSES NOBROWNOUT               //No brownout reset
  14. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  15. #FUSES NOCPD                    //No EE protection
  16. #FUSES NOWRT                    //Program memory not write protected
  17. #FUSES NOOSCSEN
  18. #FUSES NOPUT
  19. #FUSES CCP2C1
  20. #FUSES NOSTVREN
  21. #FUSES NODEBUG
  22. #FUSES NOWRTD
  23. #FUSES NOWRTB
  24. #FUSES NOWRTC
  25. #FUSES NOCPB
  26. #FUSES NOEBTR
  27. #FUSES NOEBTRB
  28.  
  29. #use delay(clock = 20000000)
  30. #use rs232 (baud=9600,xmit=PIN_C6,rcv=PIN_C7)
  31.  
  32. unsigned int16 seconds = 0;
  33.  
  34. #INT_RTCC                                    //Interrupt procedure
  35. clock_isr() {                                //called every time RTCC
  36. set_timer0(19531);
  37.       ++seconds;   //Inc SECONDS counter every
  38.                                            //76 times to keep time
  39. }
  40.  
  41. void main() {                                //a simple stopwatch program
  42.  
  43.    setup_timer_0(RTCC_INTERNAL | RTCC_DIV_256 );
  44.    set_timer0(19531);
  45.    enable_interrupts(INT_RTCC);
  46.    enable_interrupts(GLOBAL);
  47.  
  48.    do {
  49.       delay_ms(1000);
  50.       printf("%lu seconds \n\r", seconds);
  51.    } while (TRUE);
  52. }
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: Suky en 23 de Diciembre de 2010, 12:45:04
Si escribís 19531, el timer cuenta 46005 (65536-19531) veces antes de la interrupción, y eso es correcto?
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: jhozate en 23 de Diciembre de 2010, 12:56:48
segun las cuentas con esa precarga el timer se desborda cada 2355,45 mS es decir 2.355 segundos
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: RALF2 en 23 de Diciembre de 2010, 13:17:20
Que tal amigos!
Con esta formula puedes calcular mas exacto el tiempo con el timer 0:

temp = [(256 – carga) · PS + 2] · Tinstr

ps:Pre escaler
tinst:4/frecuencia del cristal
carga:Valor a cargar en el timer 0
temp: tiempo deseado a temporizar  :mrgreen:

Espero les sea util!

Saludos
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: Suky en 23 de Diciembre de 2010, 13:20:26
Que tal amigos!
Con esta formula puedes calcular mas exacto el tiempo con el timer 0:

temp = [(256 – carga) · PS + 2] · Tinstr

ps:Pre escaler
tinst:4/frecuencia del cristal
carga:Valor a cargar en el timer 0
temp: tiempo deseado a temporizar  :mrgreen:

Espero les sea util!

Saludos


Ojo, eso es solo para Timer0 de los 16F


Saludos!
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: lopb en 23 de Diciembre de 2010, 16:15:39
segun las cuentas con esa precarga el timer se desborda cada 2355,45 mS es decir 2.355 segundos
ah, ya entendi jeje
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: bmb en 23 de Diciembre de 2010, 16:51:20
Hola lopb, para contar 1 segundo, puedes por ejemplo configurar el Timer0 así:

setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);      //1.6 s overflow

luego haces tus cálculos así:

clock = 20000000 Hz
Tosc = (1 / clock)

Tiempo = 4 x Tosc x Valor a contar en Timer0 + 1 x Rango del Divisor
Tiempo = 4 x 0.00000005 x 39062 x 128 = 0.9999 Seg.        // Timer 16 bits a 20MHz
Valor de inicio para Timer0 = 65536 - 39062 = 26474

set_timer0(26474);

Saludos!
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: RALF2 en 23 de Diciembre de 2010, 18:03:32
Citar
Ojo, eso es solo para Timer0 de los 16F


Que tal suky amigo eso que coloque arriba es valido solo para el timer 0 en los pic de la serie 16 y 18 incluso.
Fijate en el diagrama de bloques de este alli veras el bloque de retardo de 2 ciclos de instruccion  :mrgreen:

Saludos
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: jhozate en 23 de Diciembre de 2010, 18:08:02
lo que pasa es que en la serie 16f el timer0 es de 8bits, mientras en los 18f es configurable a 8 ó 16bits
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: Suky en 23 de Diciembre de 2010, 18:18:07
lo que pasa es que en la serie 16f el timer0 es de 8bits, mientras en los 18f es configurable a 8 ó 16bits

Exactamente!
Citar
Ojo, eso es solo para Timer0 de los 16F
Fijate en el diagrama de bloques de este alli veras el bloque de retardo de 2 ciclos de instruccion  :mrgreen:

No solo hay que mirar las imagenes!  :D Sirve para un modo de configuración  ;-)



Saludos!
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: RALF2 en 23 de Diciembre de 2010, 20:30:37
Que tal amigos!
Tal como dicen una imagen habla mas que mil palabras!
Otro detalle es que el timer 0 independientemente de que sea de 8 0 16bits usa un bloquecito que retarda la señal 2 ciclos de reloj, ver imajen.
Asi que para operar en modo de 8 bits la formula seria:

temp = [(256 – carga) · PS + 2] · Tinstr

Y para operar a modo de 16bits seria esta:

temp = [(65536 – carga) · PS + 2] · Tinstr

Con esto aclaro por completo los modos de operacion para la familia pic18XXXX

Nota: ver el bloquecito que dice Sync witch internal clocks en ambas figuras :D

(http://img268.imageshack.us/img268/571/timer0.png)

Saludos
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: Manel28 en 29 de Marzo de 2011, 06:16:25
Hola buenas,
estoy usando un PIC18F25j10 con ccs 4.093. Que versión de CCS tienen ustedes? Estoy intentando compilar usando timer0 con 16 bits y no puedo( Error 12 "Prueba1.c" Line 288(44,55): Undefined identifier   RTCC_16_BIT).

La configuración es la siguiente:
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16|RTCC_16_BIT);
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: jhozate en 29 de Marzo de 2011, 10:46:54
me suena a que no es la forma de indicar que el timer será de 16 bits, tendrias que confirmarlo buscando en la carpeta ”devices” de ccs el .h de tu pic, ahi deberia estar explicada la sintaxis para el timer
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: bmb en 29 de Marzo de 2011, 17:50:00
Hola Manuel28, es como te dice jhozate.  En este caso, como el Timer0 del PIC18f25j50 trabaja por defecto a 16 bits, te estaría sobrando la última instrucción y quedaría asi:

Citar
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16);

En el caso de que lo quisieras trabajar a 8 bits, ahí si tendrías que adicionar la instrucción: RTCC_8_BIT asi:

Citar
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_16|RTCC_8_BIT);

Saludos!
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: diegoap en 11 de Abril de 2011, 15:38:54
Pues para lograr un segundo exacto con el timer del PIC utilice el Timer2 seteado para que la interrupcion salte cada 400us, y puse un contador a 2500. Cuando el contador llega a 0, tengo 1seg casi exacto.
Lo arme y lo heche a andar, y lo deje un buen rato, conectado a unos leds q marcaran minutos y segundo, y comparando con un cronometro, y al cabo de poco mas de una hora y media, tuve una desviacion por arriba de un poco màs de 1seg.

Esepero les sea util mi experiencia.
Un Salduo.
Título: Re: Entendiendo el TIMER0 en CCS
Publicado por: Simon21 en 19 de Enero de 2013, 14:19:08
Muy buena tu explicacion RALF2. Para los aplausos  ((:-))  ((:-))  ((:-))  ((:-))  ((:-))

Hacia rato andaba buscando una explicación así por la web.

Mucha gente genia en este foro  :) !!
 
Saludos a todos
Título: Re:Entendiendo el TIMER0 en CCS
Publicado por: orlandodz09 en 24 de Noviembre de 2016, 19:57:05
Saludos a todos, soy novato en programación CCS, necesito saber como activar un temporizador que cada vez que se ejecute un "metodo" este salga al inicio del programa después de no recibir ninguna instrucción (un tiempo de 30 segundos), esto necesito ya que mi programa tiene 5 metodos que se ejecutan por usuarios, pero algunos usuarios llegan hasta el tercer metodo (por ejemplo) y lo dejan ahi colgado, entonces necesito que el programa tras 30 segundos de no recibir ninguna ejecucion, este se salga al inicio del programa, es decir realice un rest_cpu 
Título: Re:Entendiendo el TIMER0 en CCS
Publicado por: KILLERJC en 24 de Noviembre de 2016, 23:20:29
Hola orlandodz09

No se que son los "metodos" a cuales te referis.

El TMR0 siempre esta activo, por lo cual no vas a poder activarlo. Siempre esta contando, lo unico que podes llegar a hacer es activar su interrupcion (previo limpiado de su flag y setup al inicio del programa). De esa forma contar la cantidad de interrupciones que ocurren y si superan cierta cantidad ejecutar un reset o plantear que el programa se haga de otra forma.
Título: Re:Entendiendo el TIMER0 en CCS
Publicado por: trucksbear en 09 de Diciembre de 2016, 02:05:21
Hola, agradecerpía mucho una ayuda para poder entender mejor el TIMER0 como contador, yo necesito contar pulso de bajo a alto, entiendo que selia low_to_high la configuración, y utilizando el prescaler de 1:2 tendría que contar un pulso de 70uS en el pin T0CKI, que al prescaler 1:2 esto serían 140uS, eso es errado o es cierto?
y usar ese conteo si el pulso alto duró 140uS(70uS) para rellenar un vector con un 1 o un 0

como sería el código entonces?
for(i=1, i<41, i++){
if (timer0=140uS){vector ==1}
else{vector ==0}}
eso sería correcto?
lo que no sé bien es como configurar el pin T0CKI para que cuente el ancho de los flancos ascendentes hasta que descienden otra vez a 0
gracias
Título: Re:Entendiendo el TIMER0 en CCS
Publicado por: KILLERJC en 09 de Diciembre de 2016, 12:22:18
Citar
Hola, agradecerpía mucho una ayuda para poder entender mejor el TIMER0 como contador, yo necesito contar pulso de bajo a alto, entiendo que selia low_to_high la configuración, y utilizando el prescaler de 1:2 tendría que contar un pulso de 70uS en el pin T0CKI, que al prescaler 1:2 esto serían 140uS, eso es errado o es cierto?

Voy a explicarte un poco, pero todo lo demas lo vas a tener que aprender del datasheet del micro. En el datasheet esta TODO.

el LOW_TO_HIGH es para que ingrese un pulso al timer cuando la señal EXTERNA pasa de bajo a alto. Como bien dije, es una señal EXTERNA que entraria por un pin.
Si vos queres saber el tiempo que paso. Usaria mejor el reloj interno, en ves de tomar pulsos de afuera, los tome del mismo reloj que usa el procesador ( Fosc / 4 )
El contador/timer, es un timer de 8 bits, asi que el maximo que puede almacenar es 255 (0xFF), siempre es ascendente, cuando suma 1 mas ocurre que produce un overflow y pasa a 0x00. Es en ese momento que uno debe recargarlo de vuelta y que sabe que paso ya el tiempo cargado.

Supongamos que queres 140us, y tenes un micro con un cristal de 4Mhz, al tener un cristal de 4Mhz el reloj que entra al procesador y al timer es de 4Mhz / 4 = 1Mhz, esto te da un periodo de 1 / 1Mhz = 1us. Entonces el PIC va a sumar 1, cada 1us, si quisieramos que pasen 140us, deberiamos contar 140. Ahora viene la parte "tramposa" de esto.
Como dije antes el timer/contador es siempre ascendente. Por lo cual si quisieramos cargar un valor y que a los 140 llegue a 0, deberiamos cargar 256 - 140 = 116, Cargando 116, cuando cuente 140 va a estar en 0x00 y es ahi donde vamos a tener que cargarlo de nuevo. Esto con preescaler en 1:1, si fuera 1:2 serian 70 pulsos

Citar
lo que no sé bien es como configurar el pin T0CKI para que cuente el ancho de los flancos ascendentes hasta que descienden otra vez a 0

Lo que explique arriba es el funcionamiento del Timer como contador/timer.

Si quisieras hacer eso con el TMR0, deberias leer el pin. Supongamos que queres leer el pulso en alto. Usando el timer y siguiendo el ejemplo de arriba, tenes que cada pulso es 1us.
Leo el pin y espero que se ponga a 1. Al momento que se pone en uno, leo el valor del timer y lo guardo en una variable. Ahora espero el 0, cuando leo cero, guardo ese valor en otra variable.

El ancho va a estar dado por la diferencia de esas 2 variables. Si el timer va a tener "cuentas" de pulsos, pero vos sabes exactamente cuanto tarda cada pulso de reloj, en el ejemplo de 4Mhz el cristal y preescaler 1:1, teniamos que eran 1us por pulso o cuenta del timer, si teniamos preescaler 1:2 son 2us cada cuenta.

Asi podes determinar el ancho de tu pulso con el TMR0