Toolkit:SDCC 8051 Development System
Location:/bipom/devtools/SDCC/examples/lcd/calculator
#define MAX_ROWS 4 #define MAX_COLS 4 #define STATE_IDLE 0 #define STATE_ENTER_NUM1 1 #define STATE_ENTER_NUM2 2 #define STATE_ENTER_OPERATION 3 #define STATE_SHOW_RESULT 4 #define MAX_NUM_LEN 10 // ****************************************************************** char ScanKeypad() { char row; char col; unsigned char RowTable[] = { 0xFE, 0xFD, 0xFB, 0xF7 }; char KeyTable[] = { '1', '2', '3', 'A', '4', '5', '6', 'B', '7', '8', '9', 'C', '*', '0', '#', 'D' }; col = 0; for( row=0; row<MAX_ROWS; row++ ) { P2 = RowTable[row]; if( !(P2 & 0x80) ) col = 4; if( !(P2 & 0x40) ) col = 3; if( !(P2 & 0x20) ) col = 2; if( !(P2 & 0x10) ) col = 1; if( col != 0 ) { delay(500); return KeyTable[col-1 + row*MAX_COLS]; } } return 0; } // ****************************************************************** void main() { float num1, num2, result; char num1txt[MAX_NUM_LEN]; char num2txt[MAX_NUM_LEN]; char p = 0; char IsPointAdded = 0; int State = STATE_IDLE; // Initialize the serial port serinit(CBR_19200); puts( "\rCALCULATOR SAMPLE" ); // Initialize the LCD LCD_Init(); // Write a simple message to the LCD LCD_Clear(); LCD_SetTopLine(); LCD_Write("CALCULATOR SAMPLE"); delay(2000); num1 = num2 = result = 0; while(1) { char ch = ScanKeypad(); if(ch == 0 && State != STATE_IDLE) continue; switch(State) { default: case STATE_IDLE: LCD_Clear(); LCD_SetTopLine(); LCD_Write("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; LCD_WriteData(ch); } if(ch == '*' && !IsPointAdded) { num1txt[p++] = '.'; IsPointAdded = 1; LCD_WriteData('.'); } if(ch == '#' || p >= (MAX_NUM_LEN-1)) { State = STATE_ENTER_NUM2; p = 0; } if(State == STATE_ENTER_NUM2) { LCD_SetBottomLine(); LCD_Write("ENTER NUM2: "); } break; case STATE_ENTER_NUM2: if(ch >= '0' && ch <= '9') { num2txt[p++] = ch; LCD_WriteData(ch); } if(ch == '*' && !IsPointAdded) { num2txt[p++] = '.'; IsPointAdded = 1; LCD_WriteData('.'); } if(ch == '#' || p >= (MAX_NUM_LEN-1)) State = STATE_ENTER_OPERATION; if(State == STATE_ENTER_OPERATION) { LCD_Clear(); LCD_SetTopLine(); LCD_Write("ENTER OPERATION: "); } break; case STATE_ENTER_OPERATION: if(ch == 'A' || ch == 'B' || ch == 'C' || ch == 'D') { num1 = atof(num1txt); num2 = atof(num2txt); printf("\rNUM1: %f", num1); printf("\rNUM2: %f", num2); printf("\rOPERATION: %c", ch); if(ch == 'A') { LCD_WriteData('+'); result = num1 + num2; printf("\rRESULT (+): %f", result); } if(ch == 'B') { LCD_WriteData('-'); result = num1 - num2; printf("\rRESULT (-): %f", result); } if(ch == 'C') { LCD_WriteData('*'); result = num1 * num2; printf("\rRESULT (*): %f", result); } if(ch == 'D') { LCD_WriteData(''); result = num1 num2; printf("\rRESULT (/): %f", result); } State = STATE_SHOW_RESULT; } if(State == STATE_SHOW_RESULT) { LCD_SetBottomLine(); LCD_Printf("RESULT: %f", result); } break; case STATE_SHOW_RESULT: if(ch == '#') State = STATE_IDLE; break; } } }