STM32WB55 PMW LED control
Our laboratory board supports an RGB LED that can be controlled with a PWM signal. Red, Green and Blue LEDs are in the same enclosure but can be controlled separately. In the stm32duino examples 1), there is a simple program which allows us to control a single LED with PWM. It is named “All-in-one_setPWM” 2). It uses hardware timer output connected directly to an LED. The STM32WB55 microcontroller has two timer units built-in capable of generating PWM signals. One timer is connected to RGB LED, and another to the fan and servo. Not every pin can work as the timer output, so this example requires proper selection of the pin connected internally to the PWM timer output. On the laboratory board, the pins used are as presented in table 1.
| GPIO no | LED |
|---|---|
| D3 | Red LED |
| D6 | Green LED |
| D9 | Blue LED |
At the beginning of the code, there is a definition of pin value. Although the P-Nucleo-WB55 has the LED_BUILTIN defined it can't work as the PMW timer output. We have to override it.
// ********************************************************* #define LED_BUILTIN D6 //Override of the default LED_BUILTIN // ********************************************************* #if defined(LED_BUILTIN) #define pin LED_BUILTIN #else #define pin D2 #endif
In the setup part of the code, the program automatically retrieves the timer instance and PWM channel number connected to the previously defined pin.
TIM_TypeDef *Instance = (TIM_TypeDef *)pinmap_peripheral(digitalPinToPinName(pin), PinMap_PWM); uint32_t channel = STM_PIN_CHANNEL(pinmap_function(digitalPinToPinName(pin), PinMap_PWM));
While having information on the timer instance and channel number it instantiates the HardwareTimer object.
HardwareTimer *MyTim = new HardwareTimer(Instance);
The setup function oi finished with starting the timer to operate in PMW mode and configuring the PWM signal with frequency and duty cycle.
MyTim->setPWM(channel, pin, 5, 10); // 5 Hertz, 10% dutycycle
It is possible to modify the duty cycle by changing the current value of the capture and compare register for specified channel. To do it we need to use the function.
MyTim->setCaptureCompare(channel, 50, PERCENT_COMPARE_FORMAT); // 50%
