[应用相关]

使用TMR DMA模拟PWM波

[复制链接]
3857|5
手机看帖
扫描二维码
随时随地手机跟帖
ArterySW|  楼主 | 2021-4-18 22:48 | 显示全部楼层 |阅读模式
使用TMR DMA模拟PWM波

功能介绍:

本demo介绍了在没有Timer引脚能使用的情况下,如何使用TMR+DMA+GPIO模拟出PWM波形,此方法与常规用interrupt+软件反转IO口相比更加节省系统开销。



功能实现:

实现此功能,需要使用到一个TMR DMA通道,和开启TMR的DMA请求,然后配置一个IO口为输出模式即可。

需要特别注意的是,DMA传输数据到GPIO口时,DMA的及地址配置不能为GPIO的输出数据寄存器,而是要GPIO口的BSER寄存器及地址,代码可参考如下配置,程序中使得GPIOA.04输出PWM波形:

  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)&GPIOA->BSRE;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)Toggle_Buffer;
  DMA_InitStructure.DMA_Direction = DMA_DIR_PERIPHERALDST;
  DMA_InitStructure.DMA_BufferSize = 2;
  DMA_InitStructure.DMA_PeripheralInc = DMA_PERIPHERALINC_DISABLE;
  DMA_InitStructure.DMA_MemoryInc = DMA_MEMORYINC_ENABLE;
  DMA_InitStructure.DMA_PeripheralDataWidth = DMA_PERIPHERALDATAWIDTH_WORD;
  DMA_InitStructure.DMA_MemoryDataWidth = DMA_MEMORYDATAWIDTH_WORD;
  DMA_InitStructure.DMA_Mode = DMA_MODE_CIRCULAR;
  DMA_InitStructure.DMA_Priority = DMA_PRIORITY_HIGH;
  DMA_InitStructure.DMA_MTOM = DMA_MEMTOMEM_DISABLE;

使能TMR1的update事件的DMA请求,每次update事件DMA会传输一笔数据到GPIOA->BSRE寄存器,达到反转GPIO的目的。为什么不是GPIO->OPDT寄存器呢?这是因为采用GPIOA->BSRE寄存器可以只改变任意的IO口状态,GPIO->OPDT寄存器则不行。

#define Clear_GPIO_Pins_4                 ((uint32_t)0x00100000)
#define Set_GPIO_Pins_4                   ((uint32_t)0x00000010)
uint32_t Toggle_Buffer[2] = {Clear_GPIO_Pins_4,Set_GPIO_Pins_4};

可以通过调整TMR的DMA请求频率达到改变PWM波形频率的目的。

总结:
此方法在硬件电路已将固定,没有办法改变,或者TMR口受限的情况下很是方便,并不会暂用使用的过多资源。
代码可查看附件,将其解压到雅特力BSP对应路径即可运行哦!!!




使用TMR DMA模拟PWM波.rar

18.6 KB

使用特权

评论回复
wenzh1111| | 2021-9-2 13:17 | 显示全部楼层
这样设置 占空比就只能固定位50%了吧?

使用特权

评论回复
评论
2013搬运工 2021-9-2 16:14 回复TA
是的 
lqwuliang| | 2021-12-9 23:17 | 显示全部楼层
看看,学习学习

使用特权

评论回复
lajfda001| | 2021-12-13 12:26 | 显示全部楼层
这个是可以好好学习一下的。
不错的**的。

使用特权

评论回复
lajfda001| | 2021-12-13 15:23 | 显示全部楼层
需要好好学习一下,这个是一个不错的**哦,很棒的。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

178

主题

266

帖子

7

粉丝