PWM Disp
This commit is contained in:
parent
161a7b1ee3
commit
d783943935
2 changed files with 201 additions and 42 deletions
|
|
@ -1,70 +1,158 @@
|
|||
#include "LPC17xx.h"
|
||||
#include <stdio.h>
|
||||
|
||||
// PWM variables
|
||||
unsigned long int duty_cycle = 0;
|
||||
unsigned long int new_duty = 0;
|
||||
int press_count = 0;
|
||||
unsigned long int pwm_counter = 0;
|
||||
|
||||
void delayMs(unsigned int ms)
|
||||
{
|
||||
unsigned int i, j;
|
||||
for (i = 0; i < ms; i++)
|
||||
for (j = 0; j < 20000; j++);
|
||||
// Pin definitions based on connectors
|
||||
#define LED_SHIFT 4 // CNA: P0.4-P0.11 (8 LEDs)
|
||||
#define LED_MASK (0xFF << LED_SHIFT)
|
||||
|
||||
// Keypad on CND - Only ROW-0
|
||||
#define COL0 (1<<0) // P2.0
|
||||
#define COL1 (1<<1) // P2.1
|
||||
#define COL2 (1<<23) // P0.23
|
||||
#define COL3 (1<<24) // P0.24
|
||||
#define ROW0 (1<<25) // P0.25 (ROW-0 only)
|
||||
|
||||
#define COL_MASK_P0 (COL2 | COL3)
|
||||
#define COL_MASK_P2 (COL0 | COL1)
|
||||
|
||||
static void short_delay(volatile unsigned int d) {
|
||||
while(d--) __NOP();
|
||||
}
|
||||
|
||||
// Set a specific column low, others high
|
||||
static void set_column(unsigned int col)
|
||||
{
|
||||
// Set all columns high first
|
||||
LPC_GPIO2->FIOSET = COL_MASK_P2;
|
||||
LPC_GPIO0->FIOSET = COL_MASK_P0;
|
||||
|
||||
// Pull specific column low
|
||||
switch(col) {
|
||||
case 0: LPC_GPIO2->FIOCLR = COL0; break;
|
||||
case 1: LPC_GPIO2->FIOCLR = COL1; break;
|
||||
case 2: LPC_GPIO0->FIOCLR = COL2; break;
|
||||
case 3: LPC_GPIO0->FIOCLR = COL3; break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if ROW-0 is pressed
|
||||
static unsigned int is_row0_pressed(void)
|
||||
{
|
||||
return !(LPC_GPIO0->FIOPIN & ROW0);
|
||||
}
|
||||
|
||||
// PWM Interrupt Handler
|
||||
void PWM1_IRQHandler(void)
|
||||
{
|
||||
if (LPC_PWM1->IR & (1 << 0))
|
||||
{
|
||||
LPC_PWM1->MR4 = new_duty;
|
||||
LPC_PWM1->LER = (1 << 4);
|
||||
LPC_PWM1->IR = (1 << 0);
|
||||
// Software PWM for LEDs (CNA: P0.4-P0.11)
|
||||
pwm_counter++;
|
||||
if(pwm_counter >= 3000) pwm_counter = 0;
|
||||
|
||||
if(pwm_counter < duty_cycle)
|
||||
LPC_GPIO0->FIOSET = LED_MASK; // LEDs ON
|
||||
else
|
||||
LPC_GPIO0->FIOCLR = LED_MASK; // LEDs OFF
|
||||
|
||||
LPC_PWM1->IR = (1 << 0); // Clear interrupt
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
char key;
|
||||
unsigned int col_idx;
|
||||
unsigned int candidate_key = 0xFF;
|
||||
unsigned int stable = 0;
|
||||
unsigned int last_key = 0xFF;
|
||||
|
||||
LPC_PINCON->PINSEL3 |= (2 << 14);
|
||||
LPC_PWM1->TCR = (1 << 1);
|
||||
LPC_PWM1->CTCR = 0x00;
|
||||
LPC_PWM1->PR = 0;
|
||||
LPC_PWM1->MR0 = 3000;
|
||||
LPC_PWM1->MR4 = duty_cycle;
|
||||
LPC_PWM1->MCR = (1 << 1) | (1 << 0);
|
||||
LPC_PWM1->PCR = (1 << 12);
|
||||
LPC_PWM1->LER = (1 << 0) | (1 << 4);
|
||||
// === PIN CONFIGURATION ===
|
||||
LPC_PINCON->PINSEL0 = 0x00000000; // All GPIO
|
||||
LPC_PINCON->PINSEL1 = 0x00000000;
|
||||
LPC_PINCON->PINSEL3 = (2 << 14); // PWM1.4 on P1.23 (optional)
|
||||
LPC_PINCON->PINSEL4 = 0x00000000;
|
||||
|
||||
NVIC_EnableIRQ(PWM1_IRQn);
|
||||
// === GPIO DIRECTION SETUP ===
|
||||
// CNA: LEDs (P0.4-P0.11)
|
||||
LPC_GPIO0->FIODIR |= LED_MASK;
|
||||
|
||||
LPC_PWM1->TCR = (1 << 0) | (1 << 3);
|
||||
// CND: Keypad - Columns output, Row-0 input
|
||||
LPC_GPIO0->FIODIR |= COL_MASK_P0; // Columns (output)
|
||||
LPC_GPIO2->FIODIR |= COL_MASK_P2; // Columns (output)
|
||||
LPC_GPIO0->FIODIR &= ~ROW0; // Row-0 (input)
|
||||
|
||||
printf("Press any key to change brightness...\n");
|
||||
// === INITIALIZE GPIO STATES ===
|
||||
LPC_GPIO0->FIOCLR = LED_MASK; // LEDs off
|
||||
LPC_GPIO2->FIOSET = COL_MASK_P2; // Columns high (idle)
|
||||
LPC_GPIO0->FIOSET = COL_MASK_P0; // Columns high (idle)
|
||||
|
||||
while (1)
|
||||
// === PWM CONFIGURATION ===
|
||||
LPC_PWM1->TCR = (1 << 1); // Reset PWM
|
||||
LPC_PWM1->CTCR = 0; // Timer mode
|
||||
LPC_PWM1->PR = 0; // No prescaler
|
||||
|
||||
LPC_PWM1->MR0 = 3000; // PWM period = 3000
|
||||
LPC_PWM1->MR4 = duty_cycle; // Initial duty cycle = 0
|
||||
|
||||
LPC_PWM1->MCR = (1 << 1) | (1 << 0); // Reset and interrupt on MR0
|
||||
LPC_PWM1->PCR = (1 << 12); // Enable PWM4 output
|
||||
LPC_PWM1->LER = (1 << 0) | (1 << 4); // Latch MR0 and MR4
|
||||
|
||||
NVIC_EnableIRQ(PWM1_IRQn); // Enable PWM interrupt
|
||||
|
||||
LPC_PWM1->TCR = (1 << 0) | (1 << 3); // Enable counter and PWM
|
||||
|
||||
// === MAIN LOOP ===
|
||||
while(1)
|
||||
{
|
||||
key = getchar();
|
||||
unsigned int read_key = 0xFF;
|
||||
|
||||
if (key)
|
||||
// Scan ROW-0 only (columns 0-3 = keys 0, 1, 2, 3)
|
||||
for(col_idx = 0; col_idx < 4; col_idx++)
|
||||
{
|
||||
press_count++;
|
||||
set_column(col_idx);
|
||||
short_delay(200);
|
||||
|
||||
if (press_count == 1)
|
||||
new_duty = 300;
|
||||
else if (press_count == 2)
|
||||
new_duty = 1500;
|
||||
else if (press_count == 3)
|
||||
new_duty = 2700;
|
||||
else
|
||||
{
|
||||
new_duty = 0;
|
||||
press_count = 0;
|
||||
if(is_row0_pressed()) {
|
||||
read_key = col_idx; // Key 0, 1, 2, or 3
|
||||
break;
|
||||
}
|
||||
|
||||
printf("Duty cycle set to %lu\r\n", new_duty);
|
||||
|
||||
delayMs(500);
|
||||
}
|
||||
|
||||
// Restore all columns high
|
||||
LPC_GPIO2->FIOSET = COL_MASK_P2;
|
||||
LPC_GPIO0->FIOSET = COL_MASK_P0;
|
||||
|
||||
// Debounce logic
|
||||
if(read_key == candidate_key) {
|
||||
if(stable < 3) stable++;
|
||||
} else {
|
||||
candidate_key = read_key;
|
||||
stable = 1;
|
||||
}
|
||||
|
||||
// Update intensity when key is stable and changed
|
||||
if(stable >= 3) {
|
||||
if(candidate_key != last_key && candidate_key != 0xFF) {
|
||||
last_key = candidate_key;
|
||||
|
||||
// Set duty cycle based on key pressed
|
||||
switch(candidate_key) {
|
||||
case 0: duty_cycle = 300; break; // 10% of 3000
|
||||
case 1: duty_cycle = 750; break; // 25% of 3000
|
||||
case 2: duty_cycle = 1500; break; // 50% of 3000
|
||||
case 3: duty_cycle = 2250; break; // 75% of 3000
|
||||
}
|
||||
|
||||
LPC_PWM1->MR4 = duty_cycle;
|
||||
LPC_PWM1->LER = (1 << 4);
|
||||
}
|
||||
stable = 3;
|
||||
}
|
||||
|
||||
short_delay(2000);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue