proj
This commit is contained in:
parent
77490396d4
commit
c59338aeea
1 changed files with 60 additions and 43 deletions
|
|
@ -2,35 +2,33 @@
|
|||
|
||||
/* ===================================================
|
||||
* SMART CALCULATOR - LPC176x
|
||||
* Supports DEC, BIN, OCT, and HEX input modes
|
||||
*, with 4x4 keypad, LCD, 7-segment, and mode button.
|
||||
* Supports BIN, BASE4, OCT, DEC, and HEX modes with
|
||||
* 4x4 keypad, LCD, and 7-segment display.
|
||||
* ---------------------------------------------------
|
||||
* Decimal mode: Operators B-F active directly
|
||||
* Hexadecimal mode: Operators B-F active with MODE button
|
||||
* DEC/BIN/BASE4/OCT : Operators B–F work directly
|
||||
* HEX : Operators B–F require MODE pressed
|
||||
* ===================================================
|
||||
*/
|
||||
|
||||
// 7-Segment patterns for 0-F
|
||||
// 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
|
||||
};
|
||||
|
||||
/* ---------------- Pin Mapping ----------------
|
||||
/* ===== Pin Mapping =====
|
||||
* Keypad (4x4):
|
||||
* Columns: P0.15–P0.18 (Output)
|
||||
* Rows: P0.19–P0.22 (Input, pull-up)
|
||||
* Columns: P0.15–P0.18 (Outputs)
|
||||
* Rows: P0.19–P0.22 (Inputs, pull-ups)
|
||||
*
|
||||
* 7-Segment:
|
||||
* Segments: P0.4–P0.11
|
||||
* Digit Enable: P1.23
|
||||
*
|
||||
* LCD:
|
||||
* Data: P0.23–P0.26
|
||||
* RS: P0.27, EN: P0.28
|
||||
* Data: P0.23–P0.26, RS: P0.27, EN: P0.28
|
||||
*
|
||||
* Mode Button: P2.12
|
||||
* ------------------------------------------------
|
||||
* Mode Button: P2.12 (active low)
|
||||
*/
|
||||
|
||||
/* ===== MACROS ===== */
|
||||
|
|
@ -50,6 +48,7 @@ const unsigned char seven_seg[16] = {
|
|||
#define MODE_BUTTON (1 << 12)
|
||||
|
||||
#define MODE_BIN 2
|
||||
#define MODE_BASE4 4
|
||||
#define MODE_OCT 8
|
||||
#define MODE_DEC 10
|
||||
#define MODE_HEX 16
|
||||
|
|
@ -61,6 +60,7 @@ const unsigned char seven_seg[16] = {
|
|||
|
||||
/* ===== Global Variables (Predeclared) ===== */
|
||||
int input_num;
|
||||
unsigned int seg_pattern;
|
||||
int stored_num;
|
||||
int result;
|
||||
unsigned int current_base;
|
||||
|
|
@ -70,7 +70,6 @@ unsigned char result_displayed;
|
|||
|
||||
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);
|
||||
|
|
@ -91,7 +90,7 @@ void change_mode(void);
|
|||
void operate(unsigned int op);
|
||||
void perform_operation(void);
|
||||
|
||||
/* ===== Utility & LCD Handling ===== */
|
||||
/* ===== Delays ===== */
|
||||
void delay(volatile unsigned int d) {
|
||||
while (d--)
|
||||
__NOP();
|
||||
|
|
@ -103,6 +102,7 @@ void lcd_delay(unsigned long r) {
|
|||
;
|
||||
}
|
||||
|
||||
/* ===== LCD ===== */
|
||||
void lcd_write_nibble(unsigned char nibble, unsigned char is_data) {
|
||||
unsigned long temp;
|
||||
temp = (nibble & 0x0F) << LCD_DATA_SHIFT;
|
||||
|
|
@ -188,11 +188,14 @@ void lcd_print_num(int num, unsigned int base) {
|
|||
lcd_data(buffer[--i]);
|
||||
}
|
||||
|
||||
/* ===== Display Handling ===== */
|
||||
void display_mode(void) {
|
||||
lcd_cmd(0x80);
|
||||
lcd_print_str("Mode: ");
|
||||
if (current_base == MODE_BIN)
|
||||
lcd_print_str("BIN ");
|
||||
else if (current_base == MODE_BASE4)
|
||||
lcd_print_str("BASE4 ");
|
||||
else if (current_base == MODE_OCT)
|
||||
lcd_print_str("OCT ");
|
||||
else if (current_base == MODE_DEC)
|
||||
|
|
@ -217,7 +220,7 @@ void display_operator_feedback(const char *op_symbol) {
|
|||
display_input();
|
||||
}
|
||||
|
||||
/* ====== Keypad & Button Handling ===== */
|
||||
/* ===== Input Handling ===== */
|
||||
unsigned int scan_keypad(void) {
|
||||
unsigned int col, row;
|
||||
unsigned int row_bits;
|
||||
|
|
@ -246,11 +249,28 @@ unsigned int scan_mode_button(void) {
|
|||
return ((LPC_GPIO2->FIOPIN & MODE_BUTTON) == 0) ? 1 : 0;
|
||||
}
|
||||
|
||||
/* ===== Mode Switching ===== */
|
||||
void change_mode(void) {
|
||||
if (current_base == MODE_DEC)
|
||||
current_base = MODE_BIN;
|
||||
else if (current_base == MODE_BIN)
|
||||
current_base = MODE_BASE4;
|
||||
else if (current_base == MODE_BASE4)
|
||||
current_base = MODE_OCT;
|
||||
else if (current_base == MODE_OCT)
|
||||
current_base = MODE_HEX;
|
||||
else
|
||||
current_base = MODE_DEC;
|
||||
display_mode();
|
||||
}
|
||||
|
||||
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_BASE4 && key >= 4)
|
||||
return 0;
|
||||
if (current_base == MODE_OCT && key >= 8)
|
||||
return 0;
|
||||
if (current_base == MODE_DEC && key >= 10)
|
||||
|
|
@ -258,20 +278,7 @@ unsigned int is_valid_digit(unsigned int key) {
|
|||
return 1; // HEX accepts all 0-F
|
||||
}
|
||||
|
||||
void change_mode(void) {
|
||||
if (current_base == MODE_DEC)
|
||||
current_base = MODE_BIN;
|
||||
else if (current_base == MODE_BIN)
|
||||
current_base = MODE_OCT;
|
||||
else if (current_base == MODE_OCT)
|
||||
current_base = MODE_HEX;
|
||||
else
|
||||
current_base = MODE_DEC;
|
||||
|
||||
display_mode();
|
||||
}
|
||||
|
||||
/* ===== Operator Handling ===== */
|
||||
/* ===== Operations ===== */
|
||||
void operate(unsigned int op) {
|
||||
stored_num = input_num;
|
||||
operation = op;
|
||||
|
|
@ -301,7 +308,7 @@ void perform_operation(void) {
|
|||
|
||||
/* ===== MAIN ===== */
|
||||
int main(void) {
|
||||
// Init globals
|
||||
// Initialize globals
|
||||
input_num = stored_num = result = 0;
|
||||
current_base = MODE_DEC;
|
||||
operation = OP_NONE;
|
||||
|
|
@ -311,20 +318,25 @@ int main(void) {
|
|||
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;
|
||||
|
||||
// Keypad setup
|
||||
LPC_GPIO0->FIODIR |= COL_MASK;
|
||||
LPC_GPIO0->FIODIR &= ~ROW_MASK;
|
||||
LPC_GPIO0->FIOSET = COL_MASK;
|
||||
|
||||
// Mode button setup
|
||||
LPC_GPIO2->FIODIR &= ~MODE_BUTTON;
|
||||
|
||||
// 7-Segment setup
|
||||
LPC_GPIO0->FIODIR |= (0xFF << SEG_SHIFT);
|
||||
LPC_GPIO1->FIODIR |= DIGIT_EN;
|
||||
|
||||
// LCD setup
|
||||
LPC_GPIO0->FIODIR |= LCD_DATA_MASK | LCD_RS | LCD_EN;
|
||||
|
||||
lcd_init();
|
||||
|
|
@ -335,6 +347,7 @@ int main(void) {
|
|||
key = scan_keypad();
|
||||
button_state = scan_mode_button();
|
||||
|
||||
// Debounce keypad
|
||||
if (key == last_key) {
|
||||
if (stable < 5)
|
||||
stable++;
|
||||
|
|
@ -343,6 +356,7 @@ int main(void) {
|
|||
stable = 0;
|
||||
}
|
||||
|
||||
// Debounce mode button
|
||||
if (button_state == last_button_state) {
|
||||
if (button_stable < 5)
|
||||
button_stable++;
|
||||
|
|
@ -351,18 +365,24 @@ int main(void) {
|
|||
button_stable = 0;
|
||||
}
|
||||
|
||||
// Cycle through modes
|
||||
if (button_stable == 3 && button_state == 1) {
|
||||
change_mode();
|
||||
button_stable = 5;
|
||||
}
|
||||
|
||||
// Handle keypad press
|
||||
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)) {
|
||||
unsigned char allow_operator = 0;
|
||||
|
||||
// Operators allowed directly for all modes except HEX (must hold mode)
|
||||
if (current_base == MODE_HEX && button_state == 1)
|
||||
allow_operator = 1;
|
||||
else if (current_base != MODE_HEX)
|
||||
allow_operator = 1;
|
||||
|
||||
// Operator Keys: B–F (indices 11–15)
|
||||
if (allow_operator) {
|
||||
if (key == 11) { // B = +
|
||||
operate(OP_ADD);
|
||||
display_operator_feedback("+");
|
||||
|
|
@ -391,21 +411,18 @@ int main(void) {
|
|||
display_input();
|
||||
}
|
||||
}
|
||||
|
||||
stable = 5;
|
||||
}
|
||||
|
||||
// ===== STATE DISPLAY on 7-Segment =====
|
||||
unsigned int seg_pattern;
|
||||
|
||||
if (operation == OP_NONE && result_displayed == 0)
|
||||
seg_pattern = 0x06; // '1'
|
||||
seg_pattern = 0x06; // '1' - Input mode
|
||||
else if (operation != OP_NONE)
|
||||
seg_pattern = 0x5B | 0x80; // '2' + DP
|
||||
seg_pattern = 0x5B | 0x80; // '2' + DP - Waiting for 2nd operand
|
||||
else if (result_displayed == 1)
|
||||
seg_pattern = 0x4F | 0x80; // '3' + DP
|
||||
seg_pattern = 0x4F | 0x80; // '3' + DP - Result shown
|
||||
else
|
||||
seg_pattern = 0x3F; // '0'
|
||||
seg_pattern = 0x3F; // '0' - Reset
|
||||
|
||||
LPC_GPIO0->FIOCLR = (0xFF << SEG_SHIFT);
|
||||
LPC_GPIO0->FIOSET = (seg_pattern << SEG_SHIFT);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue