MIT-Curricular/ES/Lab/Lab11/PWM_Keyboard.c
2025-10-23 13:06:11 +05:30

125 lines
2.8 KiB
C

#include "LPC17xx.h"
volatile unsigned long int duty_cycle = 300;
volatile unsigned long int pwm_counter = 0;
#define LED_MASK (0xFF << 4)
#define COL0 (1<<0)
#define COL1 (1<<1)
#define COL2 (1<<23)
#define COL3 (1<<24)
#define ROW0 (1<<25)
#define COL_MASK_P0 (COL2 | COL3)
#define COL_MASK_P2 (COL0 | COL1)
static void delay_ms(unsigned int ms) {
unsigned int i, j;
for(i = 0; i < ms; i++)
for(j = 0; j < 10000; j++);
}
static void set_column(unsigned int col)
{
LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0;
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;
}
}
static unsigned int is_row0_pressed(void)
{
return !(LPC_GPIO0->FIOPIN & ROW0);
}
void PWM1_IRQHandler(void)
{
if (LPC_PWM1->IR & (1 << 0))
{
if(pwm_counter < duty_cycle)
LPC_GPIO0->FIOSET = LED_MASK;
else
LPC_GPIO0->FIOCLR = LED_MASK;
pwm_counter++;
if(pwm_counter >= 3000)
pwm_counter = 0;
LPC_PWM1->IR = (1 << 0);
}
}
int main(void)
{
unsigned int col_idx;
unsigned int read_key;
unsigned int last_key = 0xFF;
LPC_PINCON->PINSEL0 &= ~(0xFFFF << 8);
LPC_PINCON->PINSEL1 &= ~(0xFFFF << 14);
LPC_PINCON->PINSEL4 &= ~(0xF << 0);
LPC_GPIO0->FIODIR |= LED_MASK;
LPC_GPIO0->FIODIR |= COL_MASK_P0;
LPC_GPIO2->FIODIR |= COL_MASK_P2;
LPC_GPIO0->FIODIR &= ~ROW0;
LPC_GPIO0->FIOCLR = LED_MASK;
LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0;
LPC_PWM1->TCR = (1 << 1);
LPC_PWM1->CTCR = 0;
LPC_PWM1->PR = 0;
LPC_PWM1->MR0 = 3000;
LPC_PWM1->MCR = (1 << 1) | (1 << 0);
LPC_PWM1->LER = (1 << 0);
NVIC_EnableIRQ(PWM1_IRQn);
NVIC_SetPriority(PWM1_IRQn, 0);
LPC_PWM1->TCR = (1 << 0) | (1 << 3);
while(1)
{
read_key = 0xFF;
for(col_idx = 0; col_idx < 4; col_idx++)
{
set_column(col_idx);
delay_ms(5);
if(is_row0_pressed()) {
read_key = col_idx;
while(is_row0_pressed()) {
delay_ms(10);
}
break;
}
}
LPC_GPIO2->FIOSET = COL_MASK_P2;
LPC_GPIO0->FIOSET = COL_MASK_P0;
if(read_key != 0xFF && read_key != last_key) {
last_key = read_key;
switch(read_key) {
case 0: duty_cycle = 300; break;
case 1: duty_cycle = 750; break;
case 2: duty_cycle = 1500; break;
case 3: duty_cycle = 2250; break;
}
}
delay_ms(50);
}
}