9.1 KiB
LPC1768 Multi-Base Calculator - Code Explainer & Hardware Mapping Report
Overview
This code implements a multi-base calculator for the LPC1768 microcontroller with support for Binary, Octal, Decimal, and Hexadecimal number systems. It features a 4x4 matrix keypad for input, a 16x2 LCD for display, and a single 7-segment display for quick output visualization.
Core Functionality
1. Number Base Modes
The calculator supports four number bases:
- Binary (BIN) - Base 2 (digits 0-1)
- Octal (OCT) - Base 8 (digits 0-7)
- Decimal (DEC) - Base 10 (digits 0-9) - Default mode
- Hexadecimal (HEX) - Base 16 (digits 0-9, A-F)
Mode switching is done via the P2.12 button in the cycle: DEC → BIN → OCT → HEX → DEC...
2. Keypad Operation
Standard Digit Input (Keys 0-F)
- Keys 0-9 and A-F enter digits
- Only valid digits for the current base are accepted
- Numbers are built up by multiplying the current value by the base and adding the new digit
Operator Mode (Hold Key 0 + Another Key)
The code uses Key 0 as a "shift" key for operator access:
| Combination | Function | Operation |
|---|---|---|
| Key 0 + B | Addition | Stores current number, sets + operation |
| Key 0 + C | Clear | Resets all values |
| Key 0 + D | Subtraction | Stores current number, sets - operation |
| Key 0 + E | Multiplication | Stores current number, sets × operation |
| Key 0 + F | Equals | Calculates result based on stored operation |
3. Signed Integer Handling
The code uses signed 32-bit integers (int type) with special display logic:
- Decimal mode: Negative numbers shown with "-" sign
- Other bases: Numbers displayed as unsigned (two's complement representation)
- 7-segment display: Decimal point illuminates to indicate negative numbers
4. Display Outputs
LCD Display (16x2)
- Line 1: Current mode ("Mode: BIN/OCT/DEC/HEX")
- Line 2: Input number ("Inp: [number]") or Result ("Res: [number]")
- Brief operator feedback shown when operations are selected
7-Segment Display
- Shows the last digit (rightmost) of the current input in base-16
- Decimal point lights up when the number is negative
Hardware Mapping to FRC Connectors
CNA Connector (P0.4 to P0.11)
Usage: 7-Segment Display
| Pin CNA | LPC1768 Pin | Function | Code Reference |
|---|---|---|---|
| 1 | P0.4 | Segment a | SEG_SHIFT = 4 |
| 2 | P0.5 | Segment b | Bits 4-11 control segments |
| 3 | P0.6 | Segment c | seven_seg[] array patterns |
| 4 | P0.7 | Segment d | |
| 5 | P0.8 | Segment e | |
| 6 | P0.9 | Segment f | |
| 7 | P0.10 | Segment g | |
| 8 | P0.11 | Decimal point | Bit 7 of pattern (0x80) |
| 10 | GND | Ground |
Code Configuration:
#define SEG_SHIFT 4
LPC_GPIO0->FIODIR |= (0xFF << SEG_SHIFT); // Configure as output
LPC_GPIO0->FIOSET = (seg_pattern << SEG_SHIFT); // Set segments
CNB Connector (P1.23-P1.26, P2.10-P2.13)
Usage: 7-Segment Digit Enable & Mode Button
| Pin CNB | LPC1768 Pin | Function | Code Reference |
|---|---|---|---|
| 1 | P1.23 | 7-Seg Digit Enable | DIGIT_EN (1<<23) |
| 7 | P2.12 | Mode Button (Input) | MODE_BUTTON (1<<12) |
| 2-6, 8 | P1.24-26, P2.10-11, P2.13 | Unused | |
| 10 | GND | Ground |
Code Configuration:
#define DIGIT_EN (1<<23)
LPC_GPIO1->FIODIR |= DIGIT_EN; // P1.23 as output
LPC_GPIO1->FIOSET = DIGIT_EN; // Enable digit
#define MODE_BUTTON (1<<12)
LPC_GPIO2->FIODIR &= ~MODE_BUTTON; // P2.12 as input (pull-up)
Mode Button Behavior:
- Active LOW (reads 0 when pressed)
- Debounced with 5-sample stability check
- Cycles through number bases
CNC Connector (P0.15-P0.22, P2.13)
Usage: 4×4 Matrix Keypad
| Pin CNC | LPC1768 Pin | Function | Keypad Role |
|---|---|---|---|
| 1 | P0.15 | Column 0 | Output (scan low) |
| 2 | P0.16 | Column 1 | Output (scan low) |
| 3 | P0.17 | Column 2 | Output (scan low) |
| 4 | P0.18 | Column 3 | Output (scan low) |
| 5 | P0.19 | Row 0 | Input (pull-high) |
| 6 | P0.20 | Row 1 | Input (pull-high) |
| 7 | P0.21 | Row 2 | Input (pull-high) |
| 8 | P0.22 | Row 3 | Input (pull-high) |
| 10 | GND | Ground |
Keypad Matrix Layout:
Col0 Col1 Col2 Col3
(15) (16) (17) (18)
Row0 (19) 0 1 2 3
Row1 (20) 4 5 6 7
Row2 (21) 8 9 A B
Row3 (22) C D E F
Scanning Algorithm:
- Set all columns HIGH
- Pull one column LOW
- Read row pins
- If a row is LOW, a key at that (column, row) is pressed
- Key number =
col × 4 + row
Code Configuration:
#define COL_BASE 15
#define ROW_BASE 19
#define COL_MASK (0x0F << COL_BASE) // P0.15-18
#define ROW_MASK (0x0F << ROW_BASE) // P0.19-22
LPC_GPIO0->FIODIR |= COL_MASK; // Columns as output
LPC_GPIO0->FIODIR &= ~ROW_MASK; // Rows as input
CND Connector (P0.23-P0.28, P2.0-P2.1)
Usage: 16×2 LCD Display (4-bit mode)
| Pin CND | LPC1768 Pin | Function | LCD Pin |
|---|---|---|---|
| 1 | P0.23 | Data bit 4 (D4) | LCD D4 |
| 2 | P0.24 | Data bit 5 (D5) | LCD D5 |
| 3 | P0.25 | Data bit 6 (D6) | LCD D6 |
| 4 | P0.26 | Data bit 7 (D7) | LCD D7 |
| 5 | P0.27 | Register Select (RS) | LCD RS |
| 6 | P0.28 | Enable (EN) | LCD EN |
| 7-8 | P2.0-1 | Unused | |
| 10 | GND | Ground |
LCD Communication (4-bit Mode):
- Each byte sent as two 4-bit nibbles (high nibble first)
- RS = 0: Command mode
- RS = 1: Data mode
- EN pulse: Latches data into LCD
Code Configuration:
#define LCD_DATA_SHIFT 23
#define LCD_DATA_MASK (0x0F << LCD_DATA_SHIFT) // P0.23-26
#define LCD_RS (1<<27) // P0.27
#define LCD_EN (1<<28) // P0.28
LPC_GPIO0->FIODIR |= LCD_DATA_MASK | LCD_RS | LCD_EN; // All outputs
LCD Initialization Sequence:
- Wait 5ms after power-on
- Send 0x03 three times (8-bit mode reset)
- Send 0x02 (switch to 4-bit mode)
- Configure: 4-bit, 2-line, 5×8 font (0x28)
- Display ON, cursor OFF (0x0C)
- Clear display (0x01)
- Entry mode: increment, no shift (0x06)
Key Code Functions
Keypad Scanning
unsigned int scan_keypad(void)
- Scans 4×4 matrix by pulling columns low sequentially
- Returns key number (0-15) or 0xFF if no key pressed
- Includes debouncing delay
Shift Key Detection
unsigned int is_key0_pressed(void)
- Specifically checks if Key 0 is being held down
- Enables "operator mode" when Key 0 + another key pressed
Digit Validation
unsigned int is_valid_digit(unsigned int key)
- Ensures entered digit is valid for current base
- BIN: 0-1, OCT: 0-7, DEC: 0-9, HEX: 0-F
LCD Number Display
void lcd_print_num(int num, unsigned int base)
- Handles negative numbers in decimal mode (shows "-")
- For other bases, displays unsigned representation
- Converts number to string in specified base
Operation Flow Example
Example: Calculate 5 + 3 in Decimal Mode
- Power on → Mode: DEC, Input: 0
- Press Key 5 → Input: 5 (displayed on LCD and 7-seg)
- Hold Key 0 + Press B → "Op: +" feedback, stored = 5, input = 0
- Press Key 3 → Input: 3
- Hold Key 0 + Press F → "Res: 8" displayed, input = 8
- Result can be used for next calculation
Example: Switch to Binary Mode
- Press P2.12 button → Mode cycles DEC → BIN
- LCD shows "Mode: BIN"
- Only keys 0 and 1 are now valid
- Display shows binary representation
Debouncing Strategy
Both keypad and mode button use count-based debouncing:
if(key == last_key){
if(stable < 5) stable++;
}
- Requires 3 consecutive stable reads before acting (
stable == 3) - After action, sets
stable = 5to prevent repeat triggers - Prevents false triggers from mechanical switch bounce
Safety & Overflow Handling
if(input_num > 32767) input_num = input_num % 32768;
if(input_num < -32768) input_num = -32768;
- Wraps overflow for signed 32-bit integers
- Prevents display issues with very large numbers
Pin Configuration Summary Table
| GPIO Port | Pins Used | Direction | Function | FRC Connector |
|---|---|---|---|---|
| P0.4-11 | 8 bits | Output | 7-seg segments | CNA 1-8 |
| P0.15-18 | 4 bits | Output | Keypad columns | CNC 1-4 |
| P0.19-22 | 4 bits | Input | Keypad rows | CNC 5-8 |
| P0.23-26 | 4 bits | Output | LCD data D4-D7 | CND 1-4 |
| P0.27 | 1 bit | Output | LCD RS | CND 5 |
| P0.28 | 1 bit | Output | LCD EN | CND 6 |
| P1.23 | 1 bit | Output | 7-seg digit enable | CNB 1 |
| P2.12 | 1 bit | Input | Mode button | CNB 7 |
Conclusion
This calculator demonstrates effective use of the LPC1768's GPIO capabilities across multiple peripherals:
- Efficient matrix keypad scanning minimizes pin usage
- 4-bit LCD mode reduces wiring complexity
- Single 7-segment provides instant visual feedback
- Clever "shift key" mechanism provides operator access without dedicated buttons
The hardware mapping efficiently utilizes all four FRC connectors to create a fully functional multi-base calculator with a clean user interface.