100 likes | 194 Views
ECE 447 Fall 2009. Lecture 8: TI MSP430 Interrupts, ISRs. ECE447: Interrupt Service Routines in Assembly. PORT1_ISR: ; respond to inputs on port1 reti ; return from interrupt ORG 0FFE8 DW PORT1_ISR -- or -- COMMON INTVEC ORG PORT1_VECTOR DW PORT1_ISR.
E N D
ECE 447 Fall 2009 Lecture 8: TI MSP430 Interrupts, ISRs
ECE447: Interrupt Service Routines in Assembly PORT1_ISR: ; respond to inputs on port1 reti ; return from interrupt ORG 0FFE8 DW PORT1_ISR -- or -- COMMON INTVEC ORG PORT1_VECTOR DW PORT1_ISR • The service routine itself is quite simple. (Note the “reti” instruction.) • To store the address of this ISR in the proper vector table location an ORG directive is used. • PORT1_VECTOR is defined in the header file relative to the INTVEC segment. The COMMON directive must be used to place the defined address (PORT1_ISR) in the correct location. This is useful for defining ISRs in multiple files.
ECE447: Interrupt Service Routines in C // tell the compiler the vector for this ISR #pragma vector = PORT1_VECTOR __interrupt void port1_isr(void) { // respond to inputs on port1 } • “#pragma vector” tells the compiler to store the address of this routine in the PORT1_VECTOR location. • “__interrupt” is used to tell the compiler that this function should end with a “reti” instruction.
ECE447: Interrupt Vector Jump Table • The jump table tells the program where to go when an interrupt occurs. • A vector points to the address where the interrupt service routine starts. • The MSP430 jump table is stored in RAM from 0xFFC0 to 0xFFFF and can be modified by the programmer.
ECE447: MSP430 Status Register • GIE (bit 3): Global Interrupt Enable • 1: Enables all interrupts (interrupts must also be enabled individually) • 0: Disable all interrupts NOTE: SR is saved on the stack and cleared when an ISR is executed.
ECE447: Setting and Clearing the General Interrupt Mask • Assembly EINT – Enable interrupts (set GIE) DINT – Disable interrupts (clear GIE) • C asm(“ EINT”); asm(“ DINT”); • C (#include intrinsics.h) __enable_interrupt(); __disable_interrupt();
ECE447: MSP430 Interrupt execution flow RAM JUMP TABLE 0xFFFF SR PC 00F8 EE 10EE 10 0000 0xFFC0 STACK F8 00 SP RAM SERVICE ROUTINE 0x10EE
Interrupts Example: Toggling LEDs // Listing 6.5: Toggles LEDs in ISR using interrupts from timer A CCR0 // in Up mode with a period of about 0.5s #define LED1 BIT3 #define LED2 BIT4 void main (void) { WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer P2OUT = ~LED1; // Preload LED1 on, LED2 off P2DIR = LED1 | LED2; // Set pins with LED1,2 to output TACCR0 = 49999; // Upper limit of count for TAR TACCTL0 = CCIE; // Enable interrupts on Compare 0 TACTL = MC_1 | ID_3 | TASSEL_2 | TACLR; // Set up and start Timer A // “Up to CCR0” mode, divide clock 8, clock SMCLK, clear timer __enable_interrupt ( ); // Enable interrupts (intrinsic) for (;;) { // Loop forever doing nothing } // Interrupts do the work } // Interrupt Service Routine for Timer A channel 0 #pragma vector = TIMERA0_VECTOR // Assoc. the funct. w/ an interrupt vector __interrupt void TA0_ISR (void) // name of the interrupt function (can be anything) { P2OUT ^= LED1 | LED2; // Toggle LEDs }
ECE447: MSP430 Interrupt Class Exercise Write a program that collects samples from input Port 2. A signal line that indicates a new data value is available is connected to pin P1.0. Use an interrupt to detect a rising edge on the P1.0. When an interrupt is triggered the value on Port2 should be stored into a byte array of 32 entries. When 32 samples have been collected, P1.7 should be driven as an output high to indicate the memory is “full”