关于GD32F427 DMA+PWM控制WS2812B的丢波问题,STM32不会丢

[复制链接]
1991|7
ETO降临派 发表于 2025-9-4 11:49 | 显示全部楼层 |阅读模式
笔者使用GD32F427 TIMER4 CH1输出pwm,通过配置dma控制PWM输出精准波形

  1. static void MX_TIM4_Init(void)
  2. {

  3.   /* USER CODE BEGIN TIM4_Init 0 */

  4.   /* USER CODE END TIM4_Init 0 */

  5.   TIM_MasterConfigTypeDef sMasterConfig = {0};
  6.   TIM_OC_InitTypeDef sConfigOC = {0};

  7.   /* USER CODE BEGIN TIM4_Init 1 */

  8.   /* USER CODE END TIM4_Init 1 */
  9.   htim4.Instance = TIM4;
  10.   htim4.Init.Prescaler = 0;
  11.   htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
  12.   htim4.Init.Period = 112-1;
  13.   htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
  14.   htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
  15.   if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
  16.   {
  17.     Error_Handler();
  18.   }
  19.   sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  20.   sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  21.   if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
  22.   {
  23.     Error_Handler();
  24.   }
  25.   sConfigOC.OCMode = TIM_OCMODE_PWM1;
  26.   sConfigOC.Pulse = 0;
  27.   sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
  28.   sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
  29.   if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
  30.   {
  31.     Error_Handler();
  32.   }
  33.   /* USER CODE BEGIN TIM4_Init 2 */
  34.   /* USER CODE END TIM4_Init 2 */
  35. // HAL_TIM_Base_Start_IT(&htim4);
  36.   HAL_TIM_MspPostInit(&htim4);

  37. }

  38. void DMA1_Stream0_IRQHandler(void)
  39. {
  40.     HAL_DMA_IRQHandler(&hdma_tim4_ch1); // 调用HAL库中断处理函数
  41. }

  42. // 补充DMA传输完成回调(可选,用于确认传输结束)
  43. void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
  44. {
  45.     if (htim == &htim4)
  46.     {
  47.         HAL_TIM_PWM_Stop_DMA(&htim4, TIM_CHANNEL_1); // 传输完成后停止PWM

  48.         //rt_kprintf("call back\r\n");
  49.     }
  50. }



  51. /**
  52.   * Enable DMA controller clock
  53.   */
  54. static void MX_DMA_Init(void)
  55. {

  56.   /* DMA controller clock enable */
  57.   __HAL_RCC_DMA1_CLK_ENABLE();

  58.   /* DMA interrupt init */
  59.   /* DMA1_Stream0_IRQn interrupt configuration */
  60.   HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
  61.   HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);


  62. }
  1. void ws2812_load(void)
  2. {

  3.     if (HAL_OK != HAL_TIM_PWM_Start_DMA(&htim4,TIM_CHANNEL_1,(uint32_t *)WS2812_RGB_Buff,sizeof(WS2812_RGB_Buff)/sizeof(uint16_t)));//sizeof(WS2812_RGB_Buff)/sizeof(uint16_t))
  4.     {
  5.        // rt_kprintf("HAL_TIM_PWM_Start_DMA err");
  6.     }
  7. }
  1. void ws_set_color(uint16_t num, uint32_t rgb_data)
  2. {
  3.     uint16_t i,j,z=0;

  4.     for(i=0;i<24;i++)
  5.     {
  6.         WS2812_RGB_Buff[24 * num + i] = (((rgb_data << i) & 0X800000) ? WS_H : WS_L);
  7.     }

  8. }
经过测试发现 GD32在给ws2812发送第一个像素数据的时候,会丢失第二个bit的pwm波形,我将0X800000 逐次右移一位然后输出,发现在0X800000>>1的时候,灯会直接灭掉,通过示波器也证实过此现象。不知道是芯片的问题还是配置的为题。但是同样的程序我在stm32上是正常运行的。
海滨消消 发表于 2025-9-26 16:25 | 显示全部楼层
GD32和STM32虽然同属ARM Cortex-M系列,但在外设实现上可能存在细微差异。
海滨消消 发表于 2025-9-26 16:25 | 显示全部楼层
GD32的定时器或DMA模块可能在处理某些特定配置时与STM32不同。
classroom 发表于 2025-9-26 17:26 | 显示全部楼层
PWM配置问题,,预分频器设置为0,周期设置为112-1,这可能导致PWM频率过高或过低,影响波形质量。
cr315 发表于 2025-9-26 18:27 | 显示全部楼层
DMA配置有点问题吧
duo点 发表于 2025-9-26 19:28 | 显示全部楼层
GD32F427可能本身有缺陷
flycamelaaa 发表于 2025-9-26 20:29 | 显示全部楼层
建议参考GD32官方文档。
jcky001 发表于 2025-9-26 21:30 | 显示全部楼层
可能需要换GD32F427芯片
您需要登录后才可以回帖 登录 | 注册

本版积分规则

7

主题

22

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部