Hello Experts,
Please help me to solve the below issue. I have written a code to handle two external interrupts (ENT1 and ENT2) and toggle port pins to confirm the ISR's execution. When both the interrupts are paralleled (i.e. raising is given at same time) only ISR assigned to ENT1 is executed. But when the interrupt at other input is delayed or given at different incidents both are serviced.
Please let me know hwat is the mistake I have done in the code. I need to handle all four external interrupts simultaneously which may occur even together. I am checking my code in Proteus. I am just a beginner in LPC2138.
Please help me.
__irq void eint1_srv (void); __irq void eint2_srv (void);
unsigned long temp=0;
#include <LPC21xx.H>
int main(void) {
IODIR0 = 0x0000FFFF;
EXTMODE = 0x0F;
EXTPOLAR = 0x0F;
PINSEL0 = 0xA0000000;
VICVectAddr1 = (unsigned long) eint1_srv;
VICVectAddr2 = (unsigned long) eint2_srv;
VICVectCntl1 = 0x20 | 15;
VICVectCntl2 = 0x20 | 16;
VICIntEnable = 0x0003C00C;
while(1)
{
++temp;
if (temp>1000) temp=0;
} }
__irq void eint1_srv (void) {
IO0PIN ^= 0x00000001;
EXTINT |= 1<<1; // Clear EINT1 interrupt flag
VICVectAddr = 0; // Acknowledge Interrupt
}
__irq void eint2_srv (void) {
IO0PIN ^= 0x00000002;
EXTINT |= 1<<2; // Clear EINT2 interrupt flag
EXTINT |= 1<<1; // Clear EINT1 interrupt flag"
This is _not_ how you should acknowledge the interrupt.
You are reading all flags that exists in the register (which can be more than just EINT1) and then you are writing that back together with the clear of EINT1 flag. How many flags do you think you are clearing? You should be able to notice what is happening if you try the debugger and look at this register...
Correct code:
EXTINT = 1<<1;
Another thing: Why do you show
You are enabling 6 bits while your code only sets up 2 interrupt handlers. Copy-paste of just subset of code? In that case, you should try to split out the different functionality into individual functions to make sure you get a better overview of what register writes belongs to what interrupt etc.
Thank you so much. With your input the program works fine.
I thought that the code EXTINT |= 1<<1; will only set first bit and will not disturb other bits of EXTINT register. But it messed up. In future i will try to use debugger too.
With the code VICIntEnable = 0x0003C00C; I enabled few other interrupts too, I just copied that code in this simplified program (to analyze ext interrupts alone) to locate the fault. In future I will try to write in clear way.
Thank you so much.
"I thought that the code EXTINT |= 1<<1; will only set first bit and will not disturb other bits of EXTINT register."
Note that reading EXTINT will tell you all pending external interrupts.
So:
EXTINT = EXTINT;
Might look like it doesn't upset anything, but it will pick up all pending external interrupts and write a one to those positions - so clearing all external interrupts.
And
EXTINT |= 1 << 1;
is just a short form for
EXTINT = EXTINT | (1 << 1);
So as you can see, you are not in control of how many bits you will actually affect with your original instruction.
With peripherial hardware, it really is important to remember that "writing the same value back" often is not a no-operation, since the registers aren't just RAM but have hardware connected that will react to the written values.