通过示波器观察PWM+DMA的方式驱动WS2812灯珠的波形及分析对应的现象
文章目录
-
- 1. 在DMA传送完PWM波形后不关闭PWM的DMA输出
- 2. 在DMA传送完PWM波形后,在PWM传输完成后回调函数中关闭PWM的DMA输出
- 3. 在DMA传送完PWM波形后,在DMA中断函数中关闭PWM的DMA输出
- 分析
1. 在DMA传送完PWM波形后不关闭PWM的DMA输出
灯珠显示效果:
灯珠会错乱显示(没有按正常设定的颜色显示)
示波器显示如下:
2. 在DMA传送完PWM波形后,在PWM传输完成后回调函数中关闭PWM的DMA输出
灯珠显示效果:
会按照设定的颜色正常显示,但灯带的起始位置会有绿色的余光(基于自己测试时使用的灯带)
示波器显示如下
3. 在DMA传送完PWM波形后,在DMA中断函数中关闭PWM的DMA输出
灯珠显示效果:
按照设定的颜色模式正常显示
示波器显示效果如下:
分析
方式1在pwm通过DMA的方式传输完成后会保持高电平,且会产生杂波,可能是导致灯珠显示错乱的主要原因.
方式2在DMA传输完成的回调函数关闭PWM输出,还会产生杂波,而将关闭PWM输出的函数放到DMA中断中便不会产生杂波,这个现象感觉很怪异,DMA中断函数
- 会产生杂波的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | /* 中断回调函数,在设定的pwm通过DMA发送完成后会调用 */ void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef* htim) {<!-- --> /* TODO:无论在这里是否关闭DMA输出,在PWM传输完成后都会产生一段杂波(用示波器看到的)。但是在这里关闭DMA输出后 灯珠的颜色可以正常显示,杂波不会影响当前及后续灯珠的显示。但是在这里不关闭DMA输出,便会影响灯珠的显示。 (不清楚原因) TODO:在DMA中断函数中关闭DMA输出便不会产生杂波 */ /* 注意这里的通道号要用 HAL_TIM_ACTIVE_CHANNEL_x而不能用TIM_CHANNEL_x,看定时器句柄定义的Channel类型便可知晓*/ if(htim->Instance == TIM3) {<!-- --> if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_1) {<!-- --> HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_1); } else if(htim->Channel == HAL_TIM_ACTIVE_CHANNEL_2) {<!-- --> HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_2); } } } |
- 不会产生杂波的方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | /** * @brief This function handles DMA1 stream4 global interrupt. */ void DMA1_Stream4_IRQHandler(void) {<!-- --> HAL_DMA_IRQHandler(&hdma_tim3_ch1); /* 传输完成后,关闭DMA传输 */ HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_1); } /** * @brief This function handles DMA1 stream5 global interrupt. */ void DMA1_Stream5_IRQHandler(void) {<!-- --> HAL_DMA_IRQHandler(&hdma_tim3_ch2); /* 传输完成后,关闭DMA传输 */ HAL_TIM_PWM_Stop_DMA(&htim3, TIM_CHANNEL_2); } |
感觉非常不能理解的一点是:
如有大佬知道,希望能够不吝赐教!