diff --git a/ES/Project/code.c b/ES/Project/code.c index 957d967..c6ada29 100644 --- a/ES/Project/code.c +++ b/ES/Project/code.c @@ -25,14 +25,30 @@ * KEY FUNCTIONS: * 0-9, A-F: Digit input (valid based on current base) * - * OPERATOR MODE (Hold Key 0 + another key): - * Key 0 + B: Addition (+) - * Key 0 + C: Clear (C) - * Key 0 + D: Subtraction (-) - * Key 0 + E: Multiplication (*) - * Key 0 + F: Equals (=) + * OPERATOR KEYS: + * DEC/BIN/OCT modes (direct press): + * Key A: Addition (+) + * Key B: Subtraction (-) + * Key C: Multiplication (*) + * Key D: Equals (=) + * Key E: Clear (C) * - * P2.12 Button: Mode selection (cycles: DEC->BIN->OCT->HEX) + * HEX mode (hold MODE + key): + * MODE + A: Addition (+) + * MODE + B: Subtraction (-) + * MODE + C: Multiplication (*) + * MODE + D: Equals (=) + * MODE + E: Clear (C) + * + * P2.12 Button: + * Short press: Mode selection (cycles: DEC->BIN->OCT->HEX) + * Hold + key (HEX mode only): Operator input + * + * 7-SEGMENT STATE DISPLAY: + * '1' - Input mode (entering numbers) + * '2' with DP - Operation pending (waiting for 2nd number) + * '3' with DP - Result ready (showing calculation result) + * '0' - Cleared/Reset state (fallback) */ // 7-Segment patterns @@ -71,13 +87,13 @@ const unsigned char seven_seg[16] = { #define OP_SUB 2 #define OP_MUL 3 -// Global variables - CHANGED to signed int +// Global variables int input_num = 0; int stored_num = 0; int result = 0; unsigned int current_base = MODE_DEC; unsigned int operation = OP_NONE; -unsigned char lcd_flag = 0; +unsigned char result_displayed = 0; void delay(volatile unsigned int d){ while(d--) __NOP(); @@ -138,12 +154,10 @@ void lcd_print_str(const char* str){ } } -// MODIFIED to handle negative numbers void lcd_print_num(int num, unsigned int base){ char buffer[17]; int i = 0; - // For non-decimal bases, show as unsigned (two's complement representation) if(base != MODE_DEC){ unsigned int unum = (unsigned int)num; if(unum == 0){ @@ -159,7 +173,6 @@ void lcd_print_num(int num, unsigned int base){ unum = unum / base; } } else { - // Decimal mode: handle negative with minus sign if(num < 0){ lcd_data('-'); num = -num; @@ -194,21 +207,32 @@ void display_mode(void){ lcd_print_str("HEX "); } -void display_input(void){ +void display_status(void){ lcd_cmd(0xC0); - lcd_print_str("Inp: "); - lcd_print_num(input_num, current_base); - lcd_print_str(" "); -} -void display_operator_feedback(const char* op_symbol){ - // Brief feedback on line 2 - lcd_cmd(0xC0); - lcd_print_str("Op: "); - lcd_print_str(op_symbol); - lcd_print_str(" "); - delay(100000); // Brief delay to show feedback - display_input(); // Return to showing input + if(operation != OP_NONE){ + // Show operation pending + lcd_print_str("Op:"); + if(operation == OP_ADD) lcd_data('+'); + else if(operation == OP_SUB) lcd_data('-'); + else if(operation == OP_MUL) lcd_data('*'); + + lcd_print_str(" Val:"); + lcd_print_num(stored_num, current_base); + lcd_print_str(" "); + } + else if(result_displayed){ + // Show result + lcd_print_str("Res: "); + lcd_print_num(result, current_base); + lcd_print_str(" "); + } + else { + // Show current input + lcd_print_str("Inp: "); + lcd_print_num(input_num, current_base); + lcd_print_str(" "); + } } unsigned int scan_keypad(void){ @@ -235,24 +259,7 @@ unsigned int scan_keypad(void){ return 0xFF; } -// Check if Key 0 is currently pressed (shift key) -unsigned int is_key0_pressed(void){ - unsigned int col = 0; // Key 0 is at column 0, row 0 - unsigned int row_bits; - - LPC_GPIO0->FIOSET = COL_MASK; - delay(50); - LPC_GPIO0->FIOCLR = (1 << (COL_BASE + col)); - delay(200); - row_bits = (LPC_GPIO0->FIOPIN & ROW_MASK) >> ROW_BASE; - LPC_GPIO0->FIOSET = COL_MASK; - - // Check if row 0 is pressed (Key 0) - return ((row_bits & 0x01) == 0) ? 1 : 0; -} - -unsigned int scan_mode_button(void){ - // Return 1 if button is pressed (active low), 0 if not pressed +unsigned int is_mode_button_pressed(void){ return ((LPC_GPIO2->FIOPIN & MODE_BUTTON) == 0) ? 1 : 0; } @@ -261,7 +268,6 @@ unsigned int is_valid_digit(unsigned int key){ if(current_base == MODE_BIN && key >= 2) return 0; if(current_base == MODE_OCT && key >= 8) return 0; if(current_base == MODE_DEC && key >= 10) return 0; - // In HEX mode, all keys 0-15 are valid digits! return 1; } @@ -274,21 +280,29 @@ void change_mode(void){ current_base = MODE_HEX; else current_base = MODE_DEC; + + input_num = 0; + stored_num = 0; + operation = OP_NONE; + result = 0; + result_displayed = 0; + display_mode(); + display_status(); } int main(void){ unsigned int key, last_key = 0xFF; unsigned int stable = 0; - unsigned int button_state, last_button_state = 0; - unsigned int button_stable = 0; - unsigned int shift_active = 0; + unsigned int mode_held = 0; + unsigned int mode_press_counter = 0; + unsigned int key_pressed_with_mode = 0; // Configure pins LPC_PINCON->PINSEL0 = 0; LPC_PINCON->PINSEL1 = 0; LPC_PINCON->PINSEL3 = 0; - LPC_PINCON->PINSEL4 = 0; // Configure P2.12 + LPC_PINCON->PINSEL4 = 0; // Keypad: Columns output, Rows input LPC_GPIO0->FIODIR |= COL_MASK; @@ -296,7 +310,7 @@ int main(void){ LPC_GPIO0->FIOSET = COL_MASK; // Mode button: Input with internal pull-up - LPC_GPIO2->FIODIR &= ~MODE_BUTTON; // Set as input + LPC_GPIO2->FIODIR &= ~MODE_BUTTON; // 7-Segment LPC_GPIO0->FIODIR |= (0xFF << SEG_SHIFT); @@ -307,15 +321,14 @@ int main(void){ lcd_init(); display_mode(); - display_input(); + display_status(); for(;;){ - // Check if shift key (Key 0) is being held - shift_active = is_key0_pressed(); + // Check if MODE button is currently pressed + unsigned int mode_current = is_mode_button_pressed(); - // Scan for other keys + // Scan keypad key = scan_keypad(); - button_state = scan_mode_button(); // Debounce keypad if(key == last_key){ @@ -325,54 +338,63 @@ int main(void){ stable = 0; } - // Debounce mode button - if(button_state == last_button_state){ - if(button_stable < 5) button_stable++; + // Track MODE button hold + if(mode_current){ + mode_press_counter++; + mode_held = 1; } else { - last_button_state = button_state; - button_stable = 0; - } - - // Handle mode button press - if(button_stable == 3 && button_state == 1){ - change_mode(); - button_stable = 5; // Prevent multiple triggers + // MODE button released + if(mode_held && !key_pressed_with_mode && mode_press_counter < 50){ + // Short press without key combo = change mode + change_mode(); + } + mode_held = 0; + mode_press_counter = 0; + key_pressed_with_mode = 0; } // Handle keypad input if(stable == 3 && key != 0xFF){ // Key pressed and stable - // If Key 0 is also pressed, we're in operator mode - if(shift_active && key != 0){ - // OPERATOR MODE (Key 0 + another key) + // Check if this is an operator key (A-E) + int is_operator_key = (key >= 10 && key <= 14); - if(key == 11){ // Key 0 + B = Addition + // In HEX mode, operators require MODE button + // In other modes, operator keys work directly + int operator_mode = 0; + if(current_base == MODE_HEX){ + operator_mode = (mode_held && is_operator_key); + } else { + operator_mode = is_operator_key; + } + + if(operator_mode){ + // OPERATOR INPUT + key_pressed_with_mode = 1; + + if(key == 10){ // A = Addition stored_num = input_num; operation = OP_ADD; input_num = 0; - display_operator_feedback("+"); + result_displayed = 0; + display_status(); } - else if(key == 12){ // Key 0 + C = Clear - input_num = 0; - stored_num = 0; - operation = OP_NONE; - result = 0; - display_operator_feedback("CLR"); - } - else if(key == 13){ // Key 0 + D = Subtraction + else if(key == 11){ // B = Subtraction stored_num = input_num; operation = OP_SUB; input_num = 0; - display_operator_feedback("-"); + result_displayed = 0; + display_status(); } - else if(key == 14){ // Key 0 + E = Multiplication + else if(key == 12){ // C = Multiplication stored_num = input_num; operation = OP_MUL; input_num = 0; - display_operator_feedback("*"); + result_displayed = 0; + display_status(); } - else if(key == 15){ // Key 0 + F = Equals + else if(key == 13){ // D = Equals if(operation == OP_ADD) result = stored_num + input_num; else if(operation == OP_SUB) @@ -382,40 +404,51 @@ int main(void){ else result = input_num; - lcd_cmd(0xC0); - lcd_print_str("Res: "); - lcd_print_num(result, current_base); - lcd_print_str(" "); - input_num = result; operation = OP_NONE; + result_displayed = 1; + display_status(); + } + else if(key == 14){ // E = Clear + input_num = 0; + stored_num = 0; + operation = OP_NONE; + result = 0; + result_displayed = 0; + display_status(); } } else { - // NORMAL MODE - Digit input + // DIGIT INPUT MODE if(is_valid_digit(key)){ + result_displayed = 0; input_num = input_num * current_base + key; - // Handle overflow with wrap-around for signed int if(input_num > 32767) input_num = input_num % 32768; if(input_num < -32768) input_num = -32768; - display_input(); + display_status(); } } stable = 5; // Prevent repeated triggers } - // Display result on 7-segment (last digit only) - // MODIFIED: Use decimal point to indicate negative numbers - int display_value = (input_num < 0) ? -input_num : input_num; - unsigned int display_digit = display_value % 16; - unsigned int seg_pattern = seven_seg[display_digit]; + // ===== STATE MACHINE DISPLAY ON 7-SEGMENT ===== + unsigned int seg_pattern; - // Turn on decimal point if number is negative - if(input_num < 0){ - seg_pattern |= 0x80; // Bit 7 is the decimal point + if(operation == OP_NONE && result_displayed == 0) { + seg_pattern = 0x06; // Display '1' + } + else if(operation != OP_NONE) { + seg_pattern = 0x5B | 0x80; // Display '2' with DP + } + else if(result_displayed == 1) { + seg_pattern = 0x4F | 0x80; // Display '3' with DP + } + else { + seg_pattern = 0x3F; // Display '0' } + // Update the 7-segment display LPC_GPIO0->FIOCLR = (0xFF << SEG_SHIFT); LPC_GPIO0->FIOSET = (seg_pattern << SEG_SHIFT); LPC_GPIO1->FIOSET = DIGIT_EN;