2026-02-05 10:06 AM
hello everybody
I am programming 10 addressable Leds with PWM with DMA using the M7 cortex of an STM32H747 in a custom board.
Characteristics:
If I run the timer alone (fixed duty), the PWM is correct and stable.
When I enable PWM + DMA, the waveform becomes random/discontinuous. On the oscilloscope I see “splits” and gaps; the PWM is not continuous. For example, the first 8 bits might be high and the following 16 low (intended to represent RED), but the stream breaks unpredictably. The data buffer looks correct when inspected in the debugger.
I am using channel 4 timer 3. with internal clock source.
and DMA is configured as:
where data width is half word since the pulse of the PWM generator channel 4 is 16 bit value.
Here is my code. All IRQs are activated.
#define NUMTOTALLEDS 10
#define NUMCOLORS 24 //< 8 BYTESxCOLOUR
#define STARTSAFEBUFFER 50
#define ENDSAFEBUFFER 50
// Placed in RAM_D2
uint16_t pwmData[NUMCOLORS*NUMTOTALLEDS+STARTSAFEBUFFER+ENDSAFEBUFFER];
const
uint16_t ALLRED [340] = {
// Start safe buffer
PWM_RESET, PWM_RESET, PWM_RESET ...
// 8 bits high + 8 bits low + 8 bits low (Red, gren, blue)
PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_HIGH, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW, PWM_LOW,
// End safe buffer
... PWM_RESET, PWM_LOW, PWM_LOW};
// First of all i cpy a static buffer with all the information to fill 10 leds in red
memcpy(pwmData, ALLRED, sizeof(pwmData));
// Then
if (HAL_TIM_PWM_Start_DMA(&htim3, TIM_CHANNEL_4 , (uint32_t *)pwmData, sizeof(pwmData)) == HAL_OK) {
// It returns Ok always
}
// Callback
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_4);
}Everything is normal to me, but this is what my oscilloscope gets:
with zoom (the first 8 bits are high, and the 16 folowing are low, meaning red colour (RGB)):
My problem is that the PWM is random, and never correct.
What can I do?
Thanks in advance,
2026-02-05 10:37 AM
Hi,
Change in configuration in DMA for Memory from HalfWord to Byte. Do not change for Peripheral. Also change buffer pwmData and ALLRED from uint16_t to uint8_t.
Best Regards.
2026-02-05 10:54 AM
Yeah,
i tried so, however i do not why (maybe is a bug) both memory an peripheral must have the same length. I mean, the GUI forces the memory size to be equal to peripheral…
2026-02-05 10:59 AM
Hi,
Change in the generated code, not in GUI. Only for test.
2026-02-05 12:22 PM
1. Why don't you use UART or SPI - much less data required.
2. I don't use HAL, so I am not an expert there but I believe the size argument for HAT_PWM_Start_DMA should be the number of items rather than size in bytes.
3. When using PWM, make sure to add one more element to the table with a value of 0, so that timer output stays at 0 between packets.
4. Make sure that pwmData is a static object, not a function's local variable.
2026-02-05 12:28 PM
Thankyou.
do you know any examples using uart?
thanks ;)