C51 COMPILER V6.14 KEYPAD 10/22/2002 12:23:34 PAGE 1 C51 COMPILER V6.14, COMPILATION OF MODULE KEYPAD OBJECT MODULE PLACED IN keypad.OBJ COMPILER INVOKED BY: C:\CYGNAL\IDEFILES\C51\BIN\C51.EXE keypad.c DB OE stmt level source 1 //----------------------------------------------------------------------------- 2 // Keypad.c 3 //----------------------------------------------------------------------------- 4 // Author: Baylor Electromechanical Systems 5 // 6 // Operates on an external 18.432MHz oscillator. 7 // 8 // Target: Cygnal Educational Development Board / C8051F020 9 // Tool chain: KEIL C51 6.03 / KEIL EVAL C51 10 // 11 // This program interfaces Cygnal's C8051F02x with a 4x4, 16 pad keypad. The 12 // program was designed for the Grayhill 96BB2-056-F. With keypad DIP switch 13 // (SW5) toggled to the on positions, pins 1-8 on the keypad are 14 // connected to P2.0 - P2.7. 15 // 16 17 //----------------------------------------------------------------------------- 18 // Includes 19 //----------------------------------------------------------------------------- 20 21 #include // SFR declarations 22 #include 23 24 //----------------------------------------------------------------------------- 25 // Global CONSTANTS 26 //----------------------------------------------------------------------------- 27 28 #define BAUDRATE 9600 // Baud rate of UART in bps 29 #define SYSCLK 18432000 // SYSCLK frequency in Hz 30 31 32 // Lookup table for converting keycode to ASCII 33 unsigned int keytab[4][4] ={{'1','2','3','A'}, 34 {'4','5','6','B'}, 35 {'7','8','9','C'}, 36 {'*','0','#','D'}}; 37 38 39 //----------------------------------------------------------------------------- 40 // Function PROTOTYPES 41 //----------------------------------------------------------------------------- 42 43 void SYSCLK_Init (void); 44 void PORT_Init (void); 45 void UART0_Init (void); 46 int button_dn(void); 47 unsigned int scankey (void); 48 void delay_ms(int ms); 49 50 //----------------------------------------------------------------------------- 51 // MAIN Routine 52 //----------------------------------------------------------------------------- 53 54 void main (void) 55 { C51 COMPILER V6.14 KEYPAD 10/22/2002 12:23:34 PAGE 2 56 1 unsigned int rd1; 57 1 58 1 WDTCN = 0xde; // disable watchdog timer 59 1 WDTCN = 0xad; 60 1 61 1 SYSCLK_Init (); // initialize oscillator 62 1 PORT_Init (); // initialize crossbar and GPIO 63 1 UART0_Init (); // initialize UART0 64 1 65 1 EA = 1; // Enable global interrupts 66 1 67 1 while (1) 68 1 { 69 2 if(button_dn()) // check for key press 70 2 { 71 3 delay_ms(5); // delay for debouncing 72 3 rd1 = scankey(); // read keypad 73 3 if(rd1 != 0) 74 3 { 75 4 putchar (254); // LCD command 76 4 putchar (0x01); // clear LCD 77 4 printf (" You pressed:\r " ); 78 4 putchar (rd1); 79 4 } 80 3 while(button_dn()); // check for key release 81 3 } 82 2 delay_ms(5); 83 2 } 84 1 } 85 86 //----------------------------------------------------------------------------- 87 // Initialization Subroutines 88 //----------------------------------------------------------------------------- 89 90 //----------------------------------------------------------------------------- 91 // SYSCLK_Init 92 //----------------------------------------------------------------------------- 93 // 94 // This routine initializes the system clock to use an 18.432MHz crystal 95 // as its clock source. 96 // 97 void SYSCLK_Init (void) 98 { 99 1 int i; // delay counter 100 1 101 1 OSCXCN = 0x67; // start external oscillator with 102 1 // 18.432MHz crystal 103 1 104 1 for (i=0; i < 256; i++) ; // XTLVLD blanking interval (>1ms) 105 1 106 1 while (!(OSCXCN & 0x80)) ; // Wait for crystal osc. to settle 107 1 108 1 OSCICN = 0x88; // select external oscillator as SYSCLK 109 1 // source and enable missing clock 110 1 // detector 111 1 } 112 113 //----------------------------------------------------------------------------- 114 // PORT_Init 115 //----------------------------------------------------------------------------- 116 // 117 // Configure the Crossbar and GPIO ports C51 COMPILER V6.14 KEYPAD 10/22/2002 12:23:34 PAGE 3 118 // 119 void PORT_Init (void) 120 { 121 1 XBR0 = 0x04; // Enable UART0 122 1 XBR1 = 0x00; 123 1 XBR2 = 0x40; // Enable crossbar and weak pull-ups 124 1 P0MDOUT |= 0x01; // enable TX0 as a push-pull output 125 1 126 1 // PORT 3 CONFIGURATION 127 1 P2MDOUT = 0xF0; // P2 u.n. push pull, lower-nibble input 128 1 P2 = 0x0F; // upper nibble hi-imp, allowing input read 129 1 130 1 } 131 132 //----------------------------------------------------------------------------- 133 // UART0_Init 134 //----------------------------------------------------------------------------- 135 // 136 // Configure the UART0 using Timer1, for and 8-N-1. 137 // 138 void UART0_Init (void) 139 { 140 1 SCON0 = 0x50; // SCON0: mode 1, 8-bit UART, enable RX 141 1 TMOD = 0x20; // TMOD: timer 1, mode 2, 8-bit reload 142 1 TH1 = -(SYSCLK/BAUDRATE/16); // set Timer1 reload value for baudrate 143 1 TR1 = 1; // start Timer1 144 1 CKCON |= 0x10; // Timer1 uses SYSCLK as time base 145 1 PCON |= 0x80; // SMOD00 = 1 146 1 TI0 = 1; // Indicate TX0 ready 147 1 } 148 149 //----------------------------------------------------------------------------- 150 // Local Functions 151 //----------------------------------------------------------------------------- 152 153 //----------------------------------------------------------------------------- 154 // button_dn 155 //----------------------------------------------------------------------------- 156 // 157 // Function: test keypad for the presence of a key press. 158 // Return: 1 if keypress; 0 otherwise. 159 160 int button_dn() 161 { 162 1 int tmp; 163 1 tmp = (P2 & 0x0F)^0x0F; // read P2.3->P2.0 and XOR output 164 1 165 1 if(tmp) // if button is depressed, tmp != 0 166 1 return 1; 167 1 else 168 1 return 0; 169 1 } 170 171 //----------------------------------------------------------------------------- 172 // scankey 173 //----------------------------------------------------------------------------- 174 // 175 // Function: read keypad and convert keypress into equiv. ASCII code. 176 // Return: ASCII equivalent of pressed key's label. 177 178 unsigned int scankey(void) 179 { C51 COMPILER V6.14 KEYPAD 10/22/2002 12:23:34 PAGE 4 180 1 int row = 0; 181 1 int col = 0; 182 1 int k,j; 183 1 184 1 P2 = 0x0F; // set data register 185 1 P2MDOUT = 0xF0; // drive P2.3->P2.0 as output 186 1 delay_ms(10); // let drive signals settle 187 1 188 1 row = (P2 & 0x0F)^0x0F; // read P2.3->P2.0 and XOR output 189 1 190 1 delay_ms(2); 191 1 192 1 if(row == 0) 193 1 return 0; // no closure detected 194 1 195 1 P2 = 0xF0; // set data register 196 1 P2MDOUT = 0x0F; // drive P2.7->P2.4 as output 197 1 delay_ms(2); // let drive signals settle 198 1 199 1 col = (P2 & 0xF0)^0xF0; // P2.7->P2.4 and XOR output 200 1 col = col >> 4; // move hi nibble to lo nibble 201 1 202 1 if(col == 0) 203 1 return 0; // no closure detected 204 1 205 1 P2 = 0x0F; // set data register 206 1 P2MDOUT = 0xF0; // drive P2.3->P2.0 as output 207 1 delay_ms(2); // let drive signals settle 208 1 209 1 switch(row) // convert 1-of-4 to binary 210 1 { 211 2 case 1: j = 0; break; 212 2 case 2: j = 1; break; 213 2 case 4: j = 2; break; 214 2 case 8: j = 3; break; 215 2 default: return 0; 216 2 } 217 1 218 1 switch(col) // convert 1-of-4 to binary 219 1 { 220 2 case 1: k = 0; break; 221 2 case 2: k = 1; break; 222 2 case 4: k = 2; break; 223 2 case 8: k = 3; break; 224 2 default: return 0; 225 2 } 226 1 227 1 return keytab[j][k]; // return the ASCII value at that row and column 228 1 } 229 230 //----------------------------------------------------------------------------- 231 // delay_ms 232 //----------------------------------------------------------------------------- 233 // 234 // an approximate x ms delay. 235 236 void delay_ms(int ms) 237 { 238 1 int y; 239 1 int z; 240 1 for (y=1; y<=250; y++) for (z=1; z<= ms; z++); 241 1 } C51 COMPILER V6.14 KEYPAD 10/22/2002 12:23:34 PAGE 5 MODULE INFORMATION: STATIC OVERLAYABLE CODE SIZE = 446 ---- CONSTANT SIZE = 18 ---- XDATA SIZE = ---- ---- PDATA SIZE = ---- ---- DATA SIZE = 32 10 IDATA SIZE = ---- ---- BIT SIZE = ---- ---- END OF MODULE INFORMATION. C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)