Hola amigos:
·Tengo algunas dudas respecto a un proyecto que estoy desarrollando. Tengo que monitorear tres pulsadores, lo cual estoy haciendo mediante la interrupción por cambio del puerto B, y discrimino en software qué pin cambió.
·Si cualquiera de los pines cambia de estado, se inicia una temporización de 2 segundos; la temporización se interrumpe si otro de los pines cambia de estado, y se produce un pulso de salida de 10 [ms] de duración. Si la cuenta termina normalmente, no hay pulso de salida.
·Mi problema se produce con la temporización; el período es de una duración real mucho mayor a la que yo esperaba, y no entiendo bien el porqué; supongo que se debe a las líneas de assembler que genera el compilador, pero aun así creo que es demasiado largo.
·A continuación adjunto el codigo que escribí, para que por favor me echen una manito:
Codigo:
//Funciona mediante la interrupción de cambio de PortB.
//En este caso, detecta los cantos de subida en los
//pines RB4 a RB7.
#include <16F628A.h>
#reserve 0x20
#byte FLAGS = 0x20
#bit FLAG5 = 0x20.5
#bit FLAG6 = 0x20.6
#bit FLAG7 = 0x20.7
#fuses INTRC_IO,NOWDT,NOPROTECT,NOBROWNOUT,NOLVP,NOMCLR,NOPUT,NOCPD
#use delay(clock=4000000)
#use rs232(baud=9600, parity=N, bits=8, xmit=PIN_B2, rcv=PIN_B1)
#use standard_io(B)
#int_rb
void rb_isr()
{
int change,last_b;
change = last_b ^ input_b();
if(bit_test(change,7)&&!bit_test(last_b,7))
FLAG7 = 1; // cambio RB7
if(bit_test(change,6)&&!bit_test(last_b,6))
FLAG6 = 1; // cambio RB6
if(bit_test(change,5)&&!bit_test(last_b,5))
FLAG5 = 1; // cambio RB5
//if(bit_test(change,4)&&!bit_test(last_b,4))
// FLAG4 = 1; // cambio RB4
last_b = input_b();
delay_ms(50); //Antirebotes
}
#int_rda
void rda_isr()
{
int dato;
dato = getc();
if(dato==49)
{
write_eeprom(0,49); //1 segundo
reset_cpu();
}
if(dato==50)
{
write_eeprom(0,50); //2 segundos
reset_cpu();
}
if(dato==51)
{
write_eeprom(0,51); //3 segundos
reset_cpu();
}
}
void pulse()
{
output_high(PIN_A1);
delay_ms(10);
output_low(PIN_A1);
}
main()
{
int16 i;
int stored,t;
ENABLE_INTERRUPTS(global);
ENABLE_INTERRUPTS(int_rb);
ENABLE_INTERRUPTS(int_rda);
stored = read_eeprom(0); //Leer seteo para la demora;
//se hace en cada reset.
if(stored==49)
t=20; //1 segundo = 50000 * 20 [us]
if(stored==50)
t=40; //2 segundos = 50000 * 40 [us]
if(stored==51)
t=60; //3 segundos = 50000 * 60 [us]
i=0;
while(1)
{
if(FLAG7) //CASO 1
{
output_high(PIN_A2);
while(!(FLAG6||FLAG5)&&(i<50000)) //Rutina de retardo
{
delay_us(t);
i++;
}
output_low(PIN_A2);
if(FLAG6||FLAG5)
pulse();
FLAGS=0; //bajar el flag
i=0; //Resetear contador
}
if(FLAG6) //CASO 2
{
output_high(PIN_A2);
while(!(FLAG7||FLAG5)&&(i<50000)) //Rutina de retardo
{
delay_us(t);
i++;
}
output_low(PIN_A2);
if(FLAG7||FLAG5)
pulse();
FLAGS=0; //bajar el flag
i=0; //Resetear contador
}
if(FLAG5) //CASO 3
{
output_high(PIN_A2);
while(!(FLAG7||FLAG6)&&(i<50000)) //Rutina de retardo
{
delay_us(t);
i++;
}
output_low(PIN_A2);
if(FLAG7||FLAG6)
pulse();
FLAGS=0; //bajar el flag
i=0; //Resetear contador
}
}
}
·Bueno, ese es mi problema; espero que alguien me pueda ayudar en esto. También pensé en temporizar contando interrupciones de TMR0, pero no logré realizarlo
·Agradeciendo de antemano su ayuda, se despide atte.
Fernando