This commit is contained in:
sherlock 2025-10-30 09:22:28 +05:30
parent a2d3f71108
commit 5c427867cd
2 changed files with 67 additions and 95 deletions

View file

@ -1,57 +1,77 @@
#include "LPC17xx.h" #include "LPC17xx.h"
unsigned long int duty_cycle = 0; // Global variables for PWM control
int direction = 1; unsigned long int duty_cycle = 0; // Current duty cycle value (0-3000)
int step = 50; 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) void PWM1_IRQHandler(void)
{ {
// Check if interrupt flag for PWM match channel 0 is set
if (LPC_PWM1->IR & (1 << 0)) if (LPC_PWM1->IR & (1 << 0))
{ {
// Ramp up the duty cycle if direction is 1
if (direction == 1) if (direction == 1)
{ {
duty_cycle += step; duty_cycle += step;
// Check if we've reached maximum duty cycle
if (duty_cycle >= 3000) if (duty_cycle >= 3000)
{ {
duty_cycle = 3000; duty_cycle = 3000;
direction = 0; direction = 0; // Change direction to decreasing
} }
} }
// Ramp down the duty cycle if direction is 0
else else
{ {
duty_cycle -= step; duty_cycle -= step;
// Check if we've reached minimum duty cycle
if (duty_cycle <= 0) if (duty_cycle <= 0)
{ {
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; LPC_PWM1->MR4 = duty_cycle;
// Latch the new match value
LPC_PWM1->LER = (1 << 4); LPC_PWM1->LER = (1 << 4);
// Clear the interrupt flag for channel 0
LPC_PWM1->IR = (1 << 0); LPC_PWM1->IR = (1 << 0);
} }
} }
int main(void) 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_PINCON->PINSEL3 |= (2 << 14);
LPC_PWM1->TCR = (1 << 1); // Reset and configure PWM1 counter and prescaler
LPC_PWM1->CTCR = 0; LPC_PWM1->TCR = (1 << 1); // Reset PWM counter
LPC_PWM1->PR = 0; LPC_PWM1->CTCR = 0; // Timer mode (counter increments on PCLK)
LPC_PWM1->PR = 0; // Prescaler = 0 (no prescaling)
LPC_PWM1->MR0 = 3000; // Set PWM cycle period and initial duty cycle
LPC_PWM1->MR4 = 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); // Configure PWM interrupts and enable output
LPC_PWM1->PCR = (1 << 12); 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); LPC_PWM1->LER = (1 << 0) | (1 << 4);
// Enable PWM1 interrupt in NVIC
NVIC_EnableIRQ(PWM1_IRQn); 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); while (1);
} }

View file

@ -3,107 +3,59 @@
unsigned long pwm_value = 0; unsigned long pwm_value = 0;
void PWM_Init(void){ void PWM_Init(void){
LPC_PINCON->PINSEL3 |= 0x02 << 8; LPC_PINCON->PINSEL3 |= 0x02 << 8;
LPC_SC->PCONP |= 1 << 6; LPC_SC->PCONP |= 1 << 6;
LPC_PWM1->PR = 0; LPC_PWM1->PR = 0;
LPC_PWM1->CTCR = 0; LPC_PWM1->CTCR = 0;
LPC_PWM1->MR0 = 1000; LPC_PWM1->MR0 = 1000;
LPC_PWM1->MR2 = 500; LPC_PWM1->MR2 = 500;
LPC_PWM1->LER = 0x05; LPC_PWM1->LER = 0x05;
LPC_PWM1->PCR = 1 << 10; LPC_PWM1->PCR = 1 << 10;
LPC_PWM1->TCR = 0x09; LPC_PWM1->TCR = 0x09;
NVIC_EnableIRQ(PWM1_IRQn); NVIC_EnableIRQ(PWM1_IRQn);
} }
void Keyboard_Init(void){ void Keyboard_Init(void){
LPC_PINCON->PINSEL0 &= ~(0x03 << 0); LPC_PINCON->PINSEL0 &= ~0x0FFF;
LPC_PINCON->PINSEL0 &= ~(0x03 << 2); LPC_GPIO0->FIODIR &= ~0x0F;
LPC_PINCON->PINSEL0 &= ~(0x03 << 4);
LPC_PINCON->PINSEL0 &= ~(0x03 << 6);
LPC_GPIO0->FIODIR &= ~(0x0F << 0);
} }
void Delay(unsigned long count){ void Delay(unsigned long count){
unsigned long i; for(unsigned long i = 0; i < count; i++);
for(i = 0; i < count; i++);
} }
unsigned char Read_Keyboard(void){ unsigned char Read_Keyboard(void){
unsigned char key = 0xFF; for(unsigned char i = 0; i < 4; i++){
if(!(LPC_GPIO0->FIOPIN & (1 << i))){
if(!(LPC_GPIO0->FIOPIN & (1 << 0))){ Delay(500000);
if(!(LPC_GPIO0->FIOPIN & (1 << i))){
while(!(LPC_GPIO0->FIOPIN & (1 << i)));
Delay(500000); Delay(500000);
if(!(LPC_GPIO0->FIOPIN & (1 << 0))){ return i;
key = 0; }
while(!(LPC_GPIO0->FIOPIN & (1 << 0)));
Delay(500000);
}
} }
else if(!(LPC_GPIO0->FIOPIN & (1 << 1))){ }
Delay(500000); return 0xFF;
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;
} }
int main(void){ int main(void){
unsigned char key; unsigned char key;
const unsigned long pwm_values[] = {100, 250, 500, 750};
PWM_Init(); PWM_Init();
Keyboard_Init(); Keyboard_Init();
while(1){ while(1){
key = Read_Keyboard(); key = Read_Keyboard();
if(key < 4){
switch(key){ LPC_PWM1->MR2 = pwm_values[key];
case 0: LPC_PWM1->LER |= 0x04;
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;
} }
}
return 0; return 0;
} }
void PWM1_IRQHandler(void){ void PWM1_IRQHandler(void){
LPC_PWM1->IR |= 0x01; LPC_PWM1->IR |= 0x01;
} }