Interrupción en GP3/MCLR 12F675

#1
Buenas de nuevo, hoy estoy haciendo un programa que mediante una "matriz analógica", al pulsar el botón de interrupción y a la vez uno de la matriz, lee el valor, lo asigna a una de las salidas, enciende/apaga el led de la salida y escribe en la eeprom el valor de esa salida, para cuando se reinicie, lo lea y siga en el mismo estado.

Dadas las pocas entradas de éste PIC, me está siendo completamente necesario (sé que no es bueno para la salud del micro) usar la GP3/MCLR como input, y a su vez como interrupción. Pero... No se activa la interrupción.

Creo, que el problema es la directiva del preprocesador usada antes de la función isr, he probado con #INT_RA e #INT_DEFAULT pero ninguna está dando el resultado esperado en la simulación con Proteus.

Más datos: la cuestión es que haya 4 LEDS indicadores, 1 entrada de interrupción y 1 analógica. Como no me acordaba, antes intenté utilizar la GP3 como output y no funcionaba dicha salida, pero el resto sí, por lo que el programa está bien hecho. Dejo el código:

Código:
#Include <12F675.h>
#device ADC=10
#Fuses INTRC_IO,NOWDT,NOPUT,NOPROTECT,NOCPD,NOMCLR
#Use delay(clock=4000000)
#Byte trisio=getenv("SFR:TRISIO")
#byte port=0x05
#bit  L1=0x05.5
#bit  L2=0x05.4
#bit  L3=0x05.2
#bit  L4=0x05.1
#bit  in=0x05.3
#Bit GIE=0x0B.7
#Bit  RBI=0x0B.3
#Bit  RBF=0x0B.0

int16 lect;

void INTENAB(void){ //Activa la interrupción en todo GPIO
   GIE=1;
   RBF=0; //Bandera de cambio
   RBI=1; //Habilitar INT por cambio
}

#INT_RA
void intsr(){
   while(in==1);
   read_adc(ADC_START_ONLY);
   delay_us(20);
   lect=read_adc(ADC_READ_ONLY);
   delay_us(20);
   if((lect<520)&&(lect>500)){
      L1=!L1;
      write_eeprom(0,L1);
   }
   if((lect<340)&&(lect>300)){
      L2=!L2;
      write_eeprom(1,L2);
   }
   if((lect<730)&&(lect>650)){
      L3=!L3;
      write_eeprom(2,L3);
   }
   if((lect<110)&&(lect>80)){
      L4=!L4;
      write_eeprom(3,L4);
   }
   INTENAB();
}
   

void main(){
   trisio=0b00001001;
   port=0x00;
   setup_adc_ports(sAN0);    
   setup_adc(ADC_CLOCK_DIV_8);      
   set_adc_channel(0); 
   delay_us(20);
   L1=read_eeprom(0);
   L2=read_eeprom(1);
   L3=read_eeprom(2);
   L4=read_eeprom(3);
   INTENAB();
   while(1);
}
Muchas gracias a todos.

EDITO: He encontrado la solución.

La cuestión es programar el registro IOC (0x96h), que configura una por una las entradas que se utilizarán para la interrupción, en mi caso con un IOC=0b00001000; en main() es suficiente.

3 horas con ésto y lo ponía en la datasheet del PIC :oops:
 
Última edición:
#2
Muy bien, sólo como recordatorio: en los PIC's el pin que se comparte con la señal de MCLR sólo es funcional como entrada, no como salida.
Tómalo en cuenta para futuros proyectos.

Saludos
 
Arriba