笔者使用GD32F427 TIMER4 CH1输出pwm,通过配置dma控制PWM输出精准波形
- static void MX_TIM4_Init(void)
- {
- /* USER CODE BEGIN TIM4_Init 0 */
- /* USER CODE END TIM4_Init 0 */
- TIM_MasterConfigTypeDef sMasterConfig = {0};
- TIM_OC_InitTypeDef sConfigOC = {0};
- /* USER CODE BEGIN TIM4_Init 1 */
- /* USER CODE END TIM4_Init 1 */
- htim4.Instance = TIM4;
- htim4.Init.Prescaler = 0;
- htim4.Init.CounterMode = TIM_COUNTERMODE_UP;
- htim4.Init.Period = 112-1;
- htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
- htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
- if (HAL_TIM_PWM_Init(&htim4) != HAL_OK)
- {
- Error_Handler();
- }
- sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
- sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
- if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK)
- {
- Error_Handler();
- }
- sConfigOC.OCMode = TIM_OCMODE_PWM1;
- sConfigOC.Pulse = 0;
- sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
- sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
- if (HAL_TIM_PWM_ConfigChannel(&htim4, &sConfigOC, TIM_CHANNEL_1) != HAL_OK)
- {
- Error_Handler();
- }
- /* USER CODE BEGIN TIM4_Init 2 */
- /* USER CODE END TIM4_Init 2 */
- // HAL_TIM_Base_Start_IT(&htim4);
- HAL_TIM_MspPostInit(&htim4);
- }
- void DMA1_Stream0_IRQHandler(void)
- {
- HAL_DMA_IRQHandler(&hdma_tim4_ch1); // 调用HAL库中断处理函数
- }
- // 补充DMA传输完成回调(可选,用于确认传输结束)
- void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
- {
- if (htim == &htim4)
- {
- HAL_TIM_PWM_Stop_DMA(&htim4, TIM_CHANNEL_1); // 传输完成后停止PWM
- //rt_kprintf("call back\r\n");
- }
- }
- /**
- * Enable DMA controller clock
- */
- static void MX_DMA_Init(void)
- {
- /* DMA controller clock enable */
- __HAL_RCC_DMA1_CLK_ENABLE();
- /* DMA interrupt init */
- /* DMA1_Stream0_IRQn interrupt configuration */
- HAL_NVIC_SetPriority(DMA1_Stream0_IRQn, 0, 0);
- HAL_NVIC_EnableIRQ(DMA1_Stream0_IRQn);
- }
- void ws2812_load(void)
- {
- 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))
- {
- // rt_kprintf("HAL_TIM_PWM_Start_DMA err");
- }
- }
- void ws_set_color(uint16_t num, uint32_t rgb_data)
- {
- uint16_t i,j,z=0;
- for(i=0;i<24;i++)
- {
- WS2812_RGB_Buff[24 * num + i] = (((rgb_data << i) & 0X800000) ? WS_H : WS_L);
- }
- }
经过测试发现 GD32在给ws2812发送第一个像素数据的时候,会丢失第二个bit的pwm波形,我将0X800000 逐次右移一位然后输出,发现在0X800000>>1的时候,灯会直接灭掉,通过示波器也证实过此现象。不知道是芯片的问题还是配置的为题。但是同样的程序我在stm32上是正常运行的。
|