Hi!
I am learning to use the MC9S12XEP100 with a evaluation board. I'm trying to use an interrupt to light two LEDs on the board. Whenever I interrupt the system via port P the microcontroller crashes and debugger says ILLEGAL_BP. I assume that this is due to using wrong interrupt number on the interrupt handler function.
I have tried these interrupt handler declarations (the two first ones compile ok):
interrupt (IVBR+Vportp) void PP0_ISR(void) {...
interrupt (IVBR+0x008E) void PP0_ISR(void) {
interrupt (0xFF8E) void PP0_ISR(void)
interrupt (0xFF00+Vportp) void PP0_ISR(void) {...
interrupt (VectorNumber_Vportp) void PP0_ISR(void) {...
With the debugger I can see that the I flag in CCR gets set when I interrupt port P, but the program does not go to my interrupt handler. Instead it goes to an endless loop and crashes. I have used the interrupt vector locations table on
MC9S12XEP100 Reference Manual to determine the interrupt number for the handler. But they don't work. Or there is something else wrong in my interrupt handler declarations.
Here's the whole code for my program:
#include <hidef.h> /* common defines and macros */
#include "MC9S12XEP100.h" /* derivative-specific definitions */
void PeriphInit(void) {
__asm SEI;
//Configures PB[0..3] as output, PB[4..7] as input
PORTB = 0x00; //Initialize to 0
DDRB = 0x0F;
// Enables pull-ups on PB port to drive the LEDs
PUCR |= 0x02;
//Interrupt module configuration:
//Set the 8 address window of Interrupt Request Configuration Address Register
//(INT_CFADDR) to base + 0x8E
INT_CFADDR = 0x80;
//base + 0x80
INT_CFDATA0 = 0x00;
//base + 0x82
INT_CFDATA1 = 0x00;
//base + 0x84
INT_CFDATA2 = 0x00;
//base + 0x86
INT_CFDATA3 = 0x00;
//base + 0x88
INT_CFDATA4 = 0x00;
//base + 0x8A
INT_CFDATA5 = 0x00;
//base + 0x8C
INT_CFDATA6 = 0x00;
//base + 0x8E, Port P interrupt
INT_CFDATA7 = 0x06;
//Configures PP0 as input
PTP = 0x00;
DDRP &= 0xFE;
//Enables pull-up on PP0
PERP |= 0x01;
//Port P pin 0 interrupts on falling edge
PPSP &= 0xFE;
//Enables the Port P pin 0 to interrupt
PIEP |= 0x01;
//Write 1 to the interrupt flag register to clear the flag
PIFP = 0x01;
__asm CLI;
}
void main(void) {
/* put your own code here */
PeriphInit();
for(; {
PORTB = 0x00;
if(!PORTB_PB4)
PORTB_PB0 = 1;
if(!PORTB_PB5)
PORTB_PB1 = 1;
if(!PORTB_PB6)
PORTB_PB2 = 1;
if(!PORTB_PB7)
PORTB_PB3 = 1;
_FEED_COP(); /* feeds the dog */
} /* loop forever */
/* please make sure that you never leave main */
}
interrupt (IVBR+0x008E) void PP0_ISR(void) {
unsigned int j;
PORTB_PB1 = 1;
PORTB_PB2 = 1;
//Wait...
for(j = 0; j <= 2000; j++);
//Write 1 to the interrupt flag register to clear the flag
PIFP = 0x01;
}
Solved! Go to Solution.
IVBR is interrupt vectors base register, you can't use it to specify ISR vector number. You need this number at compile time. IVBR is for run time. This should work
interrupt VectorNumber_Vportp void PP0_ISR(void) {...
Most likely you are using banked memory model. So you need to force ISR's to nonbanked memory:
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt VectorNumber_Vportp void PP0_ISR(void)
{
}
#pragma CODE_SEG DEFAULT
IVBR is interrupt vectors base register, you can't use it to specify ISR vector number. You need this number at compile time. IVBR is for run time. This should work
interrupt VectorNumber_Vportp void PP0_ISR(void) {...
Most likely you are using banked memory model. So you need to force ISR's to nonbanked memory:
#pragma CODE_SEG __NEAR_SEG NON_BANKED
interrupt VectorNumber_Vportp void PP0_ISR(void)
{
}
#pragma CODE_SEG DEFAULT
Thanks a lot! Those #pragmas fixed the code.