proj
This commit is contained in:
		
							parent
							
								
									6693a1a831
								
							
						
					
					
						commit
						f710e88793
					
				
					 1 changed files with 169 additions and 178 deletions
				
			
		|  | @ -1,13 +1,15 @@ | ||||||
| #include <LPC17xx.h> | #include <LPC17xx.h> | ||||||
|  | #include <stdbool.h> | ||||||
| 
 | 
 | ||||||
| /* ===================================================
 | /* ===================================================
 | ||||||
|  * SMART CALCULATOR - LPC176x |  * SMART CALCULATOR - LPC1768 (Final v2) | ||||||
|  * Supports BIN, BASE4, OCT, DEC, and HEX |  * Supports BIN, BASE4, OCT, DEC, and HEX | ||||||
|  * with 4x4 keypad, LCD, and 7-seg status. |  * with 4x4 keypad, LCD, and 7-seg status display. | ||||||
|  * |  * | ||||||
|  * BIN/BASE4/OCT/DEC: operators B–F direct |  * Features: | ||||||
|  * HEX: operators B–F only when MODE button held |  *  - Base-aware arithmetic and I/O | ||||||
|  * Arithmetic is performed modulo the current base |  *  - HEX: double MODE button press within 2s = operator mode | ||||||
|  |  *  - Hardware 1ms timing via SysTick | ||||||
|  * =================================================== |  * =================================================== | ||||||
|  */ |  */ | ||||||
| 
 | 
 | ||||||
|  | @ -45,20 +47,27 @@ const unsigned char seven_seg[16] = { | ||||||
| #define OP_ADD 1 | #define OP_ADD 1 | ||||||
| #define OP_SUB 2 | #define OP_SUB 2 | ||||||
| #define OP_MUL 3 | #define OP_MUL 3 | ||||||
|  | #define OP_CLR 4 | ||||||
|  | #define OP_RES 5 | ||||||
| 
 | 
 | ||||||
| /* ===== Global Variables (predeclared) ===== */ | /* ===== Global Variables ===== */ | ||||||
| int input_num; |  | ||||||
| int stored_num; |  | ||||||
| int result; |  | ||||||
| unsigned int current_base; | unsigned int current_base; | ||||||
|  | unsigned int input_num; | ||||||
|  | unsigned int stored_num; | ||||||
|  | unsigned int result; | ||||||
| unsigned int operation; | unsigned int operation; | ||||||
| unsigned char lcd_flag; |  | ||||||
| unsigned char result_displayed; | unsigned char result_displayed; | ||||||
| 
 | 
 | ||||||
| unsigned int key, last_key, stable; | unsigned int key, last_key, stable; | ||||||
| unsigned int button_state, last_button_state, button_stable; | unsigned int button_state, last_button_state, button_stable; | ||||||
| 
 | 
 | ||||||
| /* ===== Function Prototypes ===== */ | unsigned char hex_operator_mode; | ||||||
|  | unsigned long last_mode_press_time; | ||||||
|  | 
 | ||||||
|  | /* Millisecond counter via SysTick */ | ||||||
|  | volatile unsigned long sys_millis = 0; | ||||||
|  | 
 | ||||||
|  | /* ===== Function Declarations ===== */ | ||||||
| void delay(volatile unsigned int d); | void delay(volatile unsigned int d); | ||||||
| void lcd_delay(unsigned long r); | void lcd_delay(unsigned long r); | ||||||
| void lcd_write_nibble(unsigned char nibble, unsigned char is_data); | void lcd_write_nibble(unsigned char nibble, unsigned char is_data); | ||||||
|  | @ -66,36 +75,47 @@ void lcd_cmd(unsigned char cmd); | ||||||
| void lcd_data(unsigned char data); | void lcd_data(unsigned char data); | ||||||
| void lcd_init(void); | void lcd_init(void); | ||||||
| void lcd_print_str(const char *str); | void lcd_print_str(const char *str); | ||||||
| void lcd_print_num(int num, unsigned int base); | void lcd_print_num(unsigned int num, unsigned int base); | ||||||
| void display_mode(void); | void display_mode(void); | ||||||
| void display_input(void); | void display_input(void); | ||||||
| void display_operator_feedback(const char *op_symbol); | void display_result(void); | ||||||
| unsigned int scan_keypad(void); | unsigned int scan_keypad(void); | ||||||
| unsigned int scan_mode_button(void); | unsigned int scan_mode_button(void); | ||||||
| unsigned int is_valid_digit(unsigned int key); | unsigned int is_valid_digit(unsigned int key); | ||||||
| void change_mode(void); | void change_mode(void); | ||||||
|  | void handle_mode_button(void); | ||||||
| void operate(unsigned int op); | void operate(unsigned int op); | ||||||
| void perform_operation(void); | void perform_operation(void); | ||||||
| unsigned char is_operator_active(unsigned int key, unsigned int mode_button); | unsigned char is_operator_active(unsigned int key); | ||||||
|  | unsigned int base_arith(unsigned int a, unsigned int b, | ||||||
|  |                         unsigned int op, unsigned int base); | ||||||
|  | unsigned long millis(void); | ||||||
| 
 | 
 | ||||||
| /* ====== Utility ====== */ | /* ===== Utility ===== */ | ||||||
| void delay(volatile unsigned int d) { | void delay(volatile unsigned int d) { | ||||||
|     while (d--) |     while (d--) __NOP(); | ||||||
|         __NOP(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void lcd_delay(unsigned long r) { | void lcd_delay(unsigned long r) { | ||||||
|     unsigned long i; |     volatile unsigned long i; | ||||||
|     for (i = 0; i < r; i++) |     for (i = 0; i < r; i++) | ||||||
|         ; |         ; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ===== LCD ==== */ | /* ===== SysTick Millisecond Tracker ===== */ | ||||||
|  | void SysTick_Handler(void) { | ||||||
|  |     sys_millis++; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | unsigned long millis(void) { | ||||||
|  |     return sys_millis; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* ===== LCD Control ===== */ | ||||||
| void lcd_write_nibble(unsigned char nibble, unsigned char is_data) { | void lcd_write_nibble(unsigned char nibble, unsigned char is_data) { | ||||||
|     unsigned long temp; |     unsigned long temp; | ||||||
|     temp = (nibble & 0x0F) << LCD_DATA_SHIFT; |     temp = (nibble & 0x0F) << LCD_DATA_SHIFT; | ||||||
|     LPC_GPIO0->FIOPIN = |     LPC_GPIO0->FIOPIN = (LPC_GPIO0->FIOPIN & ~LCD_DATA_MASK) | temp; | ||||||
|         (LPC_GPIO0->FIOPIN & ~LCD_DATA_MASK) | temp; |  | ||||||
| 
 | 
 | ||||||
|     if (is_data) |     if (is_data) | ||||||
|         LPC_GPIO0->FIOSET = LCD_RS; |         LPC_GPIO0->FIOSET = LCD_RS; | ||||||
|  | @ -105,7 +125,7 @@ void lcd_write_nibble(unsigned char nibble, unsigned char is_data) { | ||||||
|     LPC_GPIO0->FIOSET = LCD_EN; |     LPC_GPIO0->FIOSET = LCD_EN; | ||||||
|     lcd_delay(100); |     lcd_delay(100); | ||||||
|     LPC_GPIO0->FIOCLR = LCD_EN; |     LPC_GPIO0->FIOCLR = LCD_EN; | ||||||
|     lcd_delay(500000); |     lcd_delay(250000); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void lcd_cmd(unsigned char cmd) { | void lcd_cmd(unsigned char cmd) { | ||||||
|  | @ -141,90 +161,62 @@ void lcd_print_str(const char *str) { | ||||||
|         lcd_data(*str++); |         lcd_data(*str++); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ===== Print number in base ===== */ | void lcd_print_num(unsigned int num, unsigned int base) { | ||||||
| void lcd_print_num(int num, unsigned int base) { |  | ||||||
|     char buffer[17]; |     char buffer[17]; | ||||||
|     int i = 0; |     int i = 0; | ||||||
| 
 | 
 | ||||||
|     if (base != MODE_DEC) { |     if (num == 0) { | ||||||
|         unsigned int unum = (unsigned int)num; |         lcd_data('0'); | ||||||
|         if (unum == 0) { |         return; | ||||||
|             lcd_data('0'); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         while (unum > 0 && i < 16) { |  | ||||||
|             unsigned int digit = unum % base; |  | ||||||
|             buffer[i++] = (digit < 10) ? ('0' + digit) |  | ||||||
|                                        : ('A' + (digit - 10)); |  | ||||||
|             unum /= base; |  | ||||||
|         } |  | ||||||
|     } else { |  | ||||||
|         if (num < 0) { |  | ||||||
|             lcd_data('-'); |  | ||||||
|             num = -num; |  | ||||||
|         } |  | ||||||
|         if (num == 0) { |  | ||||||
|             lcd_data('0'); |  | ||||||
|             return; |  | ||||||
|         } |  | ||||||
|         while (num > 0 && i < 16) { |  | ||||||
|             buffer[i++] = '0' + (num % 10); |  | ||||||
|             num /= 10; |  | ||||||
|         } |  | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  |     while (num > 0 && i < 16) { | ||||||
|  |         unsigned int d = num % base; | ||||||
|  |         buffer[i++] = (d < 10) ? ('0' + d) : ('A' + d - 10); | ||||||
|  |         num /= base; | ||||||
|  |     } | ||||||
|     while (i > 0) |     while (i > 0) | ||||||
|         lcd_data(buffer[--i]); |         lcd_data(buffer[--i]); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ===== Display handlers ===== */ | /* ===== Display Helpers ===== */ | ||||||
| void display_mode(void) { | void display_mode(void) { | ||||||
|     lcd_cmd(0x80); |     lcd_cmd(0x80); | ||||||
|     lcd_print_str("Mode: "); |     lcd_print_str("Mode: "); | ||||||
|     if (current_base == MODE_BIN) |     if (current_base == MODE_BIN) | ||||||
|         lcd_print_str("BIN     "); |         lcd_print_str("BIN   "); | ||||||
|     else if (current_base == MODE_BASE4) |     else if (current_base == MODE_BASE4) | ||||||
|         lcd_print_str("BASE4   "); |         lcd_print_str("BASE4 "); | ||||||
|     else if (current_base == MODE_OCT) |     else if (current_base == MODE_OCT) | ||||||
|         lcd_print_str("OCT     "); |         lcd_print_str("OCT   "); | ||||||
|     else if (current_base == MODE_DEC) |     else if (current_base == MODE_DEC) | ||||||
|         lcd_print_str("DEC     "); |         lcd_print_str("DEC   "); | ||||||
|     else |     else { | ||||||
|         lcd_print_str("HEX     "); |         lcd_print_str("HEX"); | ||||||
|  |         if (hex_operator_mode) | ||||||
|  |             lcd_print_str("[OPS]"); | ||||||
|  |         else | ||||||
|  |             lcd_print_str("    "); | ||||||
|  |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void display_input(void) { | void display_input(void) { | ||||||
|     lcd_cmd(0xC0); |     lcd_cmd(0xC0); | ||||||
|     lcd_print_str("Inp("); |     lcd_print_str("Input: "); | ||||||
|     if (current_base == MODE_BIN) |  | ||||||
|         lcd_print_str("2"); |  | ||||||
|     else if (current_base == MODE_BASE4) |  | ||||||
|         lcd_print_str("4"); |  | ||||||
|     else if (current_base == MODE_OCT) |  | ||||||
|         lcd_print_str("8"); |  | ||||||
|     else if (current_base == MODE_DEC) |  | ||||||
|         lcd_print_str("10"); |  | ||||||
|     else |  | ||||||
|         lcd_print_str("16"); |  | ||||||
|     lcd_print_str("): "); |  | ||||||
|     lcd_print_num(input_num, current_base); |     lcd_print_num(input_num, current_base); | ||||||
|     lcd_print_str("        "); |     lcd_print_str("       "); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void display_operator_feedback(const char *op_symbol) { | void display_result(void) { | ||||||
|     lcd_cmd(0xC0); |     lcd_cmd(0xC0); | ||||||
|     lcd_print_str("Op: "); |     lcd_print_str("Result: "); | ||||||
|     lcd_print_str(op_symbol); |     lcd_print_num(result, current_base); | ||||||
|     lcd_print_str("           "); |     lcd_print_str("       "); | ||||||
|     delay(100000); |  | ||||||
|     display_input(); |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ====== Scan Keypad ====== */ | /* ===== Keypad and Button ===== */ | ||||||
| unsigned int scan_keypad(void) { | unsigned int scan_keypad(void) { | ||||||
|     unsigned int col, row; |     unsigned int col, row, row_bits; | ||||||
|     unsigned int row_bits; |  | ||||||
| 
 |  | ||||||
|     for (col = 0; col < 4; col++) { |     for (col = 0; col < 4; col++) { | ||||||
|         LPC_GPIO0->FIOSET = COL_MASK; |         LPC_GPIO0->FIOSET = COL_MASK; | ||||||
|         delay(50); |         delay(50); | ||||||
|  | @ -234,9 +226,9 @@ unsigned int scan_keypad(void) { | ||||||
| 
 | 
 | ||||||
|         if (row_bits != 0x0F) { |         if (row_bits != 0x0F) { | ||||||
|             for (row = 0; row < 4; row++) { |             for (row = 0; row < 4; row++) { | ||||||
|                 if ((row_bits & (1 << row)) == 0) { |                 if (!(row_bits & (1 << row))) { | ||||||
|                     LPC_GPIO0->FIOSET = COL_MASK; |                     LPC_GPIO0->FIOSET = COL_MASK; | ||||||
|                     return (col * 4 + row); |                     return col * 4 + row; | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  | @ -245,12 +237,11 @@ unsigned int scan_keypad(void) { | ||||||
|     return 0xFF; |     return 0xFF; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ===== Mode button ===== */ |  | ||||||
| unsigned int scan_mode_button(void) { | unsigned int scan_mode_button(void) { | ||||||
|     return ((LPC_GPIO2->FIOPIN & MODE_BUTTON) == 0) ? 1 : 0; |     return ((LPC_GPIO2->FIOPIN & MODE_BUTTON) == 0) ? 1 : 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ===== Modes and Validation ===== */ | /* ===== Mode and Button ===== */ | ||||||
| void change_mode(void) { | void change_mode(void) { | ||||||
|     if (current_base == MODE_DEC) |     if (current_base == MODE_DEC) | ||||||
|         current_base = MODE_BIN; |         current_base = MODE_BIN; | ||||||
|  | @ -264,8 +255,31 @@ void change_mode(void) { | ||||||
|         current_base = MODE_DEC; |         current_base = MODE_DEC; | ||||||
| 
 | 
 | ||||||
|     display_mode(); |     display_mode(); | ||||||
|  |     input_num = stored_num = result = 0; | ||||||
|  |     operation = OP_NONE; | ||||||
|  |     result_displayed = 0; | ||||||
|  |     display_input(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void handle_mode_button(void) { | ||||||
|  |     unsigned long now = millis(); | ||||||
|  | 
 | ||||||
|  |     if (button_stable == 3 && button_state == 1) { | ||||||
|  |         if (current_base == MODE_HEX) { | ||||||
|  |             if ((now - last_mode_press_time) < 2000) { | ||||||
|  |                 hex_operator_mode = !hex_operator_mode; | ||||||
|  |                 display_mode(); | ||||||
|  |                 last_mode_press_time = 0; | ||||||
|  |             } else { | ||||||
|  |                 last_mode_press_time = now; | ||||||
|  |             } | ||||||
|  |         } else { | ||||||
|  |             change_mode(); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* ===== Validation ===== */ | ||||||
| unsigned int is_valid_digit(unsigned int key) { | unsigned int is_valid_digit(unsigned int key) { | ||||||
|     if (key >= 16) |     if (key >= 16) | ||||||
|         return 0; |         return 0; | ||||||
|  | @ -280,73 +294,72 @@ unsigned int is_valid_digit(unsigned int key) { | ||||||
|     return 1; |     return 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ===== Operator Handling ===== */ | /* ===== Arithmetic ===== */ | ||||||
|  | unsigned int base_arith(unsigned int a, unsigned int b, | ||||||
|  |                         unsigned int op, unsigned int base) { | ||||||
|  |     unsigned int r; | ||||||
|  |     switch (op) { | ||||||
|  |         case OP_ADD: | ||||||
|  |             r = a + b; | ||||||
|  |             break; | ||||||
|  |         case OP_SUB: | ||||||
|  |             r = (a >= b) ? (a - b) : 0; | ||||||
|  |             break; | ||||||
|  |         case OP_MUL: | ||||||
|  |             r = a * b; | ||||||
|  |             break; | ||||||
|  |         default: | ||||||
|  |             r = a; | ||||||
|  |             break; | ||||||
|  |     } | ||||||
|  |     return r; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | /* ===== Operation/Arithmetic Handling ===== */ | ||||||
| void operate(unsigned int op) { | void operate(unsigned int op) { | ||||||
|     stored_num = input_num; |     stored_num = input_num; | ||||||
|     operation = op; |  | ||||||
|     input_num = 0; |     input_num = 0; | ||||||
|  |     operation = op; | ||||||
|     result_displayed = 0; |     result_displayed = 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* perform_operation: arithmetic within the active base */ |  | ||||||
| void perform_operation(void) { | void perform_operation(void) { | ||||||
|     if (operation == OP_ADD) |     result = base_arith(stored_num, input_num, operation, current_base); | ||||||
|         result = stored_num + input_num; |     display_result(); | ||||||
|     else if (operation == OP_SUB) |  | ||||||
|         result = stored_num - input_num; |  | ||||||
|     else if (operation == OP_MUL) |  | ||||||
|         result = stored_num * input_num; |  | ||||||
|     else |  | ||||||
|         result = input_num; |  | ||||||
| 
 |  | ||||||
|     /* Base-aware modular arithmetic for non-DEC modes */ |  | ||||||
|     if (current_base != MODE_DEC) { |  | ||||||
|         if (result < 0) |  | ||||||
|             result = (result % current_base + current_base) % current_base; |  | ||||||
|         else |  | ||||||
|             result %= current_base; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     lcd_cmd(0xC0); |  | ||||||
|     lcd_print_str("Res("); |  | ||||||
|     if (current_base == MODE_BIN) |  | ||||||
|         lcd_print_str("2"); |  | ||||||
|     else if (current_base == MODE_BASE4) |  | ||||||
|         lcd_print_str("4"); |  | ||||||
|     else if (current_base == MODE_OCT) |  | ||||||
|         lcd_print_str("8"); |  | ||||||
|     else if (current_base == MODE_DEC) |  | ||||||
|         lcd_print_str("10"); |  | ||||||
|     else |  | ||||||
|         lcd_print_str("16"); |  | ||||||
|     lcd_print_str("): "); |  | ||||||
|     lcd_print_num(result, current_base); |  | ||||||
|     lcd_print_str("        "); |  | ||||||
| 
 |  | ||||||
|     input_num = result; |     input_num = result; | ||||||
|     operation = OP_NONE; |     operation = OP_NONE; | ||||||
|     result_displayed = 1; |     result_displayed = 1; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| unsigned char is_operator_active(unsigned int key, unsigned int mode_button) { | /* ===== Key Classifier ===== */ | ||||||
|     if (current_base == MODE_HEX) | unsigned char is_operator_active(unsigned int key) { | ||||||
|         return (mode_button && key >= 11 && key <= 15); |     if (key >= 11 && key <= 15) { | ||||||
|     else |         if (current_base == MODE_HEX) | ||||||
|         return (key >= 11 && key <= 15); |             return hex_operator_mode; | ||||||
|  |         else | ||||||
|  |             return 1; | ||||||
|  |     } | ||||||
|  |     return 0; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| /* ===== MAIN ===== */ | /* ===== MAIN ===== */ | ||||||
| int main(void) { | int main(void) { | ||||||
|     input_num = stored_num = result = 0; |  | ||||||
|     current_base = MODE_DEC; |     current_base = MODE_DEC; | ||||||
|  |     input_num = stored_num = result = 0; | ||||||
|     operation = OP_NONE; |     operation = OP_NONE; | ||||||
|     lcd_flag = 0; |  | ||||||
|     result_displayed = 0; |     result_displayed = 0; | ||||||
|     key = last_key = 0xFF; |     key = last_key = 0xFF; | ||||||
|     stable = button_stable = 0; |     stable = 0; | ||||||
|  |     button_stable = 0; | ||||||
|     button_state = last_button_state = 0; |     button_state = last_button_state = 0; | ||||||
|  |     hex_operator_mode = 0; | ||||||
|  |     last_mode_press_time = 0; | ||||||
| 
 | 
 | ||||||
|     /* Configure pins */ |     /* ===== SystemClock & SysTick Setup ===== */ | ||||||
|  |     SystemCoreClockUpdate(); | ||||||
|  |     SysTick_Config(SystemCoreClock / 1000);  // 1ms tick
 | ||||||
|  | 
 | ||||||
|  |     /* ===== Peripheral Init ===== */ | ||||||
|     LPC_PINCON->PINSEL0 = 0; |     LPC_PINCON->PINSEL0 = 0; | ||||||
|     LPC_PINCON->PINSEL1 = 0; |     LPC_PINCON->PINSEL1 = 0; | ||||||
|     LPC_PINCON->PINSEL3 = 0; |     LPC_PINCON->PINSEL3 = 0; | ||||||
|  | @ -360,85 +373,63 @@ int main(void) { | ||||||
| 
 | 
 | ||||||
|     LPC_GPIO0->FIODIR |= (0xFF << SEG_SHIFT); |     LPC_GPIO0->FIODIR |= (0xFF << SEG_SHIFT); | ||||||
|     LPC_GPIO1->FIODIR |= DIGIT_EN; |     LPC_GPIO1->FIODIR |= DIGIT_EN; | ||||||
| 
 |  | ||||||
|     LPC_GPIO0->FIODIR |= LCD_DATA_MASK | LCD_RS | LCD_EN; |     LPC_GPIO0->FIODIR |= LCD_DATA_MASK | LCD_RS | LCD_EN; | ||||||
| 
 | 
 | ||||||
|     lcd_init(); |     lcd_init(); | ||||||
|     display_mode(); |     display_mode(); | ||||||
|     display_input(); |     display_input(); | ||||||
| 
 | 
 | ||||||
|     for (;;) { |     /* ===== Main Loop ===== */ | ||||||
|  |     while (1) { | ||||||
|         key = scan_keypad(); |         key = scan_keypad(); | ||||||
|         button_state = scan_mode_button(); |         button_state = scan_mode_button(); | ||||||
| 
 | 
 | ||||||
|         /* Debounce keypad */ |         // Debounce keypad
 | ||||||
|         if (key == last_key) { |         if (key == last_key) | ||||||
|             if (stable < 5) |             stable = (stable < 5) ? stable + 1 : stable; | ||||||
|                 stable++; |         else { | ||||||
|         } else { |  | ||||||
|             last_key = key; |             last_key = key; | ||||||
|             stable = 0; |             stable = 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Debounce mode button */ |         // Debounce button
 | ||||||
|         if (button_state == last_button_state) { |         if (button_state == last_button_state) | ||||||
|             if (button_stable < 5) |             button_stable = (button_stable < 5) ? button_stable + 1 : button_stable; | ||||||
|                 button_stable++; |         else { | ||||||
|         } else { |  | ||||||
|             last_button_state = button_state; |             last_button_state = button_state; | ||||||
|             button_stable = 0; |             button_stable = 0; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Handle mode change */ |         handle_mode_button(); | ||||||
|         if (button_stable == 3 && button_state == 1) { |  | ||||||
|             change_mode(); |  | ||||||
|             button_stable = 5; |  | ||||||
|         } |  | ||||||
| 
 | 
 | ||||||
|         /* Handle key event */ |  | ||||||
|         if (stable == 3 && key != 0xFF) { |         if (stable == 3 && key != 0xFF) { | ||||||
|             unsigned char op_allowed = is_operator_active(key, button_state); |             if (is_operator_active(key)) { | ||||||
| 
 |                 switch (key) { | ||||||
|             if (op_allowed) { |                     case 11: operate(OP_ADD); display_input(); break; | ||||||
|                 if (key == 11) { |                     case 12: input_num = stored_num = result = 0; | ||||||
|                     operate(OP_ADD); |                              operation = OP_NONE; display_input(); break; | ||||||
|                     display_operator_feedback("+"); |                     case 13: operate(OP_SUB); display_input(); break; | ||||||
|                 } else if (key == 12) { |                     case 14: operate(OP_MUL); display_input(); break; | ||||||
|                     input_num = stored_num = result = 0; |                     case 15: perform_operation(); break; | ||||||
|                     operation = OP_NONE; |  | ||||||
|                     result_displayed = 0; |  | ||||||
|                     display_operator_feedback("CLR"); |  | ||||||
|                 } else if (key == 13) { |  | ||||||
|                     operate(OP_SUB); |  | ||||||
|                     display_operator_feedback("-"); |  | ||||||
|                 } else if (key == 14) { |  | ||||||
|                     operate(OP_MUL); |  | ||||||
|                     display_operator_feedback("*"); |  | ||||||
|                 } else if (key == 15) { |  | ||||||
|                     perform_operation(); |  | ||||||
|                 } |                 } | ||||||
|             } else if (is_valid_digit(key)) { |             } else if (is_valid_digit(key)) { | ||||||
|                 result_displayed = 0; |                 result_displayed = 0; | ||||||
|                 input_num = input_num * current_base + key; |                 input_num = input_num * current_base + key; | ||||||
|                 display_input(); |                 display_input(); | ||||||
|             } |             } | ||||||
| 
 |  | ||||||
|             stable = 5; |             stable = 5; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         /* Update 7-seg state display */ |         // Simple 7-seg base display
 | ||||||
|         unsigned int seg_pattern; |  | ||||||
|         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->FIOCLR = (0xFF << SEG_SHIFT); | ||||||
|         LPC_GPIO0->FIOSET = (seg_pattern << SEG_SHIFT); |         unsigned int segval = 0x3F;  // default '0'
 | ||||||
|  |         if (current_base == MODE_BIN) segval = seven_seg[2]; | ||||||
|  |         else if (current_base == MODE_BASE4) segval = seven_seg[4]; | ||||||
|  |         else if (current_base == MODE_OCT) segval = seven_seg[8]; | ||||||
|  |         else if (current_base == MODE_DEC) segval = seven_seg[0]; | ||||||
|  |         else if (current_base == MODE_HEX) segval = seven_seg[0xA];  // 'A' for HEX
 | ||||||
|  | 
 | ||||||
|  |         LPC_GPIO0->FIOSET = (segval << SEG_SHIFT); | ||||||
|         LPC_GPIO1->FIOSET = DIGIT_EN; |         LPC_GPIO1->FIOSET = DIGIT_EN; | ||||||
| 
 | 
 | ||||||
|         delay(3000); |         delay(3000); | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue