200 likes | 281 Views
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).
E N D
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
Example – Port H 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)
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*/
Example – Main Program #include <ece371.h> #include <ports_D256.h> 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
/* Set Bit 4 and 5 to full drive outputs */ RDRH = RDRH & 0xCF; //11001111 /* 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 }
Example Interrupt Handler 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; } }
Another Example: 8-Switch CounterImplemented Using Interrupts • 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: (cont) #include <ece371.h> #include <ports_D256.h> 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;
/* 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 }
Method 1 for Implementing Interrupt Service Routine 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 2 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]++;} }
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)
Main –ISR CommunicationShared Variables Intr. Service Routine Function “ci” to Read Keypad Interrupt ==0 Cflag!=0 ? Scan Keypad !=0 c=cin; cflag=0; cin=keypad character cflag=1;
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
Keypad ISR void kbisr() __attribute__ ((interrupt)); //Establish kbisr as ISR 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 }