STM32 Crazy Mystery

From Stm32World Wiki
Revision as of 06:25, 16 October 2024 by Lth (talk | contribs)
Jump to navigation Jump to search

This page documents a bit of a mystery that I - so far - have been unable to solve.

Since PC13 is commonly used to drive an on-board LED on Development Boards and since PC13 is not connected to any timer channel, usually one can only toggle that LED on or off. A while back I was experimenting with bit banging PWM on this pin to be able to dim and pulse the led.

What works (STM32F411 - Black Pill)

The first attempt was done on a STM32F411 based Black Pill board and it worked flawlessly. The idea is to run a repeating timer, run an 8-bit counter in the timer callback and then toggle the GPIO on and off at an appropriate level within that range. In the working code that looks like:

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {

    if (htim->Instance == LED_PWM_TIM) {
        ++led_pwm_cnt; // The counter is 8 bit so will wrap around after 255

        // Use BSRR to set or reset bit 13 of the LED GPIO port
        LED_GPIO_Port->BSRR = led_pwm_cnt >= led_pwm_val ? GPIO_BSRR_BS13 : GPIO_BSRR_BR13;
    }

}

Extremely simple really. First check for the right timer, then increase a counter (which will roll around automatically as it is only an 8 bit variable) and finally set the BSRR register (set/reset register) of the appropriate port to an appropriate BS13 (set) or BR13 (reset) value.

The working example can be found here: https://github.com/lbthomsen/blackpill/tree/master/bitbang_pwm