TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: DarkVect en 11 de Febrero de 2008, 10:18:08
-
Hola amigos, quiero conseguir que el Timer0 me salte cada 0,1ms. Para ellos utilizo un cristal de 4MHzy precargo el timer0 a 156 de forma que el tiempo de interrupción me queda:
T=(256-156)*(4/4·10^6)=0,0001
Dentro del Timer tengo el siguiente código:
#INT_TIMER0
void Interrupcion_Timer0()
{
set_timer0(156);
nClocks++;
if(nClocks==40000)
{
nClocks=0;
output_toggle(LED);
}
}
De forma que el led debería cambiar cada 4 segundos. Pues bien, ni por asomo se acerca a ese valor. De hecho el tiempo que obtengo es de 5,36 a 5,44 dependiendo de mi capacidad de reacción al parar el crono. La variable nClocks es un int16.
El Timer está configurado así:
setup_TIMER_0(RTCC_INTERNAL | RTCC_DIV_1);
setup_TIMER_1(T1_DISABLED);
setup_TIMER_2(T2_DISABLED,0,1);
He probado a quitar el set_timer0(156) y entonces la temporización es exacta a 10,24 segundos, como debe ser.
Qué estoy pasando por alto?
Se os ocurre otra forma de conseguir los 0,1ms.
Olvidé decir que programa en CCS, que el PIC es un 16F818 y que en el main no hay nada, es un simple bluce do-while vacío.
-
He hecho alguna prueba más y me pasa algo muy raro; cuando escalo el timer por un valor grande, 128 por ejemplo, me temporiza bien con el set_timer0(). Sin embargo si lo escalo a 1 o 2 o 4 no funciona bien.
Creo que tiene que ver que la variable que cuenta el número de interrupciones sea int16, puede ser? Es mejor que cuente con dos int8 anidados?
Gracias!!
-
Me respondo a mi mismo, anidando pasa lo mismo. HE probado con un ejemplo de lo más simple y no soy capaz de ver dónde está el error:
#include <16LF84A.h> //pic a utilizar
#fuses XT
#fuses NOWDT
#fuses PROTECT
#fuses PUT
#use delay (clock=4000000)
#use fast_io(a)
#use fast_io(b)
#define LED PIN_A1 //LED de funcionamiento
int16 nClocks=0;
#INT_TIMER0
void Interrupcion_Timer0()
{
set_timer0(56);
nClocks++;
if(nClocks==25000)
{
nClocks=0;
output_toggle(LED);
}
}
void main(void)
{
disable_interrupts(GLOBAL); //deshabilitar interrupciones
disable_interrupts(INT_EEPROM); //deshabilitar interrupcion EEPROM
disable_interrupts(INT_RB); //deshabilitar interrupcion portb
disable_interrupts(INT_EXT); //deshabilitar interrupcion externa
ext_int_edge(H_TO_L); //interrupcion en flanco de bajada
port_b_pullups(TRUE); //pullups portb activadas
setup_TIMER_0(RTCC_INTERNAL | RTCC_DIV_1);
set_tris_a(0b00000000); //porta todo como salida
set_tris_b(0b00000000); //portb todo como salida
enable_interrupts(INT_TIMER0); //interrupcion del contador
enable_interrupts(GLOBAL); //interrupciones activadas
do
{
}while(TRUE);
}
-
Mira a ver si esto te sirve: http://www.todopic.com.ar/foros/index.php?topic=19025.0 (http://www.todopic.com.ar/foros/index.php?topic=19025.0)
Un saludo
-
Muchas gracias. Es justo lo que me pasa, entro demasiadas veces en la interrupción y se hace patente el error.