TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: Ranculche en 10 de Junio de 2011, 14:12:05

Título: Ayuda con Timer CCS (16f628a)
Publicado por: Ranculche en 10 de Junio de 2011, 14:12:05
Hola a todos! Estoy queriando configurar un timer del pic 16f628a para que interrumpa cada 1ms, pero no doy con la tecla, la verdad que no se que puedo tener mal, si los fuses, si la configuracion del reloj, la verdad recien empiezo con estos micros 16f. Cualquier recomendacion se las agradezco.
Aqui adjunto el archivo main.c que he hecho y no puedo hacer funcionar. Basicamente quiero encender y apagar el led cada un segundo usando un timer.
Gracias!

Saludos
Título: Re: Ayuda con Timer CCS (16f628a)
Publicado por: Suky en 10 de Junio de 2011, 14:28:17
Debes configurar el oscilador interno para que trabaje a 4MHz:

// Configuramos oscilador interno a 4MHz
   setup_oscillator(OSC_4MHZ);

Luego, el timer0 de los 16F es de 8-bits así que la configuración solo seria: setup_counters( RTCC_INTERNAL, RTCC_DIV_8)


Saludos!
Título: Re: Ayuda con Timer CCS (16f628a)
Publicado por: Ranculche en 10 de Junio de 2011, 14:48:46
Hola! gracias por la respuesta, te cuento que hice lo que me dijiste, pero no he obtenido resultaso, primero pude hacer titilar el led pero con malos tiempos, desp me dejo de funcionar. El pic se graba y funciona (porque apenas entro al programa prendo el led) pero parece que no entra a la interrupcion, porque lo deja encendido. No se si los fuses estaran bien. o el valor que le cargo al timer.

Saludos
Título: Re: Ayuda con Timer CCS (16f628a)
Publicado por: bmb en 10 de Junio de 2011, 18:59:30
Hola Ranculche:

Citar
int miliseg=0;
  .
  .
if(miliseg>1000 && flag==1)

Allí tienes una comparación de una variable entera de 8 bits con un número entero de más de 8 bits.  El resultado de esa comparación siempre va a ser falsa.  Puedes cambiar la variable por:

Citar
long miliseg=0;

Saludos!
Título: Re: Ayuda con Timer CCS (16f628a)
Publicado por: KALLITOS en 10 de Junio de 2011, 19:10:36
Hola Ranculche:

Citar
int miliseg=0;
  .
  .
if(miliseg>1000 && flag==1)

Allí tienes una comparación de una variable entera de 8 bits con un número entero de más de 8 bits.  El resultado de esa comparación siempre va a ser falsa.  Puedes cambiar la variable por:

Citar
long miliseg=0;

Saludos!


Correcto, miliseg al definirlo con tipo int va de 0 a 255 ciclicamente y la comparacion con 1000 no da un resultado coherente.

Intenta cambiando de int a int16 que va de 0 a 65535.

saludos

Título: Re: Ayuda con Timer CCS (16f628a)
Publicado por: BlueShift en 19 de Junio de 2011, 13:24:06
Esto te debería funcionar a la perfección:

Código: [Seleccionar]
//------Directivas para el compilador--------

#Include <16F628A.h>                                                                  //PIC utilizado
#Fuses INTRC_IO, NOWDT, NOPUT, NOMCLR, NOBROWNOUT, NOCPD, NOPROTECT                   //Configuramos los fuses
#Use Delay (Clock=4000000)                                                            //Oscilador a 4Mhz
#Use Fast_Io(B)                                                                       //Optimizamos E/S del PORTB
#Use Fast_Io(A)                                                                       //Optimizamos E/S del PORTA

int16 milisegundo;
int1 flag;


#int_timer0               //la interrupcion por timer0
void timer0_isr(void)
{
    milisegundo++;   
    set_timer0(135);      //cargo el timer0 para que desvorde en un 1ms (con 135 en vez de 131 para compensar)
}


void main(void)
{
   set_tris_a(0b00000000);           //configuro el puerto a
   set_tris_b(0b00000000);           //configuro el puerto b   
 
   
   //-----------------------configuramos la interrupciones-----------------------     
   disable_interrupts(global);                                          //desactivo todas las interrupciones
   
      //-----------------------configuro el timer 0-----------------------       
      setup_counters( rtcc_internal, rtcc_div_8  | rtcc_8_bit);   //configuro timer0 con prescaler de 1:8
      enable_interrupts(int_timer0);                              //activo el timer0
      set_timer0(130);                                            //cargo el timer0 para que desborde en un 1ms
      //------------------------------------------------------------------   
     
   enable_interrupts(global);       //activo las interrupciones
   //----------------------------------------------------------------------------   
   
   while(true)
   { 
   
      if ((milisegundo >= 1000) && (flag == 1))     
      {
         milisegundo = 0;   
         output_low(pin_b5);  //desactiva el led
         flag=0;
      }
   
      if ((milisegundo >= 1000) && (flag == 0))   
      {
         milisegundo = 0;   
         output_high(pin_b5);   //activa el led
         flag=1;
      }   
   
   }
   


espero que te sirva