main: control RGB LED using PWM

This commit is contained in:
King Kévin 2022-10-11 19:06:28 +02:00
parent 75fb553172
commit 21067f5f4c
1 changed files with 48 additions and 2 deletions

50
main.c
View File

@ -87,6 +87,27 @@ void puth(uint8_t h)
putn(h & 0x0f);
}
// set duty cycle of red LED
void led_red(uint16_t bightness)
{
TIM2->CCR2H.reg = (bightness >> 8); // set duty cycle
TIM2->CCR2L.reg = (bightness >> 0); // set duty cycle
}
// set duty cycle of green LED
void led_green(uint16_t bightness)
{
TIM2->CCR3H.reg = (bightness >> 8); // set duty cycle
TIM2->CCR3L.reg = (bightness >> 0); // set duty cycle
}
// set duty cycle of blue LED
void led_blue(uint16_t bightness)
{
TIM2->CCR1H.reg = (bightness >> 8); // set duty cycle
TIM2->CCR1L.reg = (bightness >> 0); // set duty cycle
}
void main(void)
{
sim(); // disable interrupts (while we reconfigure them)
@ -127,7 +148,8 @@ void main(void)
IRM_ON_PORT->CR1.reg |= IRM_ON_PIN; // use as push-pull
IRM_ON_PORT->DDR.reg |= IRM_ON_PIN; // switch pin to output
// configure RGB LED
/* use PWM instead of GPIO for controlling RGB LED
LED_RED_PORT->ODR.reg &= ~LED_RED_PIN; // switch LED off
LED_RED_PORT->CR1.reg |= LED_RED_PIN; // use as push-pull
LED_RED_PORT->DDR.reg |= LED_RED_PIN; // use pin to output
@ -137,6 +159,26 @@ void main(void)
LED_BLUE_PORT->ODR.reg &= ~LED_BLUE_PIN; // switch LED off
LED_BLUE_PORT->CR1.reg |= LED_BLUE_PIN; // use as push-pull
LED_BLUE_PORT->DDR.reg |= LED_BLUE_PIN; // use pin to output
*/
// configure timer 2 for PWM-controlling RGB LED
TIM2->PSCR.fields.PSC = 0; // set prescaler to to 244 Hz, 16E6/(2**0)/65536 = 244 Hz
TIM2->ARRH.reg = 0xff; // set period to max for most precisions
TIM2->ARRL.reg = 0xff; // set period to max for most precisions
TIM2->CCMR1.output_fields.OC1M = 6; // set PWM1 mode
TIM2->CCMR1.output_fields.CC1S = 0; // use channel as output
TIM2->CCER1.fields.CC1E = 1; // enable channel output
led_blue(0); // switch off blue LED
TIM2->CCMR2.output_fields.OC2M = 6; // set PWM1 mode
TIM2->CCMR2.output_fields.CC2S = 0; // use channel as output
TIM2->CCER1.fields.CC2E = 1; // enable channel output
led_red(0); // switch off red LED
TIM2->CCMR3.output_fields.OC3M = 6; // set PWM1 mode
TIM2->CCMR3.output_fields.CC3S = 0; // use channel as output
TIM2->CCER2.fields.CC3E = 1; // enable channel output
led_green(0); // switch off green LED
TIM2->EGR.fields.UG = 1; // transfer all registers
TIM2->CR1.fields.CEN = 1; // enable counter to start PWM
/*
// configure IR LED
@ -201,7 +243,8 @@ void main(void)
rim(); // re-enable interrupts
bool action = false; // if an action has been performed
puts("ready\r\n");
led_green(0x0100); // indicate we are ready
puts("\r\nready\r\n");
while (true) {
putc('.');
IWDG_KR = IWDG_KR_KEY_REFRESH; // reset watchdog
@ -214,6 +257,9 @@ void main(void)
if (time_count > 488 * 10) {
puts("10s\r\n");
time_count = 0; // reset counter
led_red(0); // ensure LED is off
led_green(0); // ensure LED is off
led_blue(0); // ensure LED is off
halt();
}
if (action) { // something has been performed, check if other flags have been set meanwhile