360 likes | 524 Views
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.
E N D
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<<2)+j -10;} //different offset for values>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 ProcedureRead 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
sent out Row 0 EE 1110 1110-------key = 0 DE 1101 1110-------key = 1 BE 1011 1110-------key = 2 7E 0111 1110-------key = 3 Row 1 ED 1110 1101-------key = 4 DD 1101 1101-------key = 5 BD 1011 1101-------key = 6 7D 0111 1101-------key = 7 Row 2 EB 1110 1011-------key = 8 DB 1101 1011-------key = 9 BB 1011 1011-------key = A 7B 0111 1011-------key = B Row 3 E7 1110 0111-------key = C D7 1101 0111-------key = D B7 1011 0111-------key = E 77 0111 0111-------key = F
Keypads - Section 5.2.3 • 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 = 0b00100011 • New = 0x32 = 0b00110010 • Old ^ New = 0b00010001 • (Old ^ New) & Old = 0b00000001 • Increment count[0]
“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 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 • 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) Busy Printer /Strobe Busy Data[7:0] Yes No Write Data Strobe
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 }
Printer Waveforms Busy Data /Strobe ACK PC Parallel Printer Port Definition www.fapo.com/ieee1284.htm
Parallel Printer Interface Busy Printer /Strobe Busy Data[7:0] ACK Yes No Write Data Strobe
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.)