View previous topic :: View next topic |
Author |
Message |
Abid
Joined: 25 Oct 2013 Posts: 3
|
12F675 Interrupt problem |
Posted: Fri Oct 25, 2013 7:38 pm |
|
|
I have tried a whole day now to get the PIC12F675 to toggle LEDs on button press by interrupt. The system appear to crash when ISR is called. (I want to use the global variable)
Heres the (non working) code so far:
Code: | #include <12F675.h>
#fuses INTRC_IO,NOWDT,NOPUT,BROWNOUT,NOPROTECT,NOMCLR,NOCPD
#use delay(clock=4000000)
#define LED_B PIN_A1
#define LED_G PIN_A2
#define Button PIN_A3
#define LED_R PIN_A4
int State = 0;
#INT_RA
void Cycle_States(void)
{
delay_ms(10);
State = !State;
}
void main()
{
enable_interrupts(INT_RA3);
ext_int_edge(H_TO_L);
enable_interrupts(GLOBAL);
while(TRUE)
{
if(State==0)
{
output_low(LED_G);
output_high(LED_R);
}
else
{
output_high(LED_G);
output_low(LED_R);
}
}
} |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 25, 2013 8:08 pm |
|
|
You have to read PortA inside the #int_ra routine to clear the mismatch
condition that caused the interrupt. If you don't do that, the PIC will
continuously interrupt and it will appear to "lock up" or "crash".
See the sample code that I have posted near the end of this thread, which
shows how to read PortA inside the #int_ra routine:
http://www.ccsinfo.com/forum/viewtopic.php?t=32702 |
|
|
Abid
Joined: 25 Oct 2013 Posts: 3
|
|
Posted: Fri Oct 25, 2013 9:21 pm |
|
|
Thank you very very much PCM programmer. I have resolved this isse by adding Port reading as you have said.
But, now I have another problem: The H_TO_L condition appear that it does not work and every button push work as it was 2 actions (The button down toggle a LED and the button up toggle the following led).
Code: | #include <12F675.h>
#fuses INTRC_IO,NOWDT,NOPUT,BROWNOUT,NOPROTECT,NOMCLR,NOCPD
#use delay(clock=4000000)
#define LED_B PIN_A1
#define LED_G PIN_A2
#define Button PIN_A3
#define LED_R PIN_A4
unsigned int State = 0;
#INT_RA
void ButtonISR()
{
char Dummy;
if(State==2)
State=0;
else
State++;
Dummy=input_a(); //Read port to clear interrupt
delay_ms(100); //Debounce
}
void State0()
{
output_low(LED_B);
output_high(LED_R);
}
void State1()
{
output_low(LED_R);
output_high(LED_G);
}
void State2()
{
output_low(LED_G);
output_high(LED_B);
}
void main()
{
char Dummy;
setup_comparator(NC_NC);
Dummy=input_a();
clear_interrupt(INT_RA);
ext_int_edge(H_TO_L);
enable_interrupts(INT_RA3);
enable_interrupts(GLOBAL);
while(TRUE)
{
switch(State)
{
case 0: State0(); break;
case 1: State1(); break;
default: State2(); break;
}
}
}
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Oct 25, 2013 10:29 pm |
|
|
Quote: | ext_int_edge(H_TO_L);
enable_interrupts(INT_RA3);
The H_TO_L condition appear that it does not work and every button push work as it was 2 actions.
|
The ext_int_edge() function doesn't work with INT_RA. It only works with #int_ext.
How to detect only the falling edge:
You can read the input pin inside the #int_ra routine, and if it's at a low
level, then you have detected the falling edge. Then perform your action.
Don't do anything if you read the signal as a high level, because it means
the interrupt was caused by the rising edge (L to H). |
|
|
Abid
Joined: 25 Oct 2013 Posts: 3
|
|
Posted: Sat Oct 26, 2013 2:31 am |
|
|
Thank PCM programmer !! |
|
|
|