Allows enter 2 float numbers from keypad and shows result on LCD
# - enter
* - decimal point
A - add
B - subtract
C - mutiply
D - devide
Toolkit:AVR Development System
Location:/bipom/devtools/WinAVR/minimaxavrc/Examples/calculator
int main() { float num1, num2, result; char num1txt[MAX_NUM_LEN]; char num2txt[MAX_NUM_LEN]; int p = 0; char IsPointAdded = 0; int State = STATE_IDLE; // delay 500 milliseconds after power up _delay_ms(500); // Initialize the serial port 0 to 19200 baud uart1Init(19200); uart1Printf( "\rCALCULATOR SAMPLE" ); // Initialize the keypad InitKeypad(); // Initialize the LCD lcdInit(); pwmInit(); // Adjust LCD contrast lcdControlCursor(CURSOR_OFF); // Write a simple message to the LCD lcdClearDisplay(); lcdSetTopLine(); lcdPrintf("CALCULATOR SAMPLE"); _delay_ms(2000); num1 = num2 = result = 0; while(1) { char ch = ScanKeypad(); if(ch == 0 && State != STATE_IDLE) continue; switch(State) { default: case STATE_IDLE: lcdClearDisplay(); lcdSetTopLine(); lcdPrintf("ENTER NUM1: "); memset(num1txt, 0, MAX_NUM_LEN); memset(num2txt, 0, MAX_NUM_LEN); IsPointAdded = 0; p = 0; State = STATE_ENTER_NUM1; break; case STATE_ENTER_NUM1: if(ch >= '0' && ch <= '9') { num1txt[p++] = ch; lcdWrData(ch); } if(ch == '*' && !IsPointAdded) { num1txt[p++] = '.'; IsPointAdded = 1; lcdWrData('.'); } if(ch == '#' || p >= (MAX_NUM_LEN-1)) { State = STATE_ENTER_NUM2; p = 0; } if(State == STATE_ENTER_NUM2) { lcdSetBottomLine(); lcdPrintf("ENTER NUM2: "); } break; case STATE_ENTER_NUM2: if(ch >= '0' && ch <= '9') { num2txt[p++] = ch; lcdWrData(ch); } if(ch == '*' && !IsPointAdded) { num2txt[p++] = '.'; IsPointAdded = 1; lcdWrData('.'); } if(ch == '#' || p >= (MAX_NUM_LEN-1)) State = STATE_ENTER_OPERATION; if(State == STATE_ENTER_OPERATION) { lcdClearDisplay(); lcdSetTopLine(); lcdPrintf("ENTER OPERATION: "); } break; case STATE_ENTER_OPERATION: if(ch == 'A' || ch == 'B' || ch == 'C' || ch == 'D') { num1 = atof(num1txt); num2 = atof(num2txt); uart1Printf("\rNUM1: %f", num1); uart1Printf("\rNUM2: %f", num2); uart1Printf("\rOPERATION: %c", ch); if(ch == 'A') { lcdWrData('+'); result = num1 + num2; uart1Printf("\rRESULT (+): %f", result); } if(ch == 'B') { lcdWrData('-'); result = num1 - num2; uart1Printf("\rRESULT (-): %f", result); } if(ch == 'C') { lcdWrData('*'); result = num1 * num2; uart1Printf("\rRESULT (*): %f", result); } if(ch == 'D') { lcdWrData(''); result = num1 num2; uart1Printf("\rRESULT (/): %f", result); } State = STATE_SHOW_RESULT; } if(State == STATE_SHOW_RESULT) { lcdSetBottomLine(); lcdPrintf("RESULT: %f", result); } break; case STATE_SHOW_RESULT: if(ch == '#') State = STATE_IDLE; break; } } } // ****************************************************************** void InitKeypad() { // Set lower 4 bits of Port K as output, these are the rows of the keypad DDRK |= _BV(PK0); DDRK |= _BV(PK1); DDRK |= _BV(PK2); DDRK |= _BV(PK3); // Set upper 4 bits of Port H as input, these are the columns of the keypad PORTH |= _BV(PH4); // Enable internal pull-up resistor for PH4 so it will not float PORTH |= _BV(PH5); // Enable internal pull-up resistor for PH5 so it will not float PORTH |= _BV(PH6); // Enable internal pull-up resistor for PH6 so it will not float PORTH |= _BV(PH7); // Enable internal pull-up resistor for PH7 so it will not float DDRH &= ~_BV(PH4); // Set PH4 as input DDRH &= ~_BV(PH5); // Set PH5 as input DDRH &= ~_BV(PH6); // Set PH6 as input DDRH &= ~_BV(PH7); // Set PH7 as input } // ****************************************************************** char ScanKeypad() { int row; int col; unsigned char RowTable[] = { 0xFE, 0xFD, 0xFB, 0xF7 }; static char KeyTable[] = { '1', '2', '3', 'D', '4', '5', '6', 'A', '7', '8', '9', 'B', '*', '0', '#', 'D' }; col = 0; for( row=0; row<MAX_ROWS; row++ ) { PORTK = RowTable[row]; if( !(PINH & 0x80) ) col = 4; if( !(PINH & 0x40) ) col = 3; if( !(PINH & 0x20) ) col = 2; if( !(PINH & 0x10) ) col = 1; if( col != 0 ) { _delay_ms(500); return KeyTable[col-1 + row*MAX_COLS]; } } return 0; }