From 77490396d4d5cbe929fe0c2fa9242dc937e3b293 Mon Sep 17 00:00:00 2001 From: sherlock Date: Wed, 29 Oct 2025 12:33:15 +0530 Subject: [PATCH] proj --- ES/Project/code.c | 429 +++++++++++++++++++++++----------------------- 1 file changed, 210 insertions(+), 219 deletions(-) diff --git a/ES/Project/code.c b/ES/Project/code.c index 957d967..f702888 100644 --- a/ES/Project/code.c +++ b/ES/Project/code.c @@ -1,66 +1,54 @@ #include -/* PORT MAPPING: - * KEYPAD MATRIX (4x4): - * Columns: P0.15 - P0.18 (Output, pulled high, scan low) - * Rows: P0.19 - P0.22 (Input, pulled high internally) - * - * Layout: 0 1 2 3 - * 4 5 6 7 - * 8 9 A B - * C D E F - * - * 7-SEGMENT DISPLAY: - * Segments: P0.4 - P0.11 (a-g + dp) - * Digit Enable: P1.23 (active high) - * - * LCD (16x2): - * Data: P0.23 - P0.26 (D4-D7, 4-bit mode) - * RS: P0.27 - * EN: P0.28 - * - * MODE BUTTON: - * P2.12 (Input, internal pull-up) - * - * 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 (=) - * - * P2.12 Button: Mode selection (cycles: DEC->BIN->OCT->HEX) +/* =================================================== + * SMART CALCULATOR - LPC176x + * Supports DEC, BIN, OCT, and HEX input modes + *, with 4x4 keypad, LCD, 7-segment, and mode button. + * --------------------------------------------------- + * Decimal mode: Operators B-F active directly + * Hexadecimal mode: Operators B-F active with MODE button + * =================================================== */ -// 7-Segment patterns +// 7-Segment patterns for 0-F 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 +/* ---------------- Pin Mapping ---------------- + * Keypad (4x4): + * Columns: P0.15–P0.18 (Output) + * Rows: P0.19–P0.22 (Input, pull-up) + * + * 7-Segment: + * Segments: P0.4–P0.11 + * Digit Enable: P1.23 + * + * LCD: + * Data: P0.23–P0.26 + * RS: P0.27, EN: P0.28 + * + * Mode Button: P2.12 + * ------------------------------------------------ + */ + +/* ===== MACROS ===== */ #define COL_BASE 15 #define ROW_BASE 19 #define COL_MASK (0x0F << COL_BASE) #define ROW_MASK (0x0F << ROW_BASE) -// 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 #define MODE_OCT 8 #define MODE_DEC 10 @@ -71,29 +59,57 @@ const unsigned char seven_seg[16] = { #define OP_SUB 2 #define OP_MUL 3 -// 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 lcd_flag = 0; +/* ===== Global Variables (Predeclared) ===== */ +int input_num; +int stored_num; +int result; +unsigned int current_base; +unsigned int operation; +unsigned char lcd_flag; +unsigned char result_displayed; -void delay(volatile unsigned int d){ - while(d--) __NOP(); +unsigned int key, last_key, stable; +unsigned int button_state, last_button_state, button_stable; +unsigned int shift_active; + +/* ===== Function Declarations ===== */ +void delay(volatile unsigned int d); +void lcd_delay(unsigned long r); +void lcd_write_nibble(unsigned char nibble, unsigned char is_data); +void lcd_cmd(unsigned char cmd); +void lcd_data(unsigned char data); +void lcd_init(void); +void lcd_print_str(const char *str); +void lcd_print_num(int num, unsigned int base); +void display_mode(void); +void display_input(void); +void display_operator_feedback(const char *op_symbol); +unsigned int scan_keypad(void); +unsigned int scan_mode_button(void); +unsigned int is_valid_digit(unsigned int key); +void change_mode(void); +void operate(unsigned int op); +void perform_operation(void); + +/* ===== Utility & LCD Handling ===== */ +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; iFIOPIN = (LPC_GPIO0->FIOPIN & ~LCD_DATA_MASK) | temp; + LPC_GPIO0->FIOPIN = + (LPC_GPIO0->FIOPIN & ~LCD_DATA_MASK) | temp; - if(is_data) + if (is_data) LPC_GPIO0->FIOSET = LCD_RS; else LPC_GPIO0->FIOCLR = LCD_RS; @@ -104,17 +120,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); @@ -132,101 +148,92 @@ 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++); } } -// MODIFIED to handle negative numbers -void lcd_print_num(int num, unsigned int base){ +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){ + 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; - else - buffer[i++] = 'A' + (digit - 10); - unum = unum / base; + buffer[i++] = (digit < 10) ? ('0' + digit) + : ('A' + (digit - 10)); + unum /= base; } } else { - // Decimal mode: handle negative with minus sign - if(num < 0){ + 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; + 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) + if (current_base == MODE_BIN) lcd_print_str("BIN "); - else if(current_base == MODE_OCT) + else if (current_base == MODE_OCT) lcd_print_str("OCT "); - else if(current_base == MODE_DEC) + else if (current_base == MODE_DEC) lcd_print_str("DEC "); else lcd_print_str("HEX "); } -void display_input(void){ +void display_input(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 +void display_operator_feedback(const char *op_symbol) { 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 + delay(100000); + display_input(); } -unsigned int scan_keypad(void){ +/* ====== Keypad & Button Handling ===== */ +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<FIOSET = COL_MASK; - return col*4 + row; + return col * 4 + row; } } } @@ -235,186 +242,170 @@ 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 scan_mode_button(void) { 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; - // In HEX mode, all keys 0-15 are valid digits! - return 1; +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; + return 1; // HEX accepts all 0-F } -void change_mode(void){ - if(current_base == MODE_DEC) +void change_mode(void) { + if (current_base == MODE_DEC) current_base = MODE_BIN; - else if(current_base == MODE_BIN) + else if (current_base == MODE_BIN) current_base = MODE_OCT; - else if(current_base == MODE_OCT) + else if (current_base == MODE_OCT) current_base = MODE_HEX; else current_base = MODE_DEC; + display_mode(); } -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; +/* ===== Operator Handling ===== */ +void operate(unsigned int op) { + stored_num = input_num; + operation = op; + input_num = 0; + result_displayed = 0; +} + +void perform_operation(void) { + if (operation == OP_ADD) + result = stored_num + input_num; + else if (operation == OP_SUB) + result = stored_num - input_num; + else if (operation == OP_MUL) + result = stored_num * input_num; + 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; +} + +/* ===== MAIN ===== */ +int main(void) { + // Init globals + input_num = stored_num = result = 0; + current_base = MODE_DEC; + operation = OP_NONE; + lcd_flag = 0; + result_displayed = 0; + key = last_key = 0xFF; + stable = button_stable = 0; + button_state = last_button_state = 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; LPC_GPIO0->FIODIR &= ~ROW_MASK; 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); LPC_GPIO1->FIODIR |= DIGIT_EN; - // LCD LPC_GPIO0->FIODIR |= LCD_DATA_MASK | LCD_RS | LCD_EN; lcd_init(); display_mode(); display_input(); - for(;;){ - // Check if shift key (Key 0) is being held - shift_active = is_key0_pressed(); - - // Scan for other keys + for (;;) { 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; } - // Debounce mode button - if(button_state == last_button_state){ - if(button_stable < 5) button_stable++; + if (button_state == last_button_state) { + if (button_stable < 5) + button_stable++; } else { last_button_state = button_state; button_stable = 0; } - // Handle mode button press - if(button_stable == 3 && button_state == 1){ + if (button_stable == 3 && button_state == 1) { change_mode(); - button_stable = 5; // Prevent multiple triggers + button_stable = 5; } - // 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) - - if(key == 11){ // Key 0 + B = Addition - stored_num = input_num; - operation = OP_ADD; - input_num = 0; + if (stable == 3 && key != 0xFF) { + /* ========================= + * DECIMAL MODE: Operator works directly + * HEX MODE: Operator works with MODE_BUTTON held + * ========================= */ + if ((current_base == MODE_DEC) || + (current_base == MODE_HEX && button_state == 1)) { + if (key == 11) { // B = + + operate(OP_ADD); display_operator_feedback("+"); - } - else if(key == 12){ // Key 0 + C = Clear - input_num = 0; - stored_num = 0; + } else if (key == 12) { // C = CLR + input_num = stored_num = result = 0; operation = OP_NONE; - result = 0; + result_displayed = 0; display_operator_feedback("CLR"); - } - else if(key == 13){ // Key 0 + D = Subtraction - stored_num = input_num; - operation = OP_SUB; - input_num = 0; + } else if (key == 13) { // D = - + operate(OP_SUB); display_operator_feedback("-"); - } - else if(key == 14){ // Key 0 + E = Multiplication - stored_num = input_num; - operation = OP_MUL; - input_num = 0; + } else if (key == 14) { // E = * + operate(OP_MUL); 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) - result = stored_num - input_num; - else if(operation == OP_MUL) - result = stored_num * input_num; - 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; - } - } - else { - // NORMAL MODE - Digit input - if(is_valid_digit(key)){ + } else if (key == 15) { // F = = + perform_operation(); + } else if (is_valid_digit(key)) { + result_displayed = 0; + input_num = input_num * current_base + key; + display_input(); + } + } else { + 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(); } } - stable = 5; // Prevent repeated triggers + stable = 5; } - // 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 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; // '1' + else if (operation != OP_NONE) + seg_pattern = 0x5B | 0x80; // '2' + DP + else if (result_displayed == 1) + seg_pattern = 0x4F | 0x80; // '3' + DP + else + seg_pattern = 0x3F; // '0' LPC_GPIO0->FIOCLR = (0xFF << SEG_SHIFT); LPC_GPIO0->FIOSET = (seg_pattern << SEG_SHIFT);