UNIT 8 Keypad Interface Contact Closure Counter Exceptions (Interrupts and Reset)
Keypad Figure 5.5 Use as Outputs Use as Inputs
Interface Keypad to Port H Port H[3:0] – Output –Full Drive Port H[7:4] – Input –Pulls are Optional since Pull-ups on Keypad –Disable Interrupts
Port H Definitions /* 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
Port H Initialization /* Direction */ DDRH = 0x0F; /* Full Drive */ RDRH = 0x00; /* Pulls Not Required since pull resistors on keypad */ PERH = 0x00; /* Disable Interrupts */ PIEH = 0x00; /* Unselect Rows in Keypad */ PTH = 0x0F;
Procedure to Read Keypad /* if key is pressed, return ‘0’, ‘1’, …, ‘F’ else ‘z’ */ unsigned char keypress(void) {unsigned char mask[4]=0x0E,0x0D,0x0B,0x07; //1110, 1101, 1011, 0111 int i,j; char key; for(key=‘z’,i=0;i<4;i++) {PTH = mask[i]; // assert a 0 on a row in keypad for(j=0;j<4;j++) {if((PTH>>4) == mask[j]) //check each column for a returned 0 {if (((i<<2)+j)<10) key = ‘0’+(i<<2)+j; //value = 4*row# + column# else key=‘A’+(i 9 } PTH = 0x0F; // unselect row return (key); }
Algorithm Implemented in C i=0 PTH[3:0] = 0xE // Row 0 j=0 PTH[7:4] = 0xE key=‘0’ j=1 PTH[7:4] = 0xD key=‘1’ j=2 PTH[7:4] = 0xB key=‘2’ j=3 PTH[7:4] = 0x7 key=‘3’ i=1 PK[3:0] = 0xD // Row 1 j=0 PTH[7:4] = 0xE key=‘4’ j=1 PTH[7:4] = 0xD key=‘5’ j=2 PTH[7:4] = 0xB key=‘6’ j=3 PTH[7:4] = 0x7 key=‘7’ i=2 PTH[3:0] = 0xB // Row 2 j=0 PTH[7:4] = 0xE key=‘8’ j=1 PTH[7:4] = 0xD key=‘9’ j=2 PTH[7:4] = 0xB key=‘A’ j=3 PTH[7:4] = 0x7 key=‘B’ i=3 PTH[3:0] = 0x7 //Row 3 j=0 PTH[7:4] = 0xE key=‘C’ j=1 PTH[7:4] = 0xD key=‘D’ j=2 PTH[7:4] = 0xB key=‘E’ j=3 PTH[7:4] = 0x7 key=‘F’ keycode = 4*i+j; If(keycode<10) key = ‘0’ + keycode; else key = ‘A’ + keycode – 10;
Another Procedure Read Keypad /* if key is pressed, return ‘0’, ‘1’, …, ‘F’ else ‘z’ */ unsigned char keypress(void) {unsigned char mask[16]=0xEE,0xDE,0xBE,0x7E, 0XED,0xDD,0xBD,0x7D, 0xEB,0xDB,0xBB,0x7B, 0xE7,0xD7,0xB7,0x77; int i; char key; for(key=‘z’,i=0;i<16;i++) {PTH = mask[i]; // assert row in keypad if(PTH == mask[i]) {if (i<10) key = ‘0’+i; else key=‘A’+i-10;} } PTH = 0x0F; // unselect row return (key); } //SEE NEXT PAGE
EE key = 0 DE key = 1 BE key = 2 7E key = 3 sent out EB key = 8 DB key = 9 BB key = A 7B key = B E key = C D key = D B key = E key = F ED key = 4 DD key = 5 BD key = 6 7D key = 7 Row 0 Row 3 Row 2 Row 1
Keypads - Section Example Uses Port B and not Port H Uses switch() statements rather than for loops.
Another I/O Example: Contact Closure Counter Connect 8 Push-Button to the Pins of Port H Push-Button is normally open => “1” is input Press Momentary Push-Button => “0” is input Count Number of Times a Push-Button is Pressed Count “1” to “0” Transitions on each Pin
/* port definitions */ int main() {int count[8] = 0,0,0,0,0,0,0,0; int sum=0, int i; unsigned char oldsw, newsw, change; /* init port h */ oldsw = PTH; newsw = PTH; while(sum<1000) { while(oldsw == newsw) newsw = PTH; change = (oldsw^newsw) & oldsw; oldsw = newsw; for(i=0, i<8, i++) if(((change>>i)&0x01)!=0) {count[i]++; sum++} } return(0); } //count only 1->0 transitions
Details Old = 0x23 = 0b New = 0x32 = 0b Old ^ New = 0b (Old ^ New) & Old = 0b Increment count[0]
Exceptions, Interrupts, and Resets
“Exception”: A break in normal program flow, normally initiated by some hardware condition.
Two types of exceptions: Resets Interrupts
Exceptions can be initiated by either Internal or external events When exceptions occurs, the microcontroller: - Uses an address from a Vector Table to get to a Service Routine. - Saves the processor state on the stack (for Interrupts)
Events that Can Cause a Reset: –External Reset (via active low reset pin) –Power-on Reset –Computer Operating Properly (COP) Reset –Clock Monitor Reset Disabled by Debugger in Lab
Computer Operating Properly (COP Reset) Also called Watch Dog Timer User-configurable countdown timer If timer reaches 0, a system reset is triggered User must repeatedly reset using a reset timer sequence Disabled in Lab
Clock Monitor Reset Clock Monitor Reset when system clock frequency drops below a prescribed value or stops
Two Classes of Interrupts: –Nonmaskable Interrupts (cannot be disabled by software) –Maskable Interrupts Masked – Disabled (By software) Unmasked – Enabled (By software)
Nonmaskable Interrupts X bit – Condition Code Register (CCR) –X=“1” – Disables all Interrupts –X=“0” – Enable all Interrupts During Normal System Reset, X=“1” After System Initialization, X=“0” by software X can not be set to “1” by software
Types of Nonmaskable Interrupts Nonmaskable Interrupt Request (/XIRQ) –/XIRQ is External Pin –/XIRQ Active Low Generates Request Unimplemented Instruction Trap Software Interrupt Instruction (SWI)
Enabling of Maskable Interrupts I bit in Condition Code Register (CCR) –I = “0” Enable Maskable Interrupts –I = “1” Disable Maskable Interrupts C Program Instructions –ENABLE(); – Sets I=“0” –DISABLE(); – Sets I=“1”
Maskable Interrupt Sources IRQ Pin Real Time Clock Interrupt Enhanced Capture Timer Channels Pulse Accumulators SPI and SCI Serial I/O A/D System Port J, H, and P Pins Network Serial I/O Other
Interrupt Initialization (Fig. 4.21)
Interrupt Vector Table 2 Bytes Allocated for each Interrupt Source Contents of Vector –Starting Address of Interrupt Service Routine Vectored System –Each Source has a dedicated Vector “Boost” priority of one maskable interrupt to highest priority (HPRIO Register)
Interrupt Handling – Fig. 4.21
Interrupt Handling Save State of CPU on Stack by Hardware Disable Masked Interrupt System Determine Interrupt Source by Hardware Transfer Control to Interrupt Handling Software by Hardware Service Interrupt Request by Interrupt Service Routine (ISR) – User written Restore State of CPU from Stack using RTI instruction
Why Interrupts? Most operating systems support multiprocessing – Several application running at same time. Desirable to eliminate “busy waits” in all software since busy waits can monopolize CPU resources.
Recall: Parallel Printer Interface (Not using interrupts) Printer /Strobe Busy Data[7:0] Busy Write Data Strobe Yes No
Print a Character on Printer void printc(unsigned char c) { /* Wait while Printer is Busy */ while((PTJ&0x02)!=0); // BUSY WAIT /* Printer not Busy, Output Data */ PTH = c; /* Generate Strobe * PTJ = PTJ & 0xFE; // Bit 0 Low PTJ = PTJ | 0x01; // Bit 0 High }
Busy Data /Strobe ACK Printer Waveforms PC Parallel Printer Port Definition
Parallel Printer Interface Printer /Strobe Busy Data[7:0] ACK Busy Write Data Strobe Yes No
Interfacing a Parallel Printer Using Interrupts Present data to printer Send Strobe signal to printer When printer is no long busy, it sends out an ACK pulse to request an interrupt (The interrupt indicates the printer is ready to receive a new character to print.)