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++);
 | 
						|
    }
 | 
						|
}
 |