Autor Tema: configuracion basica TIMER1 y TIMER0  (Leído 9191 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado carlekes

  • PIC10
  • *
  • Mensajes: 14
configuracion basica TIMER1 y TIMER0
« en: 20 de Abril de 2008, 08:48:28 »
Llevo varios dias intentando hacer un programa que encienda un led y al cabo de un minuto lo apage, en lenguaje C ando muy perdido y agradeceria si alguien me pudiera facilitar algunos ejemplos sencillos de configuracion del TIMER0 y el TIMER1.

Saludos y gracias.

Por ejemplo, a continuacion pongo un programa que al mantener pulsado un pulsador normalmente cerrado RB0 (Al pulsarlo se pone en nivel bajo, 0v), se enicende el led de la patilla RB1.

Pues me gustaria que "solo" mientras estubiese pulsado se encendiera el led y se apagara en intervalos de 1 segundo actuando como un intermitente de un coche.



#include <16F877A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT

#use fast_io(A)
#use fast_io(B)


void main()
{

short a,b,c,n;                                   //definimos las variables como numeros enteros

set_tris_a(0xFF);                                   //Puerta A con 6 E/S, las define como entradas
set_tris_b(0x01);                                   //Puerta B con 8 E/S, las define como salidas menos RB0 que
                                      // queda como entrada.


//setup_timer_0 (RTCC_INTERNAL, RTCC_DIV_256);              //Configuramos reloj interno del timer 0
                                       // y ponemos el prescaler 1:256.
//n=0;

output_low (PIN_B1);                                    //Ponemos la patilla RB1 a nivel bajo (0v) al inicializar el programa.
   
while(1)                                       //La sentencia While ejecuta ininterrumpidamente mientras se
{                                       //cumpla una determinada condicionn.
      
a=input(PIN_A4);                                    //a= al valor de la entrada RA4 (interruptor derecho)



if(a==0)
   output_high (PIN_B1);
   
//   set_timer0(60);                                //Valor inicial del contaje para contar 0.05 segundos.   
   
if(a==1)
   output_low (PIN_B1);
   
}
}
« Última modificación: 20 de Abril de 2008, 09:15:50 por carlekes »

Desconectado manex_1987

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1127
Re: configuracion basica TIMER1 y TIMER0
« Respuesta #1 en: 20 de Abril de 2008, 18:21:13 »
Bien, si usas 4Mhz, para crear 1s aproximadamente (con un minimo error, pero que para RTC no serviria), necesitas 61 desbordes del TMR0 con 1:256 de prescaler.

Código: [Seleccionar]
#include <16F877A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT

#use fast_io(A)
#use fast_io(B)

short a=0,b=0,c=0,n; 

void main()
{                             

set_tris_a(0xFF);                                   
set_tris_b(0x01);                               
                                 


setup_timer_0 (RTCC_INTERNAL, RTCC_DIV_256);                                         
enable_interrupts(INT_TIMER0);

output_low (PIN_B1);                               
   
while(1)                                     
{                             
     
a=input(PIN_A4);                                   
if(b==0xFF) output_high(PIN_B1);
else output_low(PIN_B1);

}
}

#INT_TIMER0
void INT_timer0()
{
c++;
if(c==61 & a)
{
    c=0;
    b^=0xFF;
}
}

« Última modificación: 20 de Abril de 2008, 18:23:59 por manex_1987 »

Desconectado vszener

  • Moderadores
  • PIC24H
  • *****
  • Mensajes: 2395
Re: configuracion basica TIMER1 y TIMER0
« Respuesta #2 en: 20 de Abril de 2008, 18:56:16 »
En el subforo de C encontrarás multitud de ejemplos realizados en lenguaje C.


Suerte!!! ;)
· Nos vemos en los bares!!!!!
· Mi Blog: Aqueronte

Desconectado carlekes

  • PIC10
  • *
  • Mensajes: 14
Re: configuracion basica TIMER1 y TIMER0
« Respuesta #3 en: 21 de Abril de 2008, 13:12:57 »
Gracias por vuestras respuestas pero esta parte del programa no la entiendo para nada y a la hora de compilarlo me aparecen errores me la podriais explicar.

#INT_TIMER0              //aqui entro en la rutina de la interrupcion
void INT_timer0()        //¿?¿?¿?¿
{
c++;                         //¿?¿?¿?¿?
if(c==61 & a)             //¿?¿?¿?¿'
{
    c=0;                     //que es la c ¿?¿??
    b^=0xFF;              //que significa ^ ¿?¿?¿?¿
}
}

Gracias.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: configuracion basica TIMER1 y TIMER0
« Respuesta #4 en: 21 de Abril de 2008, 15:24:26 »
Gracias por vuestras respuestas pero esta parte del programa no la entiendo para nada y a la hora de compilarlo me aparecen errores me la podriais explicar.

#INT_TIMER0              //aqui entro en la rutina de la interrupcion
void INT_timer0()        //¿?¿?¿?¿
{
c++;                         //¿?¿?¿?¿?
if(c==61 & a)             //¿?¿?¿?¿'
{
    c=0;                     //que es la c ¿?¿??
    b^=0xFF;              //que significa ^ ¿?¿?¿?¿
}
}

Gracias.


#INT_TIMER0              //Acá le indicas al compilador que va a existír una subrutina de interr. del Timer0
void INT_timer0()        //Esta es la subrutina del Timer0 asociada.
{
c++;                         //Incremento la variable global "c", para ir contando las interrupciones del Timer0
if(c==61 & a)             //Cuando c valga 61, habremos contado aproximadamente 1 segundo de tiempo transcurrido. a contiene el valor del estado del pulsador. Entonces si se cumplen AMBAS condiciones(por eso esta el "&" que es "logical AND") la condicion del IF da TRUE y se ejecuta lo siguiente:
{
    c=0;                     //pongo a 0 la "c" para volver a contar de nuevo 61 interr. del Timer0
    b^=0xFF;              //la significa ^ significa XOR. La instrucción XOR, es un operador lógico, en este caso, entre un registro y un valor. Aquí la XOR se hace sobre la variable b y el valor 0xFF. Una de las utilidades de la XOR es que, mediante el valor ingresado y controlado(en esta caso 0xFF) se puede invertir el valor de los bits del registro(en este caso "b") poniendo a 1 todos los bits que se quieran invertir.  Hacer b^=0xFF entonces implica que que si "b" valía 0 antes de esta instrucción XOR, luego de la XOR valdrá 0xFF. En la próxima pasada cuando "b" valga 0xFF, la XOR nuevamente invertirá los bits de "b", haciendo que valga 0. Y así susesivamente.
}
}

El ejemplo que te ha dado manex es bueno, pero tiene un par de detalles que deberías corregir.

Yo lo haría así:

#include <16F877A.h>
#use delay(clock=4000000)
#fuses XT,NOWDT

#use fast_io(A)
#use fast_io(B)

#byte port_b= 0x06

short c=0; 

void main()
{                             

set_tris_a(0x00);                                   
set_tris_b(0x01);                               
                                 


setup_timer_0 (RTCC_INTERNAL, RTCC_DIV_256);                                         
enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);

output_low (PIN_B1);                               
   
while(1)                                     
{                             
                                   
   if(input(PIN_B0)){
      c=0;
      output_low(PIN_B1); 
   }
}
}

#INT_TIMER0
void INT_timer0()
{
c++;
if(c==61 & !input(PIN_B0))
{
    c=0;
    port_b^=0x02;  //invertir el estado del pin B1 sólamente.
}
}


Saludos!
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado carlekes

  • PIC10
  • *
  • Mensajes: 14
Re: configuracion basica TIMER1 y TIMER0
« Respuesta #5 en: 23 de Abril de 2008, 10:02:34 »
Muchas Gracias a todos ya lo pude resolver, gracias a vosotros, ahunque lo he cambiado un poco por los derechos de autor y eso.

Aqui lo dejo:


#use fast_io(A)
#use fast_io(B)

short a,b,c;                           //definimos las variables como numeros enteros

void main()
{

set_tris_a(0xFF);                        //Puerta A con 6 E/S, las define como entradas
set_tris_b(0x01);                        //Puerta B con 8 E/S, las define como salidas menos RB0 que
                                    // queda como entrada.


setup_timer_0 (RTCC_INTERNAL|RTCC_DIV_256);      //Configuramos reloj interno del timer 0
                                    // y ponemos el prescaler 1:256.

c=0;

output_low (PIN_B1);                     //Ponemos la patilla RB1 a nivel bajo (0v)
a=0;

set_timer0(60);                           //Valor inicial del contaje para contar 0.05 segundos.   

enable_interrupts(INT_TIMER0);
enable_interrupts(GLOBAL);
   
while(1)                              //La sentencia While ejecuta ininterrumpidamente mientras se
   {                                    //cumpla una determinada condicionn.
      
   }
}

#INT_TIMER0
void timer0()
{
disable_interrupts(GLOBAL);
c++;                                 //incremento de c en unidad
if(c==20)                              // cuando c sea 20 llegamos a 1 s.
   {
    if(a==0)
      {
      output_high(PIN_B1);
      a=1;
      }
   else
      {
      output_low (PIN_B1);                  //apagamos el led.
      a=0;
      }
   c=0;
   }
set_timer0(60);
enable_interrupts(GLOBAL);

}


asias:D

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: configuracion basica TIMER1 y TIMER0
« Respuesta #6 en: 23 de Abril de 2008, 10:43:40 »
Hola.

Dos cosas:

Dentro de la interr del timer0, no hace falta desactivar las interrupciones globales ni volver a activarlas al salir...

Segundo: Tu programa no tiene en cuenta que se debe estar presionando el pulsador en RB0 para que el LED efectivamente deba apagar y encender. A menos que hayas decidio cambiar el comportamiento del mísmo en cuyo caso estaría bien...

Saludos.
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.