89 lines
2.8 KiB
C
89 lines
2.8 KiB
C
#include <LPC17xx.h>
|
|
|
|
int main(void) {
|
|
unsigned long i, c, r;
|
|
unsigned long candidate = 0xFF;
|
|
unsigned long stable = 0;
|
|
unsigned long displayed = 0xFF;
|
|
unsigned long read_key, rows, seg;
|
|
unsigned char seven_seg[16] = {
|
|
0x3F, 0x06, 0x5B, 0x4F,
|
|
0x66, 0x6D, 0x7D, 0x07,
|
|
0x7F, 0x6F, 0x77, 0x7C,
|
|
0x39, 0x5E, 0x79, 0x71
|
|
};
|
|
|
|
// Configure pins as GPIO for used ranges
|
|
LPC_PINCON->PINSEL0 = 0;
|
|
LPC_PINCON->PINSEL1 = 0;
|
|
LPC_PINCON->PINSEL3 = 0;
|
|
|
|
// Directions
|
|
LPC_GPIO0->FIODIR |= (0xFFu << 4); // P0.4..P0.11 -> segments out
|
|
LPC_GPIO0->FIODIR |= (0x0Fu << 15); // P0.15..P0.18 -> columns out
|
|
LPC_GPIO0->FIODIR &= ~(0x0Fu << 19); // P0.19..P0.22 -> rows in
|
|
LPC_GPIO1->FIODIR |= (0x0Fu << 23); // P1.23..P1.26 -> digit enables out
|
|
|
|
// Initial states
|
|
LPC_GPIO0->FIOCLR = (0xFFu << 4); // segments off
|
|
LPC_GPIO1->FIOCLR = (0x0Fu << 23); // all digits off
|
|
LPC_GPIO0->FIOSET = (0x0Fu << 15); // all columns high (inactive)
|
|
|
|
while (1) {
|
|
read_key = 0xFF;
|
|
|
|
// Scan 4 columns
|
|
for (c = 0; c < 4; c++) {
|
|
// Set all columns high, then pull one low
|
|
LPC_GPIO0->FIOSET = (0x0Fu << 15);
|
|
for (i = 0; i < 50; i++); // short settle delay
|
|
LPC_GPIO0->FIOCLR = (1u << (15 + c));
|
|
for (i = 0; i < 200; i++); // settle after driving column
|
|
|
|
// Read rows P0.19..P0.22 (active-low). Normalize to 0..15.
|
|
rows = (LPC_GPIO0->FIOPIN >> 19) & 0x0Fu;
|
|
|
|
if (rows != 0x0Fu) {
|
|
for (r = 0; r < 4; r++) {
|
|
if (((rows >> r) & 1u) == 0u) {
|
|
read_key = (c << 2) + r; // c*4 + r, 0..15
|
|
break;
|
|
}
|
|
}
|
|
LPC_GPIO0->FIOSET = (0x0Fu << 15); // restore columns high
|
|
break; // found a key this scan
|
|
}
|
|
}
|
|
|
|
// Debounce: require 3 consecutive identical reads
|
|
if (read_key == candidate) {
|
|
if (stable < 3) stable++;
|
|
} else {
|
|
candidate = read_key;
|
|
stable = 1;
|
|
}
|
|
|
|
if (stable >= 3) {
|
|
if (candidate != 0xFF) {
|
|
displayed = candidate & 0x0F;
|
|
}
|
|
stable = 3; // clamp
|
|
}
|
|
|
|
// Update display if we have a digit
|
|
if (displayed != 0xFF) {
|
|
seg = seven_seg[displayed];
|
|
LPC_GPIO0->FIOCLR = (0xFFu << 4);
|
|
LPC_GPIO0->FIOSET = ((unsigned long)seg << 4);
|
|
|
|
// Enable only digit at P1.23
|
|
LPC_GPIO1->FIOCLR = (0x0Fu << 23);
|
|
LPC_GPIO1->FIOSET = (1u << 23);
|
|
} else {
|
|
LPC_GPIO1->FIOCLR = (0x0Fu << 23);
|
|
}
|
|
|
|
// Pace scanning/debounce timing
|
|
for (i = 0; i < 3000; i++);
|
|
}
|
|
}
|