hola gente, soy nuevo en esto de los microcontroladores y he tenido problemas para trabajar con dos interrupciones, especificamente int ext y int timer1, el codigo lo que hace es detectar en que sentido se mueve el motor de una puerta y en base a esto realizar una accion, la puerta tiene unos sensores y al acercarse alguien se abre hacia adentro, en ese caso el programa solo enciende un led, pero si una persona viene desde dentro la puerta no se abre, lo que hice en ese caso fue usar el contador que le puse al encoder y si se decrementa (llegado a ciertos parametros) activa unos reles que estan conectados a un modulo de la puerta que regula en que sentido abre y da la alimentacion para que abra, hasta ahi todo bien, el problema que tengo es que quiero que pasado 10 segundos la puerta vuelva a su funcionamiento normal desctivando la alimentacion y quitando el cambio de polaridad, eso lo quiero hacer con el timer 1 o timer 0, para el caso da lo mismo, la cosa es que no se como configurar el timer para que empieze a contar desde una linea especifica y para que no tenga conflictos con la interrupcion externa, mas abajo esta el codigo de lo que llevo, desde ya agradesco su ayuda
Código:
#Include <18F452.h>
#Fuses XT, NOWDT, NOPROTECT, NOLVP, BROWNOUT
#use Delay( Clock = 4000000 )
#include <LCD.c>
#Byte PortA = 0xF80
#Byte PortB = 0xF81
#Byte PortC = 0xF82
#Byte PortD = 0xF83
// ------ Variable Global ------
int16 cont = 3000;
int temp = 0;
int flag_temp;
// --------- Interrupción ---------
#int_TIMER1
void TIMER1_isr(void) {
disable_interrupts(INT_TIMER1);
set_timer1(3036);
temp++;
if(temp==20){
flag_temp=0;
}
}
#INT_EXT // Interrupción Externa por RB0: Decodificación de Encoder.
Void IntRB0()
{
If (Bit_Test(PortB, 0)) // Si RB0 se ha puesto a 1 (flanco de subida),
{
Ext_Int_Edge(H_TO_L); // entonces activar la siguiente interrupción por flanco de
// bajada.
If (Bit_Test(PortB, 1)) // Si RB1 está a 1,
{
cont++; // entonces incrementar una unidad el valor de cont.
}
}
Else // Si RB0 se ha puesto a 0 (flanco de bajada),
{
Ext_Int_Edge(L_TO_H); // entonces activar la siguiente interrupción por flanco de
// subida.
If (Bit_Test(PortB, 1)) // Si RB1 está 1,
{
cont--; // entonces decrementar una unidad el valor de cont.
}
}
}
Void Main(){ // Inicio y configuración.
lcd_init();
Port_B_Pullups(FALSE); // Configuración para el PIC 18F4550.
Setup_ADC_Ports(NO_ANALOGS); // Sin comparadores ni ADCs, todo digital, etc...
Setup_adc(ADC_CLOCK_DIV_2);
Setup_spi(SPI_SS_DISABLED);
Setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
Setup_timer_2(T2_DISABLED,0,1);
set_timer1(3036);
Enable_Interrupts(Int_Ext); // Activar Interrupción Externa a través de RB0.
Ext_Int_Edge(L_TO_H); // Inicialmente detectar interrupción por flanco de subida.
Enable_Interrupts(GLOBAL); // Interrupciones Generales Activadas.
Set_Tris_A(0b00000000); // Puerto A todo entradas,
Set_Tris_B(0b11111111); // Puerto B todo entradas, sólo usamos las entradas RB0 yRB1.
Set_Tris_C(0b00000000);
PortA=0;
// ---------- Programa Principial ----------
While (True){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
while((cont>3010)&&(cont<=3150)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
bit_set(PORTA,2);
//delay_ms(200);
}
bit_clear(PORTA,2);
flag_temp = 1;
enable_interrupts(INT_TIMER1);//inicia temporizador 10seg por interrupcion (definir un
//flag_temp que de cero cuando se cumplan 10 segundos)
while((cont<2995)&&(cont>=2870)&&(flag_temp==1)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont);
bit_set(PORTA,0);
delay_ms(100);
bit_set(PORTA,1);
}
while((cont<2995)&&(cont>=2870)&&(flag_temp==0)){
lcd_gotoxy(5,1);
printf(LCD_PUTC, "Posicion");
lcd_gotoxy(7,2);
printf(LCD_PUTC, "%Ld",cont); //ver posicion de encoder por LCD
bit_clear(PORTA,1);//saco alimentacion
delay_ms(100);
bit_clear(PORTA,0);//reestablesco el sentido de giro
}
}
}