Êíèãà: Advanced PIC Microcontroller Projects in C
Project Program
Project Program
The program listing for the program KEYPAD.C is given in Figure 6.48. Each key is given a numeric value as follows:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
The program consists of a function called getkeypad, which reads the pressed keys, and the main program. Variable MyKey stores the key value (0 to 15) pressed, variables Op1 and Op2 store respectively the first and second numbers entered by the user. All these variables are cleared to zero at the beginning of the program. A while loop is then formed to read the first number and store in variable Op1. This loop exits when the user presses the ENTER key. Similarly, the second number is read from the keyboard in a second while loop. Then the operation to be performed is read and stored in variable MyKey, and a switch statement is used to perform the required operation and store the result in variable Calc. The result is converted into a string array using function LongToStr. The leading blank characters are then removed as in Project 8. The program displays the result on the LCD, waits for five seconds, and then clears the screen and is ready for the next calculation. This process is repeated forever.
/**************************************************************
CALCULATOR WITH KEYPAD AND LCD
==============================
In this project a 4 x 4 keypad is connected to PORTB of a PIC18F452
microcontroller. Also an LCD is connected to PORTC. The project is a simple
calculator which can perform integer arithmetic.
The keys are organized as follows:
0 1 2 3
4 5 6 7
8 9 10 11
12 13 14 15
The keys are labeled as follows:
1 2 3 4
5 6 7 8
9 0 Enter
+ ? * /
Author: Dogan Ibrahim
Date: July 2007
File: KEYPAD.C
**************************************************************/
#define MASK 0xF0
#define Enter 11
#define Plus 12
#define Minus 13
#define Multiply 14
#define Divide 15
//
// This function gets a key from the keypad
//
unsigned char getkeypad() {
unsigned char i, Key = 0;
PORTB = 0x01; // Start with column 1
while((PORTB MASK) == 0) // While no key pressed
{
PORTB = (PORTB << 1); // next column
Key++; // column number
if (Key == 4) {
PORTB = 0x01; // Back to column 1
Key = 0;
}
}
Delay_Ms(20); // Switch debounce
for(i = 0x10; i !=0; i <<= 1) // Find the key pressed
{
if ((PORTB i) != 0) break;
Key = Key + 4;
}
PORTB=0x0F;
while ((PORTB MASK) != 0); // Wait until key released
Delay_Ms(20); // Switch debounce
return (Key); // Return key number
}
//
// Start of MAIN program
//
void main() {
unsigned char MyKey, i,j,lcd[5],op[12];
unsigned long Calc, Op1, Op2;
TRISC = 0; // PORTC are outputs (LCD)
TRISB = 0xF0; // RB4-RB7 are inputs
//
// Configure LCD
//
Lcd_Init(&PORTC); // LCD is connected to PORTC
Lcd_Cmd(LCD_CLEAR);
Lcd_Out(1,1, "CALCULATOR"); // Display CALCULATOR
Delay_ms(2000); // Wait 2 seconds
Lcd_Cmd(LCD_CLEAR); // Clear display
//
// Program loop
//
for(;;) // Endless loop
{
MyKey = 0;
Op1 = 0;
Op2 = 0;
Lcd_Out(1,1, "No1: "); // Display No1:
while(1) // Get first no
{
MyKey = getkeypad();
if (MyKey == Enter) break; // If ENTER pressed
MyKey++;
if (MyKey == 10) MyKey = 0; // If 0 key pressed
Lcd_Chr_Cp(MyKey + '0');
Op1 = 10*Op1 + MyKey; // First number in Op1
}
Lcd_Out(2,1, "No2: "); // Display No2:
while(1) // Get second no
{
MyKey = getkeypad();
if (MyKey == Enter) break; // If ENTER pressed
MyKey++;
if (MyKey == 10) MyKey = 0; // If 0 key pressed
Lcd_Chr_Cp(MyKey + '0');
Op2 = 10*Op2 + MyKey; // Second number in Op2
}
Lcd_Cmd(LCD_CLEAR); // Clear LCD
Lcd_Out(1,1, "Op: "); // Display Op:
MyKey = getkeypad(); // Get operation
Lcd_Cmd(LCD_CLEAR);
Lcd_Out(1,1, "Res="); // Display Res=
switch(MyKey) // Perform the operation
{
case Plus:
Calc = Op1 + Op2; // If ADD
break;
case Minus:
Calc = Op1 - Op2; // If Subtract
break;
case Multiply:
Calc = Op1 * Op2; // If Multiply
break;
case Divide:
Calc = Op1 / Op2; // If Divide
break;
}
LongToStr(Calc, op); // Convert to string in op
//
// Remove leading blanks
//
j=0;
for(i=0;i<=11;i++) {
if (op[i] != ' ') // If a blank
{
lcd[j]=op[i];
j++;
}
}
Lcd_Out_Cp(lcd); // Display result
Delay_ms(5000); // Wait 5 seconds
Lcd_Cmd(LCD_CLEAR);
}
}
Figure 6.48: Program listing
Function getkeypad receives a key from the keypad. We start by sending a 1 to column 1, and then we check all the rows. When a key is pressed, a logic 1 is detected in the corresponding row and the program jumps out of the while loop. Then a for loop is used to find the actual key pressed by the user as a number from 0 to 15.
It is important to realize that when a key is pressed or released, we get what is known as contact noise, where the key output pulses up and down momentarily, producing a number of logic 0 and 1 pulses at the output. Switch contact noise is usually removed either in hardware or by programming in a process called contact debouncing. In software the simplest way to remove the contact noise is to wait for about 20ms after a switch key is pressed or switch key is released. In Figure 6.46, contact debouncing is accomplished in function getkeypad.