This message contains an entire topic ported from a separate forum. The original message and all replies are in this single message. We have seeded this new forum with selected information that we expect will be of value to you as you search for answers to your questions.
Posted: Thu Dec 15, 2005 1:09 pm
I am having problem with generating an interrupt with a simple program. The listing is below:
Interrupt routine:
Code:
void maintimer(void) { static unsigned char flipflop; TC0 = TCNT + LOOP_TIME; // add base time to TC0 if(flipflop > 0) { PTM &= ~ALARM_LED; // LED is off flipflop = 0; } else { PTM |= ALARM_LED; // LED is on flipflop = 1; } } here is the main loop void main(void) { int flag = 0; InitCPU(); PTM = 0; asm("cli"); //enable global interrupts while(1) { if(flag > 0) { PTM &= ~CPU_LED; // LED is off flag = 0; } else { PTM |= CPU_LED; // LED is on flag = 1; } } }
The interrupt runs for a few milliseconds and then the program hangs. Any ideas as to why?
Thanks
Posted: Thu Dec 15, 2005 1:28 pm
You should clear timer flag in ISR. TFLG1 = 1 for TC0 interrupt.
Posted: Thu Dec 15, 2005 4:44 pm
My HC12 is actually an HCS12 and I have TSCR1 set to automatically clear the flag. I tried it any way and it still doesn't work. I believe the interrupt is actually occurring but runs for just a few cycles then quits. main() quits too. If I don't enable global interrupts then main() runs just fine. With global interrupts enabled with asm("cli") main() runs for about 50ms then stops. My maintimer() interrupt runs for the same time as main().
Any additional ideas you have would be appreciated.
Posted: Thu Dec 15, 2005 4:54 pm
From your excerpt it is not clear to me whether you declared your interrupt routine as such, that is, that the compiler knows to "return from interrupt" thus cleaning up the stack, instead of just returning, leaving all the registers on the stack and thus making it grow and grow until the uC goes into the woods.
Posted: Thu Dec 15, 2005 5:48 pm
Have you disabled the watchdog ? If not, you must kik it
Posted: Thu Dec 15, 2005 6:31 pm
Yes I have. It's the first thing I do.
Posted: Fri Dec 16, 2005 1:53 am
You need to specify your maintimer routine as an interrupt routine. This is necessary so the compiler know to end it with the RTI (return from interrupt) instruction rather than the RTS (return from subroutine) instruction.
RTI and RTS are different in the way they handle the stack - RTI pulls registers D, X, Y, PC and CCR from the stack, to restore their values that were stored on the stack just before the interrupt service routine started.
The use of the RTS instruction in this case corrupts the HCS12 registers, and your program therefore hangs up.
Posted: Fri Dec 16, 2005 11:55 am
I have finally determined the problem. For my port initialization I am using PORTA as inputs and had the pullup control register PUCR = 0x01; where I should have used PUCR |= 0x01; PORTE was being effected where I was disabling its pullups.
Thanks for your help.