硬汉嵌入式论坛

 找回密码
 立即注册
查看: 370|回复: 9
收起左侧

[TIMER] 在STM32H7中使用PWM+DMA驱动ws2812b问题

[复制链接]

8

主题

57

回帖

81

积分

初级会员

积分
81
发表于 2025-7-24 15:59:25 | 显示全部楼层 |阅读模式
最近在做一个简单的ws2812b灯珠的功能,从网上看到大多数人都是采用PWM+DMA方式驱动ws2812b,这种方式优点是脉冲波形准确,CPU占用小。

但是驱动过程中遇到一点问题,首先,单独使用PWM输出800KHz脉冲波形能正常输出不同占空比波形,但是当我想添加DMA做一下静态PWM输出驱动ws2812b时,设置了一组固定数据,mcu对应的引脚并没有正确输出。
1、使用STM32CUBEMX配置了一个简单的定时器PWM输出以及打开定时器的dma功能。
TIM23定时器配置以及DMA配置.png

2、生成的DMA配置
[C] 纯文本查看 复制代码
 hdma_tim23_ch2.Instance = DMA1_Stream0;
    hdma_tim23_ch2.Init.Request = DMA_REQUEST_TIM23_CH2;
    hdma_tim23_ch2.Init.Direction = DMA_MEMORY_TO_PERIPH;
    hdma_tim23_ch2.Init.PeriphInc = DMA_PINC_DISABLE;
    hdma_tim23_ch2.Init.MemInc = DMA_MINC_ENABLE;
    hdma_tim23_ch2.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
    hdma_tim23_ch2.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
    hdma_tim23_ch2.Init.Mode = DMA_NORMAL;
    hdma_tim23_ch2.Init.Priority = DMA_PRIORITY_HIGH;
    hdma_tim23_ch2.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
    if (HAL_DMA_Init(&hdma_tim23_ch2) != HAL_OK)
    {
      Error_Handler();
    }

    __HAL_LINKDMA(tim_baseHandle,hdma[TIM_DMA_ID_CC2],hdma_tim23_ch2);


3、静态测试数据
[C] 纯文本查看 复制代码
uint16_t  testPwmData[]={
    70 ,35,70,35,35,70,35,70
};
uint16_t  len = sizeof(testPwmData)/sizeof(testPwmData[0]);

//定时500ms调用该函数
HAL_TIM_PWM_Start_DMA(&htim23,TIM_CHANNEL_2,(uint32_t*)testPwmData,len);


4、DMA回调,确定完成后关闭
[C] 纯文本查看 复制代码
void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim)
{
  if(htim == &htim23)
  {
    /*关闭DMA传输以及PWM*/
 HAL_TIM_PWM_Stop_DMA(&htim23,TIM_CHANNEL_2);
  }
}

根据以上的配置以及测试,我无法正常从逻辑分析仪上接收到正确的脉冲波形,查阅了一下网上的,大多数都是差不多配置,只是使用的芯片不同,是STM32H7系列的芯片使用DMA功能还需要做其他的相关配置功能吗?

回复

使用道具 举报

0

主题

28

回帖

28

积分

新手上路

积分
28
发表于 2025-7-24 18:20:55 | 显示全部楼层
是不是使用spi加dma来输出更好些呢
回复

使用道具 举报

5

主题

162

回帖

177

积分

初级会员

积分
177
发表于 2025-7-25 09:55:05 | 显示全部楼层
有没有关cache?有没有将发送的内存放置到DMA可以访问的地方?DMA宽度跟定时器的通道匹配,而且DMA完成中断里面不需要暂停DMA,只需要将最后一位的发占空比是0就行了。
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-7-25 10:33:45 | 显示全部楼层
了无 发表于 2025-7-24 18:20
是不是使用spi加dma来输出更好些呢

硬件上没有spi,所以这种方式被pass
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-7-25 11:04:54 | 显示全部楼层
2859932063 发表于 2025-7-25 09:55
有没有关cache?有没有将发送的内存放置到DMA可以访问的地方?DMA宽度跟定时器的通道匹配,而且DMA完成中断 ...

MPU设置时默认的配置如下:
mpu配置.png
回复

使用道具 举报

5

主题

162

回帖

177

积分

初级会员

积分
177
发表于 2025-7-27 17:31:28 | 显示全部楼层
Ainit 发表于 2025-7-25 11:04
MPU设置时默认的配置如下:

把发送数组放置到DMA开源访问的位置
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-7-28 08:54:17 | 显示全部楼层
2859932063 发表于 2025-7-27 17:31
把发送数组放置到DMA开源访问的位置

您好,没太明白您的意思,是否是说使用STM32H7芯片的DMA功能时,需要配置芯片MPU功能,将发送数据的那个数组放入到指定的内存段中?
回复

使用道具 举报

5

主题

162

回帖

177

积分

初级会员

积分
177
发表于 2025-7-28 09:00:11 | 显示全部楼层
Ainit 发表于 2025-7-28 08:54
您好,没太明白您的意思,是否是说使用STM32H7芯片的DMA功能时,需要配置芯片MPU功能,将发送数据的那个 ...

H7的DMA1/2有一部分内存是不支持的访问的,所以你需要将数组的地址放到DMA可以访问的地方。H7有几个内存区域 你看一下总线就知道了,如果默认分配在ITCM/DTCM没法使用DMA
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-7-28 10:21:31 | 显示全部楼层
2859932063 发表于 2025-7-28 09:00
H7的DMA1/2有一部分内存是不支持的访问的,所以你需要将数组的地址放到DMA可以访问的地方。H7有几个内存 ...

您好,根据您提供的帮助,我现在将发送数据放入到指定的RAM_D3内存段中,目前能够通过HAL_TIM_PWM_Start_DMA()将数组中的数据发送出去,并且能够通过逻辑分析仪得到固定的波形数据。
回复

使用道具 举报

8

主题

57

回帖

81

积分

初级会员

积分
81
 楼主| 发表于 2025-7-29 10:07:02 | 显示全部楼层
记录该问题解决步骤:
1、首先就是如何配置PWM+DMA功能,为了简单明了,直接通过STM32CUBEMX工具配置,如下
tim_parameter配置.png tim23_dma配置.png
2、先调用默认的占空比,打开TIM_PWM输出,确定是否能正常输出固定占空比波形:
修改默认占空比
[C] 纯文本查看 复制代码
sConfigOC.Pulse = 30;

[C] 纯文本查看 复制代码
HAL_TIM_PWM_Start(&htim23, TIM_CHANNEL_2); // 先启动PWM

其他的配置,如完成PWM脉冲发送完成后的回调,关闭PWM输出等。
3、确定DMA数据需要存放再那个内存段中才能被访问到,比如我目前为了方便直接将数组定义再RAM_D3内存段中。
[C] 纯文本查看 复制代码
/* 可选:为大数组创建专用段(16KB),放到RAM_D3 __attribute__((section(".large_array16"))) */
      .large_array16 :
      {
        *(.large_array16)
      } > RAM_D3  AT> FLASH

[C] 纯文本查看 复制代码
uint32_t __attribute__((section(".large_array16"))) testPwmData[4]

以上做好后,能够输出,但是还有一个问题,比如我设置占空比的数组为多个数据,比如
[C] 纯文本查看 复制代码
uint32_t __attribute__((section(".large_array16"))) testPwmData[4] = {30, 55,
                                                                      55, 30};
,以上testPwmData数据时四个PWM占空比,但是实际上只有第一个占空比波形会输出,具体原因还在继续排查。

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 03:04 , Processed in 0.049373 second(s), 26 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表