Chapter 5 Interrupts Interrupts and Exceptions Di Jasio

  • Slides: 22
Download presentation
Chapter 5 - Interrupts

Chapter 5 - Interrupts

Interrupts and Exceptions Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupts and Exceptions Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Service Functions Interrupt service functions are not supposed to return any value (use

Interrupt Service Functions Interrupt service functions are not supposed to return any value (use type void). q No parameter can be passed to the function (use parameter void). q They cannot be called directly by other functions. q Ideally, they should not call any other function. q Di Jasio - Programming 32 -bit Microcontrollers in C

Sources of Interrupt Among the external sources available for the PIC 32 MX 3,

Sources of Interrupt Among the external sources available for the PIC 32 MX 3, there are: q 5 x External pins with level trigger detection q 22 x External pins connected to the Change Notification module q 5 x Input Capture modules q 5 x Output Compare modules q 2 x Serial port interfaces (UARTs) q 4 x Synchronous serial interfaces (SPI and I 2 C) q 1 x Parallel Master Port Among the internal sources we count: q 1 x 32 internal (core) timer q 5 x 16 -bit Timers q 1 x Analog-to-Digital Converter q 1 x Analog Comparators module q 1 x Real Time Clock and Calendar q 1 x Flash controller q 1 x Fail Safe Clock Monitor q 2 x Software interrupts q 4 x DMA channels Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Flags & Priorities q The Interrupt Enable bit (typically represented with the name

Interrupt Flags & Priorities q The Interrupt Enable bit (typically represented with the name of the interrupt source peripheral followed by the suffix –IE in the device datasheet), a single bit of data: q q The Interrupt Flag (typically represented with a suffix -IF), a single bit of data: is set each time the specific trigger event is activated, independently of the status of the enable bit. q q Notice how, once set, it must be cleared (manually) by the user. In other words it must be cleared before exiting the interrupt service routine, or the same interrupt service routine will be immediately called again. The Group Priority Level (typically represented with a suffix -IP). Interrupts can have up to 7 levels of priority (from ipl 1 to ipl 7). Should two interrupt events occur at the same time, the highest priority event will be served first. q q When cleared, the specific trigger event is prevented from generating interrupts. When set, it allows the interrupt to be processed. At power on, all interrupt sources are disabled by default. Three bits encode the priority level of each interrupt source. At any given point in time, the PIC 32 execution priority level value is kept in the MIPS core status-register. Interrupts with a priority level lower than the current value will be ignored. At power on, all interrupt sources are assigned a default level of ipl 0, once more assuring all interrupts are disabled. The Sub-priority Level. Two more bits are allocated to define four more possible levels of priority within a priority group. If two events of the same priority level occur simultaneously, the one with the highest sub-priority will be selected first. q Once an interrupt of a given priority group is selected though, any following interrupts of the same level (even if of higher sub-priority) will be ignored until the current interrupt (flag) has been cleared. Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Vectors Table Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Vectors Table Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Handlers in C You can declare an Interrupt handler function in C using

Interrupt Handlers in C You can declare an Interrupt handler function in C using one of two syntax options: q Example using attributes syntax: void __attribute__ (( interrupt(ipl 1), vector(0))) Interrupt. Handler( void) { // your interrupt service routine code here. . . } // interrupt handler q Example using pragma syntax: #pragma interrupt Interrupt. Handler ipl 1 vector 0 void Interrupt. Handler( void) { // interrupt service routine code here. . . } // interrupt handler Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Service Macro q A more compact alternative using the predefined macro: __ISR( v,

Interrupt Service Macro q A more compact alternative using the predefined macro: __ISR( v, ipl) q Example: void __ISR( 0, ipl 1) Interrupt. Handler (void) { // interrupt service routine code here. . . } // interrupt handler Di Jasio - Programming 32 -bit Microcontrollers in C

“int. h” Support Functions & Macros q INTEnable. System. Single. Vectored. Int(); q q

“int. h” Support Functions & Macros q INTEnable. System. Single. Vectored. Int(); q q INTEnable. System. Multi. Vectored. Int(); q q Same as the above, but enables the vectored interrupt management mode of the PIC 32. m. XXSet. Int. Priority( x); q q q This function follows a precise sequence of initialization of the interrupt control module (as prescribed in the device datasheet) so to enable the basic interrupt management mode of the PIC 32. This is actually just a placeholder for a long list of similar macros (replace the XX with the interrupt source abbreviations from Interrupt Vector Table to obtain each macro name). It assigns a given priority level (from 0 to 7) to the chosen interrupt source. m. XXClear. Int. Flag(); q This represents an entire class of macros that allow us to clear the interrupt flag (–IF bit) of the chosen interrupt source. Di Jasio - Programming 32 -bit Microcontrollers in C

Single. c Example /* ** Single vector Interrupt test */ #include <plib. h> int

Single. c Example /* ** Single vector Interrupt test */ #include <plib. h> int count; void __ISR( 0, ipl 1) Interrupt. Handler( void) { count++; m. T 2 Clear. Int. Flag(); } // interrupt handler main() { // 1. init timers PR 2 = 15; T 2 CON = 0 x 8030; // 2. init interrupts m. T 2 Set. Int. Priority( 1); INTEnable. System. Single. Vectored. Int(); m. T 2 Int. Enable( 1); // 3. main loop while( 1); } // main Di Jasio - Programming 32 -bit Microcontrollers in C

Simulating “single. c” Di Jasio - Programming 32 -bit Microcontrollers in C

Simulating “single. c” Di Jasio - Programming 32 -bit Microcontrollers in C

Nesting. c Example /* ** Single Vector Interrupt Nesting */ #include <plib. h> int

Nesting. c Example /* ** Single Vector Interrupt Nesting */ #include <plib. h> int count; void __ISR( 0, ipl 1) Interrupt. Handler( void) { // 1. re-enable interrupts immediately (nesting) asm("ei"); // 2. check and serve the highest priority first if ( m. T 3 Get. Int. Flag()) { count++; // clear the flag and exit m. T 3 Clear. Int. Flag(); } // _T 3 // 3. check and serve the lower priority else if ( m. T 2 Get. Int. Flag()) { // spend a LOT of time here! while( 1); // before clearing the flag and exiting m. T 2 Clear. Int. Flag(); } // _T 2 } // Interrupt Handler Di Jasio - Programming 32 -bit Microcontrollers in C

Nesting. c Example (cont. ) main() { // 4. PR 3 = PR 2

Nesting. c Example (cont. ) main() { // 4. PR 3 = PR 2 = T 3 CON T 2 CON init timers 20; 15; = 0 x 8030; // 5. init interrupts m. T 2 Set. Int. Priority( 1); m. T 3 Set. Int. Priority( 3); INTEnable. System. Single. Vectored. Int(); m. T 2 Int. Enable( 1); m. T 3 Int. Enable( 1); // main loop while( 1); } // main Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Vector Table Di Jasio - Programming 32 -bit Microcontrollers in C

Interrupt Vector Table Di Jasio - Programming 32 -bit Microcontrollers in C

Multiple. c Example /* ** Multiple Vector Interrupt */ #include <plib. h> int count;

Multiple. c Example /* ** Multiple Vector Interrupt */ #include <plib. h> int count; void __ISR( _TIMER_3_VECTOR, ipl 7) T 3 Interrupt. Handler( void) { // 1. T 3 handler is responsible for incrementing count++; // 2. clear the flag and exit m. T 3 Clear. Int. Flag(); } // T 3 Interrupt Handler void __ISR( _TIMER_2_VECTOR, ipl 1) T 2 Interrupt. Handler( void) { // 3. re-enable interrupts immediately (nesting) asm("ei"); // 4. T 2 handler code here while( 1); // 5. clear the flag and exit m. T 2 Clear. Int. Flag(); } // T 2 Interrupt Handler Di Jasio - Programming 32 -bit Microcontrollers in C

Multiple. c Example (cont. ) main() { // 5. PR 3 = PR 2

Multiple. c Example (cont. ) main() { // 5. PR 3 = PR 2 = T 3 CON T 2 CON init timers 20; 15; = 0 x 8030; // 6. init interrupts m. T 2 Set. Int. Priority( 1); m. T 3 Set. Int. Priority( 7); INTEnable. System. Multi. Vectored. Int(); m. T 2 Int. Enable( 1); m. T 3 Int. Enable( 1); // 7. main loop while( 1); } // main Di Jasio - Programming 32 -bit Microcontrollers in C

A Real Time Clock /* ** A real time clock ** */ #include <plib.

A Real Time Clock /* ** A real time clock ** */ #include <plib. h> int d. Sec = 0; int Min = 0; // 1. Timer 1 interrupt service routine void __ISR( 0, ipl 1) T 1 Interrupt( void) { // 1. 1 increment the tens of a second counter d. Sec++; if ( d. Sec > 9) // 10 tens in a second { d. Sec = 0; Sec++; // increment the seconds counter if ( Sec > 59) // 60 seconds make a minute { Sec = 0; Min++; // increment the minute counter if ( Min > 59)// 59 minutes in an hour Min = 0; } // minutes } // seconds // 1. 2 clear the interrupt flag m. T 1 Clear. Int. Flag(); } //T 1 Interrupt Di Jasio - Programming 32 -bit Microcontrollers in C

main() { // 2. 1 init I/Os DDPCONbits. JTAGEN = 0; // disable JTAG

main() { // 2. 1 init I/Os DDPCONbits. JTAGEN = 0; // disable JTAG port TRISA = 0 xff 00; // set PORTA LSB as output // 2. 2 configure Timer 1 module PR 1 = 25000 -1; // set the period register T 1 CON = 0 x 8030; // enabled, prescaler 1: 256, internal clock // 2. 3 init interrupts m. T 1 Set. Int. Priority( 1); m. T 1 Clear. Int. Flag(); INTEnable. System. Single. Vectored. Int(); m. T 1 Int. Enable( 1); // 2. 4. main loop while( 1) { // your main code here PORTA = Sec; } // main loop } // main Di Jasio - Programming 32 -bit Microcontrollers in C

Clock. c Simulation Di Jasio - Programming 32 -bit Microcontrollers in C

Clock. c Simulation Di Jasio - Programming 32 -bit Microcontrollers in C

Using the Secondary Oscillator // 1. Timer 1 interrupt service routine void __ISR( 0,

Using the Secondary Oscillator // 1. Timer 1 interrupt service routine void __ISR( 0, ipl 1) T 1 Interrupt( void) { // 1. 1 Sec++; // increment the seconds counter if ( Sec > 59) // 60 seconds make a minute { Sec = 0; Min++; // increment the minute counter if ( Min > 59)// 59 minutes in an hour Min = 0; } // minutes // 1. 2 clear the interrupt flag m. T 1 Clear. Int. Flag(); } //T 1 Interrupt q q q Change the period register to generate one interrupt every 32, 768 cycles PR 1 = 32768 -1; // set the period register Change the Timer 1 configuration word (the prescaler is not required anymore) T 1 CON = 0 x 8002; // enabled, prescaler 1: 1, use secondary oscillator NOTE: Unfortunately you will not be able to immediately test this new configuration with the simulator since the secondary oscillator input is not fully supported by MPLAB SIM. Di Jasio - Programming 32 -bit Microcontrollers in C

Using the RTCC module main() { // 2. 1 init I/Os DDPCONbits. JTAGEN =

Using the RTCC module main() { // 2. 1 init I/Os DDPCONbits. JTAGEN = 0; // disable JTAG port TRISA = 0 xff 00; // set PORTA LSB as output // 2. 2 configure RTCC module Rtcc. Init(); // inits the RTCC // set present time rtcc. Time tm; tm. sec=0 x 15; tm. min=0 x 30; tm. hour=01; // set present date rtcc. Date dt; dt. wday=0; dt. mday=0 x 15; dt. mon=0 x 10; dt. year=0 x 07; Rtcc. Set. Time. Date(tm. l, dt. l); // set desired alarm to Feb 29 th dt. wday=0; dt. mday=0 x 29; dt. mon=0 x 2; Rtcc. Set. Alarm. Time. Date(tm. l, dt. l); // 2. 2 init interrupts, m. RTCCSet. Int. Priority( 1); m. RTCCClear. Int. Flag(); INTEnable. System. Single. Vectored. Int(); m. RTCCInt. Enable( 1); // 2. 3. main loop while( 1) { // your main code here //. . . } // main loop } // main Di Jasio - Programming 32 -bit Microcontrollers in C

Using the RTCC module (Cont. ) // 1. RTCC interrupt service routine void __ISR(

Using the RTCC module (Cont. ) // 1. RTCC interrupt service routine void __ISR( 0, ipl 1) RTCCInterrupt( void) { // 1. 1 your code here, will be executed only once a year // or once every 365 x 24 x 60 x 16, 000 MCU cycles // that is once every 504, 576, 000, 000 MCU cycles // 1. 2 clear the interrupt flag m. RTCCClear. Int. Flag(); } // RTCCInterrupt Di Jasio - Programming 32 -bit Microcontrollers in C