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