Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

KPD.c

Go to the documentation of this file.
00001 // This file has been prepared for Doxygen automatic documentation generation.
00023 #include "KPD.h"
00024 
00025 unsigned char KPD_KeyPressed;
00026 unsigned char KPD_LastKey;
00027 unsigned char KPD_ScanRow;
00028 unsigned char KPD_KeyDown;
00029 
00030 __flash static unsigned char KPD_Array[4][4] = { {'1','4','7','A'},{'2','5','8','0'},{'3','6','9','B'},{'F','E','D','C'}};
00031 
00032 void  KPD_Init(void)
00033 {
00034   TCCR0B = 0;                         // stop timer/counter
00035 
00036   KPD_KeyPressed = 0;
00037   KPD_LastKey = 0;
00038   KPD_ScanRow = 0;
00039   KPD_KeyDown = 0;
00040 
00041   DDRA |= (1 << PINA0);               // set pin A0 as output (X1)
00042   DDRA |= (1 << PINA1);               // set pin A1 as output (X2)
00043   DDRA |= (1 << PINA2);               // set pin A2 as output (X3)
00044   DDRA |= (1 << PINA3);               // set pin A3 as output (X4)
00045   PORTA |= (1 << PINA0);              // set pin A0 high
00046   PORTA |= (1 << PINA1);              // set pin A1 high
00047   PORTA |= (1 << PINA2);              // set pin A2 high
00048   PORTA |= (1 << PINA3);              // set pin A3 high
00049 
00050   DDRB &= ~(1 << PINB0);              // set pin B0 to input (Y1)
00051   DDRB &= ~(1 << PINB1);              // set pin B1 to input (Y2)
00052   DDRB &= ~(1 << PINB2);              // set pin B2 to input (Y3)
00053   PORTB |= (1 << PINB0);              // enable pull-up
00054   PORTB |= (1 << PINB1);              // enable pull-up
00055   PORTB |= (1 << PINB2);              // enable pull-up
00056 
00057 #ifdef DEBUGWIRE
00058 #else
00059   DDRB &= ~(1 << PINB3);              // set pin B3 to input (Y4)
00060   PORTB |= (1 << PINB3);              // enable pull-up
00061 #endif
00062 
00063   PCMSK1 |= (1 << PCINT8);            // enable pin change int 8
00064   PCMSK1 |= (1 << PCINT9);            // enable pin change int 9
00065   PCMSK1 |= (1 << PCINT10);           // enable pin change int 10
00066 
00067 #ifdef DEBUGWIRE
00068 #else
00069   PCMSK1 |= (1 << PCINT11);           // enable pin change int 11
00070 #endif
00071 
00072   GIMSK |= (1 << PCIE1);              // enable pin change ints
00073   GIFR |= (1 << PCIF1);               // clear flag
00074 
00075   TCNT0 = 0;                          // clear counter
00076   TIMSK0 = (1 << TOIE0);              // enable overflow interrupt
00077   TCCR0A = 0;         // normal mode and normal port operation on all t/c pins
00078   TCCR0B = (1<<CS01)|(1<<CS00); // normal mode, TOP = 0xFF, TOVF on MAX, CLK/8
00079                                       // => overflow each 2 ms @ 1 MHz
00080   asm("sei");                         // enable all interrupts
00081 }
00082 
00083 unsigned char KPD_GetKey(void)
00084 {
00085   if (KPD_KeyPressed)
00086   {
00087     KPD_KeyPressed = 0;
00088     return (KPD_LastKey);
00089   }
00090   else
00091     return (0);
00092 }
00093 
00094 // executed when SREG:I = 1 and GIMSK:PCIE1 = 1. GIFR:PCIF1 cleared upon entry.
00095 #pragma vector = PCINT1_vect
00096 __interrupt void PCINT1_ISR(void)
00097 {
00098   unsigned int delay=2857;             // 7 cycles per count, 20 ms @ 1 MHz
00099   unsigned char column;
00100 
00101   GIMSK &= ~(1 << PCIE1);             // disable pin change int for de-bounce
00102   do
00103   {}
00104   while(delay--);                     // de-bounce: allow inputs to settle
00105   GIMSK |= (1 << PCIE1);              // enable pin change ints
00106 
00107 #ifdef DEBUGWIRE
00108   column = (~PINB) & 0x07;
00109 #else
00110   column = (~PINB) & 0x0F;
00111 #endif
00112 
00113   switch (column)
00114   {
00115     case  0x00: KPD_KeyDown = 0;
00116                 break;
00117     case  0x01: KPD_LastKey = KPD_Array[KPD_ScanRow][0];
00118                 if (!KPD_KeyDown)
00119                   KPD_KeyPressed = 1;               // must release key before press recorded
00120                 KPD_KeyDown = 1;
00121                 break;
00122     case  0x02: KPD_LastKey = KPD_Array[KPD_ScanRow][1];
00123                 if (!KPD_KeyDown)
00124                   KPD_KeyPressed = 1;               // must release key before press recorded
00125                 KPD_KeyDown = 1;
00126                 break;
00127     case  0x04: KPD_LastKey = KPD_Array[KPD_ScanRow][2];
00128                 if (!KPD_KeyDown)
00129                   KPD_KeyPressed = 1;               // must release key before press recorded
00130                 KPD_KeyDown = 1;
00131                 break;
00132     case  0x08: KPD_LastKey = KPD_Array[KPD_ScanRow][3];
00133                 if (!KPD_KeyDown)
00134                   KPD_KeyPressed = 1;               // must release key before press recorded
00135                 KPD_KeyDown = 1;
00136                 break;
00137     default:    KPD_LastKey = 0;
00138                 KPD_KeyPressed = 0;
00139   }
00140 }
00141 
00142 #pragma vector = TIM0_OVF_vect
00143 __interrupt void TC0_ISR(void)
00144 {
00145   if (!KPD_KeyDown)
00146   {
00147     PORTA |= (1 << KPD_ScanRow);        // set pin high
00148     if (++KPD_ScanRow > 3)
00149       KPD_ScanRow = 0;
00150     PORTA &= ~(1 << KPD_ScanRow);       // set pin low
00151   }
00152 }

Generated on Mon Oct 10 15:25:09 2005 for AVR245: Code Lock with 4x4 Keypad and I2C(TM) LCD by  doxygen 1.4.4