From 21067f5f4c7cf8ed5874f8d662abb22b2ca9e230 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?King=20K=C3=A9vin?= Date: Tue, 11 Oct 2022 19:06:28 +0200 Subject: [PATCH] main: control RGB LED using PWM --- main.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 2 deletions(-) diff --git a/main.c b/main.c index 5a90b4a..4a9287d 100644 --- a/main.c +++ b/main.c @@ -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