TODOPIC

Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: manuelroin24 en 18 de Octubre de 2006, 15:15:13

Título: AYUDA CON TIMER0!!!
Publicado por: manuelroin24 en 18 de Octubre de 2006, 15:15:13
AMIGOS MIOS ESTE ES MI PROGRAMA EN CCS COMPILER PERO NECESITO USAR EL TIMER 0 PARA IR PRENDIENDO Y APGANDO UN LED CADA SEGUNDO PARA ESO CARGUE EN EL TIMER0 EL NUMERO 61 PERO POR ALGUNA RAZON NO PUEDO VISUALIZAR EL LED PRENDIDO ALGUIEN PUEDE AYUDARME AQUI LES DEJO EL PROGRAMA.

   #INCLUDE   <16F84A.H>
   #FUSES      XT,NOPROTECT,NOWDT,PUT
   #USE      delay (clock = 4000000)
   #USE      STANDARD_IO(B)

   INT    FLAG = 0 ;

   //INTERRUPCION
   #INT_TIMER0
   VOID INTERRUPTION()
   {
     FLAG ++;
    IF (FLAG = 20){
                OUTPUT_HIGH(PIN_B0);
                }
    IF (FLAG = 40){
                OUTPUT_LOW(PIN_B0);
                FLAG = 0;
                }
    //SET_TIMER0(61); //RESET TIMER 0
   }

   //PROGRAMA
   VOID MAIN (VOID)
   {
      SET_TRIS_B(0X00);
      ENABLE_INTERRUPTS(GLOBAL);
      ENABLE_INTERRUPTS(INT_TIMER0);
      SET_TIMER0(61);
      SETUP_COUNTERS(RTCC_INTERNAL,RTCC_DIV_256);

      OUTPUT_LOW(PIN_B0);
   
      DO   {
          OUTPUT_HIGH(PIN_B7);
         }WHILE(TRUE);
   }
Título: Re: AYUDA CON TIMER0!!!
Publicado por: RedPic en 18 de Octubre de 2006, 16:07:16
Amigo Manuel en C para comparar debes utilizar los simbolos == ya que un solo = es una asignación.

Tu programa debe quedar:

  VOID INTERRUPTION()
   {
     FLAG ++;
    IF (FLAG == 20){
                OUTPUT_HIGH(PIN_B0);
                }
    IF (FLAG == 40){
                OUTPUT_LOW(PIN_B0);
                FLAG = 0;
                }
    //SET_TIMER0(61); //RESET TIMER 0
   }

Creo que asi te debe funcionar.

P.D: Ah, por cierto procura escribir en minúsculas ya que todo en mayúsculas se entiende en Internet como que se está gritando.  :mrgreen:
Título: Re: AYUDA CON TIMER0!!!
Publicado por: RedPic en 18 de Octubre de 2006, 17:16:02
Amigo Manuel:

Mas cosas ... Aqui tienes un articulillo donde hablo de como conseguir un segundo (mas o menos) Template para el uso de la Interrupción RTCC mediante el TIMER0
 (http://picmania.garcia-cuervo.com/PICC.htm#RTCC1)

El código que propongo es

Código: C
  1. #include <16f628.h>                    // Selecciona el PIC
  2. #fuses XT,NOWDT,NOPROTECT,PUT,BROWNOUT // Opciones de configuración
  3. #use delay(clock=4000000)              // Velocidad del Cristal : 4 Mhz
  4.  
  5. byte const NInts=30;                   // Numero de interrupciones para 1 Segundo
  6.  
  7. // VARIABLES GLOBALES
  8.  
  9. char C_Ints=0;                         // Contador de Interrupciones ocurridas
  10. char Flag=0;                           // Flag que cambia cada NInts interrupciones
  11.  
  12. #int_RTCC                              // Interrupción por desbordamiento
  13. RTCC_isr() {                           // del TIMER0 RTCC
  14.   if(C_Ints > NInts){                  // Si las ints ocurridas > ints para 1 Seg.
  15.     if(Flag==0){
  16.       Flag=1;
  17.     }
  18.     else{
  19.       Flag=0;
  20.     }
  21.     C_Ints=0;                          // Reinicializo Contador de Ints
  22.   }
  23.   ++C_Ints;                            // Incremento el número de interrupciones
  24. }                                      // Ocurridas
  25.  
  26.  
  27.  
  28. void main(void) {
  29.  
  30.   setup_counters(RTCC_INTERNAL,RTCC_DIV_128);// TIMER0: Clock Interno, Presescaler 128
  31.   setup_timer_1(T1_DISABLED);                // para una RTCC cada 33.3 milisegundos
  32.   setup_timer_2(T2_DISABLED,0,1);            // -> 1 Segundo = 30 RTCC
  33.   setup_comparator(NC_NC_NC_NC);
  34.   setup_vref(FALSE);
  35.   enable_interrupts(INT_RTCC);               // Habilito Interrupción RTCC
  36.   enable_interrupts(global);                 // Habilito Interrupciones
  37.  
  38.   do{ // Bucle infinito
  39.     if(Flag==K){}
  40.     else
  41.     {                                        // si ha cambiado Flag ...
  42.  
  43.       // AQUI HAGO LO QUE DESEE CADA 1 SEGUNDO
  44.  
  45.       k=Flag;                                // Guardo estado anterior de Flag
  46.     }
  47.   }While(TRUE);
  48. }

Espero que te sirva.
Título: Re: AYUDA CON TIMER0!!!
Publicado por: manuelroin24 en 18 de Octubre de 2006, 22:22:55
Muchas gracias llegando a casa lo pruebo a ver q sucede
Título: Re: AYUDA CON TIMER0!!!
Publicado por: manuelroin24 en 19 de Octubre de 2006, 17:32:56
efectivamente lo probe y funciono muchas gracias no c como no me pude percatar de algo tan sencillo gracias amigo. Una cosa mas no entiendo a la que te refieres con un segundo exacto., porque cuando yo lo simulo en el proteus me sale todos los cmabios a un segundo ya que si con el numero 61 tenemos 50ms por 20 veces seria 1 segundo o estoy mal??? gracias
Título: Re: AYUDA CON TIMER0!!!
Publicado por: RedPic en 20 de Octubre de 2006, 01:29:24
Amigo Manuel:

Si acumulas muchos de estos segundos notarás que se desfasa con respecto a un reloj exacto.

Esto es porque al dividir los 4 Megahercios primero por cuatro para sacar un ciclo-máquina (el tiempo que tarda en ejecutarse una sola instruccion simple) y despues los divisores que le colocas al TIMER nunca vas a obtener una interrupción RTCC en un submultiplo exacto de 1 segundo. Siempre te faltan o sobran algunos uS. (Dale un vistazo a Los Cristales y el Tiempo (http://picmania.garcia-cuervo.com/Conceptos.htm#CristalyTime))

Esto se consigue mucho mejor con un cristal de reloj de 32.768 Khz que si produce una division exacta usando divisores del tipo 2^n (o sea los que podemos conseguir digitalmente) Tienes también un ejemplo interesante de esto en Real Time Clock o el DS1307 desatado (http://www.todopic.com.ar/foros/index.php?topic=13282.0)

Un saludo

Título: Re: AYUDA CON TIMER0!!!
Publicado por: Nocturno en 20 de Octubre de 2006, 10:54:32
Discrepo de esto último, querido Diego.

Si utilizas cristal de 4MHz, un prescaler de 8 y haces la precarga del timer para que corra durante 125 ciclos a mí me sale un segundo exacto, ¿no?
Título: Re: AYUDA CON TIMER0!!!
Publicado por: Azicuetano en 20 de Octubre de 2006, 17:18:48
Pues... siempre había leido que con un cristal de 4 Mhz no se podía hacer un retardo de un segundo exacto pero.... si he entendido bien lo que comenta Nocturno, va a ser que si.

Temporización=4*Tosc*(valor cargado en el TMR0)*(rango del divisor)

Con los valores de Nocturno tenemos que:

Temporización=0.001 s.

Si repetimos esto 1000 veces tenemos un segundo.

Es correcto el razonamiento??

Lo que la gente suele intentar es cargar el valor máximo en el TMR0 y poner el máximo rango del divisor (porque el retardo de 1s es muy grande) entonces... en las veces que tiene que repetir la operación salen decimales (con la consecuente pérdida de tiempo).

Bueno, ya me comentais.

PD: Se nota que núnca he necesitado temporizar 1 segundo exácto??  :D :D


Un saludo desde Alicante.
Título: Re: AYUDA CON TIMER0!!!
Publicado por: manuelroin24 en 20 de Octubre de 2006, 19:57:04
exacto lo que dice Nocturno es cierto gracias NOCTURNO como siempre me salvaste de quedar mal jejejejejejeje
Título: Re: AYUDA CON TIMER0!!!
Publicado por: Nocturno en 20 de Octubre de 2006, 20:16:33
Habría que probarlo, que yo no lo he hecho, eh...