From 92e301f4e2d9908a2f77a16714e5d1eeaecd14d1 Mon Sep 17 00:00:00 2001 From: sherlock Date: Wed, 29 Oct 2025 12:29:43 +0530 Subject: [PATCH] proj --- ES/Project/code.c | 358 ++++++++++++++++++++-------------------------- 1 file changed, 156 insertions(+), 202 deletions(-) diff --git a/ES/Project/code.c b/ES/Project/code.c index 978b7f2..957d967 100644 --- a/ES/Project/code.c +++ b/ES/Project/code.c @@ -25,36 +25,20 @@ * KEY FUNCTIONS: * 0-9, A-F: Digit input (valid based on current base) * - * OPERATOR KEYS: - * DEC/BIN/OCT modes (direct press): - * Key A: Addition (+) - * Key B: Subtraction (-) - * Key C: Multiplication (*) - * Key D: Equals (=) - * Key E: Clear (C) + * 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 (=) * - * 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) + * P2.12 Button: Mode selection (cycles: DEC->BIN->OCT->HEX) */ // 7-Segment patterns const unsigned char seven_seg[16] = { - 0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, - 0x7F, 0x6F, 0x77, 0x7C, 0x39, 0x5E, 0x79, 0x71 + 0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, + 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71 }; // Keypad defines @@ -65,16 +49,16 @@ const unsigned char seven_seg[16] = { // 7-Segment defines #define SEG_SHIFT 4 -#define DIGIT_EN (1 << 23) +#define DIGIT_EN (1<<23) // LCD defines #define LCD_DATA_SHIFT 23 #define LCD_DATA_MASK (0x0F << LCD_DATA_SHIFT) -#define LCD_RS (1 << 27) -#define LCD_EN (1 << 28) +#define LCD_RS (1<<27) +#define LCD_EN (1<<28) // Mode button defines -#define MODE_BUTTON (1 << 12) +#define MODE_BUTTON (1<<12) // Calculator states #define MODE_BIN 2 @@ -87,35 +71,24 @@ const unsigned char seven_seg[16] = { #define OP_SUB 2 #define OP_MUL 3 -// Global variables +// Global variables - CHANGED to signed int int input_num = 0; int stored_num = 0; int result = 0; unsigned int current_base = MODE_DEC; unsigned int operation = OP_NONE; -unsigned char result_displayed = 0; -unsigned int key = 0xFF; -unsigned int last_key = 0xFF; -unsigned int stable = 0; -unsigned int mode_held = 0; -unsigned int mode_press_counter = 0; -unsigned int key_pressed_with_mode = 0; -unsigned int mode_current = 0; -int is_operator_key = 0; -int operator_mode = 0; -unsigned int seg_pattern = 0; +unsigned char lcd_flag = 0; -void delay(volatile unsigned int d) { - while(d--) - __NOP(); +void delay(volatile unsigned int d){ + while(d--) __NOP(); } -void lcd_delay(unsigned long r) { +void lcd_delay(unsigned long r){ unsigned long i; - for(i = 0; i < r; i++); + for(i=0; iFIOPIN = (LPC_GPIO0->FIOPIN & ~LCD_DATA_MASK) | temp; @@ -131,17 +104,17 @@ void lcd_write_nibble(unsigned char nibble, unsigned char is_data) { lcd_delay(500000); } -void lcd_cmd(unsigned char cmd) { +void lcd_cmd(unsigned char cmd){ lcd_write_nibble(cmd >> 4, 0); lcd_write_nibble(cmd, 0); } -void lcd_data(unsigned char data) { +void lcd_data(unsigned char data){ lcd_write_nibble(data >> 4, 1); lcd_write_nibble(data, 1); } -void lcd_init(void) { +void lcd_init(void){ lcd_delay(5000000); lcd_write_nibble(0x03, 0); lcd_delay(500000); @@ -159,23 +132,25 @@ void lcd_init(void) { lcd_cmd(0x06); } -void lcd_print_str(const char* str) { - while(*str) { +void lcd_print_str(const char* str){ + while(*str){ lcd_data(*str++); } } -void lcd_print_num(int num, unsigned int base) { +// MODIFIED to handle negative numbers +void lcd_print_num(int num, unsigned int base){ char buffer[17]; int i = 0; - if(base != MODE_DEC) { + // For non-decimal bases, show as unsigned (two's complement representation) + if(base != MODE_DEC){ unsigned int unum = (unsigned int)num; - if(unum == 0) { + if(unum == 0){ lcd_data('0'); return; } - while(unum > 0 && i < 16) { + while(unum > 0 && i < 16){ unsigned int digit = unum % base; if(digit < 10) buffer[i++] = '0' + digit; @@ -184,28 +159,29 @@ void lcd_print_num(int num, unsigned int base) { unum = unum / base; } } else { - if(num < 0) { + // Decimal mode: handle negative with minus sign + if(num < 0){ lcd_data('-'); num = -num; } - if(num == 0) { + if(num == 0){ lcd_data('0'); return; } - while(num > 0 && i < 16) { + while(num > 0 && i < 16){ buffer[i++] = '0' + (num % 10); num = num / 10; } } - while(i > 0) { + while(i > 0){ lcd_data(buffer[--i]); } } -void display_mode(void) { +void display_mode(void){ lcd_cmd(0x80); lcd_print_str("Mode: "); if(current_base == MODE_BIN) @@ -218,51 +194,39 @@ void display_mode(void) { lcd_print_str("HEX "); } -void display_status(void) { +void display_input(void){ lcd_cmd(0xC0); - - 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(" "); - } + lcd_print_str("Inp: "); + lcd_print_num(input_num, current_base); + lcd_print_str(" "); } -unsigned int scan_keypad(void) { +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 +} + +unsigned int scan_keypad(void){ unsigned int col, row; unsigned int row_bits; - for(col = 0; col < 4; col++) { + for(col=0; col<4; col++){ 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; - if(row_bits != 0x0F) { - for(row = 0; row < 4; row++) { - if((row_bits & (1 << row)) == 0) { + if(row_bits != 0x0F){ + for(row=0; row<4; row++){ + if((row_bits & (1<FIOSET = COL_MASK; - return col * 4 + row; + return col*4 + row; } } } @@ -271,23 +235,37 @@ unsigned int scan_keypad(void) { return 0xFF; } -unsigned int is_mode_button_pressed(void) { +// 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 return ((LPC_GPIO2->FIOPIN & MODE_BUTTON) == 0) ? 1 : 0; } -unsigned int is_valid_digit(unsigned int key) { - if(key >= 16) - return 0; - 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; +unsigned int is_valid_digit(unsigned int key){ + if(key >= 16) return 0; + 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; } -void change_mode(void) { +void change_mode(void){ if(current_base == MODE_DEC) current_base = MODE_BIN; else if(current_base == MODE_BIN) @@ -296,23 +274,21 @@ 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) { +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; + // Configure pins LPC_PINCON->PINSEL0 = 0; LPC_PINCON->PINSEL1 = 0; LPC_PINCON->PINSEL3 = 0; - LPC_PINCON->PINSEL4 = 0; + LPC_PINCON->PINSEL4 = 0; // Configure P2.12 // Keypad: Columns output, Rows input LPC_GPIO0->FIODIR |= COL_MASK; @@ -320,7 +296,7 @@ int main(void) { LPC_GPIO0->FIOSET = COL_MASK; // Mode button: Input with internal pull-up - LPC_GPIO2->FIODIR &= ~MODE_BUTTON; + LPC_GPIO2->FIODIR &= ~MODE_BUTTON; // Set as input // 7-Segment LPC_GPIO0->FIODIR |= (0xFF << SEG_SHIFT); @@ -331,79 +307,72 @@ int main(void) { lcd_init(); display_mode(); - display_status(); + display_input(); - for(;;) { - // Check if MODE button is currently pressed - mode_current = is_mode_button_pressed(); + for(;;){ + // Check if shift key (Key 0) is being held + shift_active = is_key0_pressed(); - // Scan keypad + // Scan for other keys key = scan_keypad(); + button_state = scan_mode_button(); // Debounce keypad - if(key == last_key) { - if(stable < 5) - stable++; + if(key == last_key){ + if(stable < 5) stable++; } else { last_key = key; stable = 0; } - // Track MODE button hold - if(mode_current) { - mode_press_counter++; - mode_held = 1; + // Debounce mode button + if(button_state == last_button_state){ + if(button_stable < 5) button_stable++; } else { - // 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; + 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 } // Handle keypad input - if(stable == 3 && key != 0xFF) { + if(stable == 3 && key != 0xFF){ // Key pressed and stable - // Check if this is an operator key (A-E) - is_operator_key = (key >= 10 && key <= 14); + // If Key 0 is also pressed, we're in operator mode + if(shift_active && key != 0){ + // OPERATOR MODE (Key 0 + another key) - // In HEX mode, operators require MODE button - // In other modes, operator keys work directly - 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 + if(key == 11){ // Key 0 + B = Addition stored_num = input_num; operation = OP_ADD; input_num = 0; - result_displayed = 0; - display_status(); - } else if(key == 11) { // B = Subtraction + display_operator_feedback("+"); + } + 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 stored_num = input_num; operation = OP_SUB; input_num = 0; - result_displayed = 0; - display_status(); - } else if(key == 12) { // C = Multiplication + display_operator_feedback("-"); + } + else if(key == 14){ // Key 0 + E = Multiplication stored_num = input_num; operation = OP_MUL; input_num = 0; - result_displayed = 0; - display_status(); - } else if(key == 13) { // D = Equals + display_operator_feedback("*"); + } + else if(key == 15){ // Key 0 + F = Equals if(operation == OP_ADD) result = stored_num + input_num; else if(operation == OP_SUB) @@ -413,59 +382,44 @@ 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(); - } - - // Reset debounce after operator is processed - stable = 0; - last_key = 0xFF; - delay(500000); // Delay to let user release the key - - } else { - // DIGIT INPUT MODE - if(is_valid_digit(key)) { - result_displayed = 0; - input_num = input_num * current_base + key; - if(input_num > 32767) - input_num = input_num % 32768; - if(input_num < -32768) - input_num = -32768; - display_status(); - - stable = 5; // Prevent repeated triggers } } + else { + // NORMAL MODE - Digit input + if(is_valid_digit(key)){ + 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(); + } + } + + stable = 5; // Prevent repeated triggers } - // ===== STATE MACHINE DISPLAY ON 7-SEGMENT ===== + // 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]; - 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' + // Turn on decimal point if number is negative + if(input_num < 0){ + seg_pattern |= 0x80; // Bit 7 is the decimal point } - // Update the 7-segment display LPC_GPIO0->FIOCLR = (0xFF << SEG_SHIFT); LPC_GPIO0->FIOSET = (seg_pattern << SEG_SHIFT); LPC_GPIO1->FIOSET = DIGIT_EN; delay(3000); } - - return 0; }