Difference between revisions of "STM32 Crazy Mystery"

From Stm32World Wiki
Jump to navigation Jump to search
Line 7: Line 7:
  
 
== What works (STM32F411 - [[Black Pill]]) ==
 
== 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:
 +
 +
<pre>
 +
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;
 +
    }
 +
 +
}
 +
</pre>
 +
 +
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 https://github.com/lbthomsen/blackpill/tree/master/bitbang_pwm]

Revision as of 07:25, 16 October 2024

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