This commit is contained in:
sherlock 2025-10-23 12:56:40 +05:30
parent 023708f6d0
commit e36e851593

View file

@ -1,8 +1,8 @@
#include "LPC17xx.h" #include "LPC17xx.h"
// PWM variables // PWM variables
unsigned long int duty_cycle = 0; volatile unsigned long int duty_cycle = 10; // Start at 10%
unsigned long int pwm_counter = 0; volatile unsigned long int pwm_counter = 0;
// Pin definitions // Pin definitions
#define LED_SHIFT 4 // CNA: P0.4-P0.11 #define LED_SHIFT 4 // CNA: P0.4-P0.11
@ -18,10 +18,12 @@ unsigned long int pwm_counter = 0;
#define COL_MASK_P0 (COL2 | COL3) #define COL_MASK_P0 (COL2 | COL3)
#define COL_MASK_P2 (COL0 | COL1) #define COL_MASK_P2 (COL0 | COL1)
#define PWM_PERIOD 100 // Smaller for faster PWM #define PWM_PERIOD 100 // 100 steps for percentage
static void short_delay(volatile unsigned int d) { static void delay_ms(unsigned int ms) {
while(d--) __NOP(); unsigned int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 10000; j++);
} }
static void set_column(unsigned int col) static void set_column(unsigned int col)
@ -42,12 +44,12 @@ static unsigned int is_row0_pressed(void)
return !(LPC_GPIO0->FIOPIN & ROW0); return !(LPC_GPIO0->FIOPIN & ROW0);
} }
// PWM Interrupt Handler - Software PWM // HIGH-SPEED PWM Interrupt Handler
void PWM1_IRQHandler(void) void PWM1_IRQHandler(void)
{ {
if (LPC_PWM1->IR & (1 << 0)) if (LPC_PWM1->IR & (1 << 0))
{ {
// Software PWM for all 8 LEDs // Fast software PWM for all 8 LEDs
if(pwm_counter < duty_cycle) if(pwm_counter < duty_cycle)
LPC_GPIO0->FIOSET = LED_MASK; // All LEDs ON LPC_GPIO0->FIOSET = LED_MASK; // All LEDs ON
else else
@ -57,72 +59,71 @@ void PWM1_IRQHandler(void)
if(pwm_counter >= PWM_PERIOD) if(pwm_counter >= PWM_PERIOD)
pwm_counter = 0; pwm_counter = 0;
LPC_PWM1->IR = (1 << 0); // Clear interrupt LPC_PWM1->IR = (1 << 0); // Clear interrupt flag
} }
} }
int main(void) int main(void)
{ {
unsigned int col_idx; unsigned int col_idx;
unsigned int candidate_key = 0xFF; unsigned int read_key;
unsigned int stable = 0;
unsigned int last_key = 0xFF; unsigned int last_key = 0xFF;
// === SYSTEM CLOCK SETUP (Optional but recommended) ===
SystemInit(); // Use default clock setup
// === PIN CONFIGURATION === // === PIN CONFIGURATION ===
LPC_PINCON->PINSEL0 &= ~(0xFFFF << 8); // Clear P0.4-P0.11 (GPIO) LPC_PINCON->PINSEL0 &= ~(0xFFFF << 8); // P0.4-P0.11 as GPIO
LPC_PINCON->PINSEL1 &= ~(0xFFFF << 14); // Clear P0.23-P0.28 LPC_PINCON->PINSEL1 &= ~(0xFFFF << 14); // P0.23-P0.28 as GPIO
LPC_PINCON->PINSEL3 &= ~(0x3 << 14); // Clear P1.23 LPC_PINCON->PINSEL4 &= ~(0xF << 0); // P2.0-P2.1 as GPIO
LPC_PINCON->PINSEL4 &= ~(0xF << 0); // Clear P2.0-P2.1
// === GPIO DIRECTION SETUP === // === GPIO SETUP ===
LPC_GPIO0->FIODIR |= LED_MASK; // P0.4-P0.11: LEDs (output) LPC_GPIO0->FIODIR |= LED_MASK; // LEDs output
LPC_GPIO0->FIODIR |= COL_MASK_P0; // Keypad columns (output) LPC_GPIO0->FIODIR |= COL_MASK_P0; // Columns output
LPC_GPIO2->FIODIR |= COL_MASK_P2; // Keypad columns (output) LPC_GPIO2->FIODIR |= COL_MASK_P2; // Columns output
LPC_GPIO0->FIODIR &= ~ROW0; // Row-0 (input) LPC_GPIO0->FIODIR &= ~ROW0; // Row input
// === INITIALIZE GPIO === // Initialize
LPC_GPIO0->FIOCLR = LED_MASK; // All LEDs off initially LPC_GPIO0->FIOCLR = LED_MASK;
LPC_GPIO2->FIOSET = COL_MASK_P2; // Columns high LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0; // Columns high LPC_GPIO0->FIOSET = COL_MASK_P0;
// === PWM CONFIGURATION === // === HIGH-SPEED PWM CONFIGURATION ===
LPC_SC->PCONP |= (1 << 6); // Power on PWM1 LPC_SC->PCONP |= (1 << 6); // Power on PWM1
LPC_PWM1->TCR = (1 << 1); // Reset PWM LPC_PWM1->TCR = (1 << 1); // Reset
LPC_PWM1->CTCR = 0; // Timer mode LPC_PWM1->CTCR = 0; // Timer mode
LPC_PWM1->PR = 99; // Prescaler: divide by 100 LPC_PWM1->PR = 9; // Prescaler = 10
// Creates ~10kHz interrupt rate // 100MHz / 10 = 10MHz timer clock
LPC_PWM1->MR0 = PWM_PERIOD; // PWM period = 100 LPC_PWM1->MR0 = 100; // Match every 100 ticks
LPC_PWM1->MR4 = 0; // Duty cycle = 0 // Interrupt rate = 10MHz/100 = 100kHz
// PWM frequency = 100kHz/100 = 1kHz
// NO VISIBLE FLICKER!
LPC_PWM1->MCR = (1 << 1) | (1 << 0); // Reset on MR0, interrupt enabled LPC_PWM1->MCR = (1 << 1) | (1 << 0); // Reset on MR0 + interrupt
LPC_PWM1->LER = (1 << 0); // Latch MR0 LPC_PWM1->LER = (1 << 0); // Latch MR0
NVIC_EnableIRQ(PWM1_IRQn); // Enable PWM interrupt NVIC_EnableIRQ(PWM1_IRQn); // Enable interrupt
NVIC_SetPriority(PWM1_IRQn, 0); // Highest priority NVIC_SetPriority(PWM1_IRQn, 0); // Highest priority
LPC_PWM1->TCR = (1 << 0) | (1 << 3); // Enable PWM and counter LPC_PWM1->TCR = (1 << 0) | (1 << 3); // Start PWM
// Initial duty cycle: 10%
duty_cycle = 10;
// === MAIN LOOP === // === MAIN LOOP ===
while(1) while(1)
{ {
unsigned int read_key = 0xFF; read_key = 0xFF;
// Scan ROW-0 (keys 0, 1, 2, 3) // Scan ROW-0 only
for(col_idx = 0; col_idx < 4; col_idx++) for(col_idx = 0; col_idx < 4; col_idx++)
{ {
set_column(col_idx); set_column(col_idx);
short_delay(500); delay_ms(5); // Short delay for stable reading
if(is_row0_pressed()) { if(is_row0_pressed()) {
read_key = col_idx; read_key = col_idx; // Key 0, 1, 2, or 3
// Wait for key release
while(is_row0_pressed()) {
delay_ms(10);
}
break; break;
} }
} }
@ -131,30 +132,18 @@ int main(void)
LPC_GPIO2->FIOSET = COL_MASK_P2; LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0; LPC_GPIO0->FIOSET = COL_MASK_P0;
// Debounce // Update brightness immediately on key press
if(read_key == candidate_key) { if(read_key != 0xFF && read_key != last_key) {
if(stable < 5) stable++; last_key = read_key;
} else {
candidate_key = read_key;
stable = 1;
}
// Update intensity when stable switch(read_key) {
if(stable >= 5) { case 0: duty_cycle = 10; break; // 10%
if(candidate_key != last_key && candidate_key != 0xFF) { case 1: duty_cycle = 25; break; // 25%
last_key = candidate_key; case 2: duty_cycle = 50; break; // 50%
case 3: duty_cycle = 75; break; // 75%
// Set duty cycle (out of 100)
switch(candidate_key) {
case 0: duty_cycle = 10; break; // 10%
case 1: duty_cycle = 25; break; // 25%
case 2: duty_cycle = 50; break; // 50%
case 3: duty_cycle = 75; break; // 75%
}
} }
stable = 5;
} }
short_delay(5000); delay_ms(50); // Main loop delay
} }
} }