>>>Warning216”timer1.c”Line86(0,1):Interrupts disabled during call to prevent re-entrancy: (@delay_ms1)#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.Lo mejor es que utilices el hw con las configuraciones adecuadas, ello evitará tener que utilizar la recarga por sw del temporizador, muy aconsejable si lo que intentas diseñar e implementar es un cronómetro.
void ledverde(){
long i=0,a=0;
while(i<65533){
output_high(LED);
i++;
}
while(a<65534){
output_low(LED);
a++;
}
}
Se queda enganchado en los bucles y no sale de ahí y no atiende a la interrupción, si bajo el valor 65534 a un valor de por ejemplo 300 si me funciona pero el bucle es tan rápido que el led se queda fijo iluminado.#include "C:\Documents and Settings\Thulsa_Doom\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;
char banderaTIMER2=0;
//*****************************Interrupciones***********************************
#int_TIMER2
void TIMER1_isr(){
banderaTIMER2 = 1;
}
void ledverde(){
long i=0,a=0;
while(i<65533){
output_high(LED);
i++;
}
while(a<65534){
output_low(LED);
a++;
}
}
void main(){
int limitemlseg=999;
int limiteseg=59;
int limitemin=59;
port_b_pullups(true);
setup_timer_2(T2_DIV_BY_1,250,1);
enable_interrupts(INT_TIMER2);
enable_interrupts(global); //Activamos las interrupciones globales
lcd_init();
output_low(PIN_A4);
while(TRUE){
if(banderaTIMER2==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;
}
}
}
}
}
banderaTIMER2=0;
}
else{
lcd_putc("\f");
lcd_gotoxy(1,1); printf(lcd_putc,"TIEMPO");
lcd_gotoxy(1,2); printf(lcd_putc,"%02u:%02u",min,seg);
ledverde();
}
}
}
Hola doom,
asegurate que la interrupcion sea un numero redondo y exacto, por ejemplo no sirven 1,001 ms ya que al acumulado existira un desfase
yo lo haria de la siguiente manera:
cristal Mhz 4
set_timer2 249
prescaler 4
postcaler 1
interrupcion 1000 uS
Código: C
int16 milisegundos = 0; int8 segundos = 0; int8 minutos = 0; int8 horas = 0; int1 flag_segundos = 0; #int_timer2 void timer2(void) { if(++milisegundos > 999) { milisegundos = 0; flag_segundos = 1; } if(milisegundos == 0)output_low(led); if(milisegundos == 500)output_high(led); } void main (void) { while(true) { if(flag_segundos) { flag_segundos = 0; ///aqui puedes poner la muestra en el lcd ///esto ocurre cada 1 segundo if(++segundos > 59) { segundos = 0; if(++minutos > 59) { minutos = 0; if(++horas > 23) { horas = 0; } } } } } }
En el foro hay muchos ejemplos de este contador.
saludos.
while(pulsadorstart==1)
{
if(flag_segundos){
flag_segundos = 0;
lcd_putc("\f");
lcd_gotoxy(1,1); printf(lcd_putc,"TIEMPO");
lcd_gotoxy(1,2); printf(lcd_putc,"%02u:%02u",min,seg);
if(++segundos > 59){
segundos = 0;
if(++minutos > 59){
minutos = 0;
}
}
}
if(pulsadorcara == 0)output_high(SSR1);
if(pulsadorcara == 1){
output_high(SSR2);
}
if(pulsadorcara == 2){
output_high(SSR1);
output_high(SSR2);
}
} #BYTE TRIA = 0x85
#BYTE PORTA = 0x05en el main indicar que es un puerto solo de salida.TRISA = 0x00; y luego en el bucle de conteo solo he puesto PORTA = variable;donde variable es por ejemplo 0b000001PORTA = (variable1 & 0b010011)+variable2); y va a la perfección