diff --git a/ES/Lab/Lab11/PWM.c b/ES/Lab/Lab11/PWM.c index e1e2325..b38bf18 100644 --- a/ES/Lab/Lab11/PWM.c +++ b/ES/Lab/Lab11/PWM.c @@ -1,57 +1,77 @@ #include "LPC17xx.h" -unsigned long int duty_cycle = 0; -int direction = 1; -int step = 50; +// Global variables for PWM control +unsigned long int duty_cycle = 0; // Current duty cycle value (0-3000) +int direction = 1; // Direction of duty cycle change: 1=increasing, 0=decreasing +int step = 50; // Amount to change duty cycle per interrupt +// PWM1 Interrupt Service Routine +// Called when PWM match register 0 triggers an interrupt void PWM1_IRQHandler(void) { + // Check if interrupt flag for PWM match channel 0 is set if (LPC_PWM1->IR & (1 << 0)) { + // Ramp up the duty cycle if direction is 1 if (direction == 1) { duty_cycle += step; + // Check if we've reached maximum duty cycle if (duty_cycle >= 3000) { duty_cycle = 3000; - direction = 0; + direction = 0; // Change direction to decreasing } } + // Ramp down the duty cycle if direction is 0 else { duty_cycle -= step; + // Check if we've reached minimum duty cycle if (duty_cycle <= 0) { duty_cycle = 0; - direction = 1; + direction = 1; // Change direction to increasing } } + // Update PWM match register 4 with new duty cycle LPC_PWM1->MR4 = duty_cycle; + // Latch the new match value LPC_PWM1->LER = (1 << 4); + // Clear the interrupt flag for channel 0 LPC_PWM1->IR = (1 << 0); } } int main(void) { + // Configure P2.5 as PWM1[4] output + // PINSEL3 bits 15:14 = 10 for PWM1[4] function LPC_PINCON->PINSEL3 |= (2 << 14); - LPC_PWM1->TCR = (1 << 1); - LPC_PWM1->CTCR = 0; - LPC_PWM1->PR = 0; + // Reset and configure PWM1 counter and prescaler + LPC_PWM1->TCR = (1 << 1); // Reset PWM counter + LPC_PWM1->CTCR = 0; // Timer mode (counter increments on PCLK) + LPC_PWM1->PR = 0; // Prescaler = 0 (no prescaling) - LPC_PWM1->MR0 = 3000; - LPC_PWM1->MR4 = duty_cycle; + // Set PWM cycle period and initial duty cycle + LPC_PWM1->MR0 = 3000; // PWM period (match register 0) + LPC_PWM1->MR4 = duty_cycle; // Initial duty cycle (match register 4) - LPC_PWM1->MCR = (1 << 1) | (1 << 0); - LPC_PWM1->PCR = (1 << 12); + // Configure PWM interrupts and enable output + LPC_PWM1->MCR = (1 << 1) | (1 << 0); // Reset on MR0 and interrupt on MR0 + LPC_PWM1->PCR = (1 << 12); // Enable PWM4 output + // Latch the match register values LPC_PWM1->LER = (1 << 0) | (1 << 4); + // Enable PWM1 interrupt in NVIC NVIC_EnableIRQ(PWM1_IRQn); - LPC_PWM1->TCR = (1 << 0) | (1 << 3); + // Start PWM counter and enable PWM mode + LPC_PWM1->TCR = (1 << 0) | (1 << 3); // Counter enable and PWM enable + // Infinite loop - everything is handled by interrupts while (1); } diff --git a/ES/Lab/Lab11/PWM_Keyboard.c b/ES/Lab/Lab11/PWM_Keyboard.c index 741dbb9..1147de6 100644 --- a/ES/Lab/Lab11/PWM_Keyboard.c +++ b/ES/Lab/Lab11/PWM_Keyboard.c @@ -3,107 +3,59 @@ unsigned long pwm_value = 0; void PWM_Init(void){ - LPC_PINCON->PINSEL3 |= 0x02 << 8; - LPC_SC->PCONP |= 1 << 6; - LPC_PWM1->PR = 0; - LPC_PWM1->CTCR = 0; - LPC_PWM1->MR0 = 1000; - LPC_PWM1->MR2 = 500; - LPC_PWM1->LER = 0x05; - LPC_PWM1->PCR = 1 << 10; - LPC_PWM1->TCR = 0x09; - NVIC_EnableIRQ(PWM1_IRQn); + LPC_PINCON->PINSEL3 |= 0x02 << 8; + LPC_SC->PCONP |= 1 << 6; + LPC_PWM1->PR = 0; + LPC_PWM1->CTCR = 0; + LPC_PWM1->MR0 = 1000; + LPC_PWM1->MR2 = 500; + LPC_PWM1->LER = 0x05; + LPC_PWM1->PCR = 1 << 10; + LPC_PWM1->TCR = 0x09; + NVIC_EnableIRQ(PWM1_IRQn); } void Keyboard_Init(void){ - LPC_PINCON->PINSEL0 &= ~(0x03 << 0); - LPC_PINCON->PINSEL0 &= ~(0x03 << 2); - LPC_PINCON->PINSEL0 &= ~(0x03 << 4); - LPC_PINCON->PINSEL0 &= ~(0x03 << 6); - - LPC_GPIO0->FIODIR &= ~(0x0F << 0); + LPC_PINCON->PINSEL0 &= ~0x0FFF; + LPC_GPIO0->FIODIR &= ~0x0F; } void Delay(unsigned long count){ - unsigned long i; - for(i = 0; i < count; i++); + for(unsigned long i = 0; i < count; i++); } unsigned char Read_Keyboard(void){ - unsigned char key = 0xFF; - - if(!(LPC_GPIO0->FIOPIN & (1 << 0))){ + for(unsigned char i = 0; i < 4; i++){ + if(!(LPC_GPIO0->FIOPIN & (1 << i))){ + Delay(500000); + if(!(LPC_GPIO0->FIOPIN & (1 << i))){ + while(!(LPC_GPIO0->FIOPIN & (1 << i))); Delay(500000); - if(!(LPC_GPIO0->FIOPIN & (1 << 0))){ - key = 0; - while(!(LPC_GPIO0->FIOPIN & (1 << 0))); - Delay(500000); - } + return i; + } } - else if(!(LPC_GPIO0->FIOPIN & (1 << 1))){ - Delay(500000); - if(!(LPC_GPIO0->FIOPIN & (1 << 1))){ - key = 1; - while(!(LPC_GPIO0->FIOPIN & (1 << 1))); - Delay(500000); - } - } - else if(!(LPC_GPIO0->FIOPIN & (1 << 2))){ - Delay(500000); - if(!(LPC_GPIO0->FIOPIN & (1 << 2))){ - key = 2; - while(!(LPC_GPIO0->FIOPIN & (1 << 2))); - Delay(500000); - } - } - else if(!(LPC_GPIO0->FIOPIN & (1 << 3))){ - Delay(500000); - if(!(LPC_GPIO0->FIOPIN & (1 << 3))){ - key = 3; - while(!(LPC_GPIO0->FIOPIN & (1 << 3))); - Delay(500000); - } - } - - return key; + } + return 0xFF; } int main(void){ - unsigned char key; + unsigned char key; + const unsigned long pwm_values[] = {100, 250, 500, 750}; - PWM_Init(); - Keyboard_Init(); + PWM_Init(); + Keyboard_Init(); - while(1){ - key = Read_Keyboard(); - - switch(key){ - case 0: - pwm_value = 100; - LPC_PWM1->MR2 = pwm_value; - break; - case 1: - pwm_value = 250; - LPC_PWM1->MR2 = pwm_value; - break; - case 2: - pwm_value = 500; - LPC_PWM1->MR2 = pwm_value; - break; - case 3: - pwm_value = 750; - LPC_PWM1->MR2 = pwm_value; - break; - default: - break; - } - - LPC_PWM1->LER |= 0x04; + while(1){ + key = Read_Keyboard(); + if(key < 4){ + LPC_PWM1->MR2 = pwm_values[key]; + LPC_PWM1->LER |= 0x04; } + } - return 0; + return 0; } void PWM1_IRQHandler(void){ - LPC_PWM1->IR |= 0x01; + LPC_PWM1->IR |= 0x01; }