Let's say you have 4 outputs for starters, PB0 needs 80% duty cycle, PB1 50%, PB2 10%, and PB3 100% (always on). So you have to output the following sequence of bits repeated on each pin (of course you can shift the phase too by shifting the bits around)
PB0 1111111100
PB1 1111100000
PB2 1000000000
PB3 1111111111turn the above table 90 degrees clockwise, you get a list of binary numbers
uint16_t pb_pattern = {
0b1111,
0b1011,
0b1011,
0b1011,
0b1011,
0b1001,
0b1001,
0b1001,
0b1000,
0b1000
};This is just a simplified example, you can use full 16 bit values to output on PB0-PB15 simultaneously.
Now you can set up a timer to 10 times the PWM frequency, and a DMA channel that transfers 10 halfwords in circular mode from the buffer above to GPIOB->ODR, on each timer period. If more than 10% precision is needed, use a longer table and adjust the timer period.
It can then be extended to more GPIO banks, using more timer and DMA channels, for 32, 48, etc PWM signals.
It might even be possible to do it on the controlling MCU if there are enough pins and RAM available, maybe replacing it with a 144-pin STM32F103 variant with some more RAM.
If the two MCUs have to be separate, calculate the memory requirements based on the required PWM precision, and chose the cheapest MCU that has enough pins and RAM.
Enter your E-mail address. We'll send you an e-mail with instructions to reset your password.
