STM32 Crazy Mystery
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