Hola a todos, tengo un problema al intentar hacer un cronómetro con cualquiera de los timer´s del pic a ver si me pueden orientar .
Resulta que si monto un cronómetro utilizando la interrupción del TIMER1 por ejemplo, y muestro los valores de los minutos y segundos en pantalla, (solo eso), el cronómetro es estable, me cuesta mucho dejarlo ajustado a la cuenta de un cronómetro real, según he leído dicen que eso es imposible.
Yo lo he intentado pero cuando cargo el buffer, por ejemplo con esto 65480 me va más rápido que un conteo normal estándar, y si le cambio solo un dígito, por ejemplo 65489, me va más lento, no consigo ajustarlo a ver si me pueden ayudar en eso.
Otra cosa que me pasa es que si empiezo a meterle código, el cronómetro se me desestabiliza y no me hace el conteo simétrico, me refiero que empieza a contar bien pero cada 5 segundos cuenta el siguiente dos veces, como que utiliza un ciclo más que los demás conteos
Una de las cosas que al parecer no le sienta bien son los delays, cada vez que en el código utilizo un delay, da igual donde lo ponga, cuando compilo, el compilador me da este warning:
>>>Warning216”timer1.c”Line86(0,1):Interrupts disabled during call to prevent re-entrancy: (@delay_ms1)
Según interpreto me está diciendo que mientras este el delay se desactivan las interrupciones
Yo pensaba que las interrupciones de los timers trabajan ajenas a la ejecución del programa general, que se carga el buffer y mientras se ejecuta el programa este se va ejecutando hasta que se desborda y atiende el código que está en la interrupción, por eso no entiendo que mientras haya un delay no se atienda la interrupción.
Por ejemplo si hago este código:
#include "C:\Documents and Settings\Programacion\Escritorio\timer1\timer1.h"
//****************************Definiciones de pines***********************
#define start PIN_B6 //Interruptor de comienzo
#define LED PIN_A2 //Led que indica que el sistema está en ejecución
//*****************************Declaraciones Globales***************************
int mlseg=999,seg=59,min=59;
int switchstart;
//*****************************Interrupciones***********************************
#int_TIMER1
void TIMER1_isr(){
int limitemlseg=999;
int limiteseg=59;
int limitemin=59;
set_timer1(65480);
if(switchstart==1){
mlseg--;
if(mlseg > limitemlseg){
mlseg=999;
if(mlseg==limitemlseg){
seg--;
if(seg > limiteseg){
seg=59;
if(seg == limiteseg){
min--;
if(min > limitemin){
min=59;
}
}
}
}
}
}
}
#int_RB
void RB_isr(){ //Interrupción que atiende a los puertos entre B4 y B7
int limitestart=1;
if(input(start)==0){
delay_ms(20);
if(input(start)==0){
switchstart++;
if(switchstart > limitestart){
switchstart = 0;
}
}
}
}
//****************************Subrutinas****************************************
void ledverde(){
output_high(LED);
delay_ms(100);
output_low(LED);
delay_ms(300);
}
//****************************Programa Principal********************************
void main(){
port_b_pullups(true);
set_timer1(65480); //Carga del buffer del timer1 para que el salto sea a 1 ms
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); //Configuración del timer1 para el cronómetro
enable_interrupts(INT_TIMER1);
enable_interrupts(INT_RB);
enable_interrupts(global); //Activamos las interrupciones globales
lcd_init();
while(TRUE){
lcd_putc("\f");
lcd_gotoxy(1,1); printf(lcd_putc,"TIEMPO");
lcd_gotoxy(1,2); printf(lcd_putc,"%02u:%02u",min,seg);
ledverde();
}
}
Si dejo la subrutina del ledverde(), el cronómetro se hace inestable pero si la saco se vuelve estable.
¿Hay alguna manera de arreglar esto y que no se desequilibre el conteo cuando meto un delay?