ECE 371 – Unit 9 Interrupts (continued)
Example Set up Two Interrupt Request Inputs: –Port H[0] Set Interrupt Flag on “0” to “1” transition (rising edge) Port H[1] Set Interrupt Flag on “1” to “0” transition (trailing edge)
Example (cont) Response to Interrupts: Toggle H[4] on each H[0] Interrupt Toggle H[5] on each H[1] Interrupt
#include ece371.h /* Port H Port Definitions */ #define PTH _P( 0x260) #define PTIH _P( 0x261) #define DDRH _P( 0x262) #define RDRH _P( 0x263) #define PERH _P( 0x264) #define PPSH _P( 0x265) #define PIEH _P( 0x266) #define PIFH _P( 0x267) Example – Port H Interrupt
Interrupt Service Routine Setting up (declaring) “myisr” as in Interrupt Service Routine: void myisr() __attribute__ ((interrupt)); //should be at the //beginning of source file /* 2 underscores before and after attribute */ /* Do not use #pragma, which is used in the text To establish in Interrupt Service Routine*/
#include void myisr() __attribute__ ((interrupt)); int main() {/* stack is initialized by c */ /* initialize interrupt vector for Port H */ SETVECT(0xFFCC,my_isr); /* init Data Direction Bits for Port H Bits 0 and 1 are Input Bits 4 and 5 are Output Other Bits assigned to other applications /* DDRH = DDRH & 0xFC; // Bit 0 and 1 are Input DDRH = DDRH | 0x30; // Bit 4 and 5 are output Example – Main Program
/* Set Bit 4 and 5 to full drive outputs */ RDRH = RDRH & 0xCF; // /* Enable Bit 0 and 1 Pull Device on Input */ PERH = PERH | 0x03; // Enable Bit 0 and 1 Pull Device PPSH = (PPSH & 0xFC) | 0x01; // Bit 0 Rise, Bit 1 Fall /* Clear Pending Port H Bit 0 and 1 Interrupts */ PIFH = 0x03; /* Enable Bit 0 and 1 to Interrupt */ PIEH = PIEH | 0x03; // Enable Interrupts /* Enable Maskable Interrupt System */ ENABLE(); /* do main program processing */ while(TRUE); // loop }
void my_isr(void) { if ((PIFH&0x2)!=0) {//Bit 1 was source of interrupt PIFH = 0x02; // Clear Interrupt // Do interrupt specific action, complement Bit 5 PTH = PTH ^ 0x20; } if ((PIFH&0x01)!=0) {//Bit 0 was source of interrupt PIFH = 0x01; // Clear Interrupt // Do interrupt specific action, complement Bit 4 PTH = PTH ^ 0x10; } Example Interrupt Handler
Use Each Bit of Port H as an Interrupt Request Input Count the Running Total of Interrupt Request that Occur on Each of the 8 Request Inputs Another Example: 8-Switch Counter Implemented Using Interrupts
#include void myisr() __attribute__ ((interrupt)); /* Port H definitions go here */ int count[8]=0,0,0,0,0,0,0,0; // global int main() {/* stack is initialized by c */ /* initialize interrupt vector for Port H */ SETVECT(0xFFCC,my_isr); /* Init Data Direction Bits for Port H All bits are input /* DDRH = 0x00; Another Example: (cont)
/* Enable Pull Devices on Port H all bits */ PERH = 0xFF; /* Interrupt on “1” to “0” Transitions all bits PPSH = 0x00; /* Clear Pending Port H Interrupts all bits */ PIFH = 0xFF; /* Enable all Port H bits to Interrupt */ PIEH = 0xFF; // Enable Interrupts /* Enable Maskable Interrupt System */ ENABLE(); /* do main program processing */ while(TRUE); // loop }
void my_isr(void) { int i; for(i=0;i<8;i++) {if ((PIFH & (1<<i))!=0) {//Bit i was source of interrupt PIFH = (1<<i); // Clear Interrupt // Do interrupt specific action count[i]++; } Method 1 for Implementing Interrupt Service Routine
void my_isr(void) { int i; unsigned char change; change = PIFH; // change bitsw PIFH = change; // Clear interrupt flag for(i=0, i<8, i++) if(((change>>i)&0x01)!=0) {count[i]++;} } Method 2 for Implementing Interrupt Service Routine
Still Another Example: Interfacing a Keypad (Fig. 5.5) Using Interrupts Use Port H
Keypad with Interrupts Port H[3:0] –Output –Full Drive –Set Bits to “0” (all at once) Port H[7:4] –Input –Interrupt on “1” to “0” (Key Pressed)
Cflag!=0 ? c=cin; cflag=0; Function “ci” to Read Keypad Scan Keypad cin=keypad character cflag=1; Interrupt Main –ISR Communication Shared Variables ==0 !=0 Intr. Service Routine
Passing Parameters Between Main Program and Interrupt Service Routine unsigned char cin, cflag=0; /*global variables declared outside Interrupt Service Routine and all functions/* //function to read keyboard: unsigned char ci(void) { while(cflag == 0); cflag=0; return cin;}
Main Program – Receiving Character from ISR Int main() { unsigned char c; PTH=0; // select all rows ENABLE(); // enable all interrupts ---- c=ci(); // input character from keypad //function ci defined on previous slide ---- }
Tasks for Keypad ISR On a Port H Interrupt: –Clear Interrupt Flag Register with Write –Scan Keypad for Pressed Key –cin=key; cflag=1: –Set Port H outputs to “0
void kbisr() //define ISR {unsigned char mask[4]=0x0E,0x0D,0x0B,0x07;int i,j; //1110, 1101, 1011, 0111 PIFH = PIFH; // clear interrupt request for(i=0;i<4;i++) {PTH = mask[i]; // assert row in keypad for(j=0;j<4;j++) {if((PTH>>4) == mask[j]) {if (((i<<2)+j)<10) {cin = ‘0’+(i<<2)+j;cflag=1;} else cin=‘A’+(i<<2)+j -10;cflag=1;} } PTH = 0x00; // select all rows } Keypad ISR void kbisr() __attribute__ ((interrupt)); //Establish kbisr as ISR