0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

STM32 TIMER+DMA输出PWM异常案例的问题解析

茶话MCU 来源:茶话MCU 作者:茶话MCU 2023-09-28 09:04 次阅读

案例1:STM32U575的TIMER+GPDMA输出PWM异常

有人使用STM32U575的TIMER加上DMA做PWM输出。具体就是利用某TIMER的一个通道的比较事件触发DMA,通过DMA修改CCR值来实现指定占空比的PWM输出。

对于很多STM32用户来说,这个应用算是比较常见的做法了。可当他使用CubeMx完成配置,生成工程添加相应用户代码后,发现输出跟预期不一致。

而当他使用STM32F1或STM32G0系列来实现时又没有任何问题。其实,定时器基本配置都差不多,都是调用ST提供的HAL库函数HAL_TIM_PWM_Start_DMA()。该函数的原型就是下面样子:

9f1a6364-5d95-11ee-939d-92fbcf53809c.png

鉴于该用户的反馈,我找了STM32H563的开发板,也来做些验证测试。使用TIM1,快速对其做配置,开启通道1比较事件的DMA请求及PWM输出,让DMA动态修改CCR1来改变PWM输出占空比。使用CubeMx进行配置:

9f2ce6ce-5d95-11ee-939d-92fbcf53809c.png

9f4fffe2-5d95-11ee-939d-92fbcf53809c.png

创建工程后,稍微添加点用户代码后即可进行测试。下面数组里有10个数据,对应10个不同占空比的脉冲。

9f75204c-5d95-11ee-939d-92fbcf53809c.png

我期望输出下面的波形:

9f901ec4-5d95-11ee-939d-92fbcf53809c.png

当我基于上面配置及用户代码运行程序后,发现输出却是这样的:

9fa91208-5d95-11ee-939d-92fbcf53809c.png

显然跟我的预期相差甚远。那是怎么回事呢?

我也顺便找了块STM32G4的开发板,快速地验证了该功能,输出跟预期完全吻合。那STM32U5有什么特别的地方呢?后来经过快速浏览手册和阅读库函数,终于还是发现了问题原因所在。

不管我们使用哪个STM32系列,实现上述功能,使用HAL库的话,调用的库函数都是一样的。都是前面提到过的HAL_TIM_PWM_Start_DMA(),【注:最后都会调用HAL_DMA_Start_IT】,在这个函数里有个Length变量。该变量在STM32U5系列的HAL库里的约定含义跟其它系列,比如F4/G4/G0等的不太一样。

在STM32U5系列库函数里,该Length变量表示的是一轮【块】传输过程中DMA从源搬到目的的数据所对应的字节数;【下面截图来自STM32U5系列HAL库,注释中特地强调以字节为单位】

9fbfe2da-5d95-11ee-939d-92fbcf53809c.png

而在F4/G4/G0这些系列的库函数里,该变量表示的则是DMA从源搬到目的的数据个数【见下面函数注释】;

9fdacabe-5d95-11ee-939d-92fbcf53809c.png

当然,我们也可以从STM32参考手册里的寄存器定义看出差别来。在STM32U5系列GPDMA里描述DMA传输长度的寄存器是GPDMA_CxBR1,其中字段BNDT[15:0]表述块传输过程中从源传输到目的的数据字节数。

a009861a-5d95-11ee-939d-92fbcf53809c.png

而在STM32G4/F4系列里,描述DMA传输长度的寄存器是DMA_CNDTRx。

a021fb28-5d95-11ee-939d-92fbcf53809c.png

明确表示该长度为DMA传输的数据个数,一轮【块】最多传输64K个数据。

介绍到这里,我们就基本明白了,为什么同样的操作及函数,STM32F4/G4/G0/F1系列表现正常,而STM32U5表现异常了。回到开头,现在源数据宽度为16位,希望一轮传输10个数据,那对应的传输字节数就是10*2。当我把上面的那个DAM启动函数里的Length调整20时输出也的确正常了。

也就是说,对于STM32U5系列,这个Length应设置成传输的数据个数乘以源数据宽度即可。当然,别的系列是否也有类似问题不好说,具体应用时我们稍微留意下。总之,遇到问题时不能完全死守经验,必要的阅读手册和阅读函数也是必要的。

案例2:基于TIMER Burst DMA实现PWM输出异常

有人使用STM32G4系列芯片开发产品,用到基于STM32定时器的DMA BURST传输。他使用定时器TIM1的更新事件同时修改其3个输出通道的PWM占空比并保持同步输出。如下图所示:

a03d0440-5d95-11ee-939d-92fbcf53809c.png

可是,他在调试过程中发现个非常奇怪的现象。感觉只要接上STLINK调试器,输出就不正常。主要体现就是TIM1的3路PWM输出不再保持同步,如下图所示的情形:

a05f70fc-5d95-11ee-939d-92fbcf53809c.png

结合他的反馈和本人经验,我觉得问题可能不是出在连接调试器上,而很可能与打开PC端IDE的寄存器窗口有关。经了解,他当时使用的IDE是ARM MDK,调试过程中也的确一直打开了相关TIMER的寄存器观察串口。

a081d458-5d95-11ee-939d-92fbcf53809c.png

当他尝试把TIMER1的寄存器视窗关闭后,重新运行代码,3路输出就恢复同步输出了,完全符合预期。看来,输出正常与否跟接不接STLINK调试器是没有关系的,根本原因是打开了TIMER的寄存器视窗。

那问题来了,TIMER的寄存器观察窗口被打开后怎么就影响到PWM输出呢?

这里可以有个初步判断,因为芯片的调试组件不时地访问TIMER的某些寄存器而影响到PWM输出了。TIMER的寄存器这么多,具体是哪个或哪几个寄存器因为调试组件的访问而被影响其内容,进而影响到PWM输出呢?

快速浏览一遍TIM1的寄存器,并没有立即发现或锁定哪个寄存器因被读取后会明显影响当前定时器的正常运行的。后来,他干脆就将那些TIMER寄存器一个个地试,看看到底哪个寄存器因为中途被读取后会影响到当前PWM输出。功夫不负有心人,最后发现跟寄存器TIMx_DMAR有关!

刚才前面说过了,他现在是使用STM32定时器的DMA BURST传输。该类传输涉及到2个专门的寄存器,分别是TIMx_DCR 和 TIMx_DMAR。

a0ab678c-5d95-11ee-939d-92fbcf53809c.png

其中,DCR寄存器配置BURST长度和每次发起Burst传输时参与传输的定时器的第一个寄存器位置。DMAR寄存器专门用来提供DMA访问定时器寄存器时的地址,我们可以将DMAR寄存器看成一个地址指针,DMA访问DMAR寄存器时所获得的外设地址【即定时器寄存器地址】由算式(TIMx_CR1地址)+(DBA+DMA 索引号)x 4来决定。

a0cfc6ae-5d95-11ee-939d-92fbcf53809c.png

其中,DBA、DBL在DCR寄存器中配置好了的,是固定值。DMA索引号在0~DBL之间依次动态变化。具体到本案例应用,DBL等于2。

为什么当开启寄存器观察窗口后,DMAR寄存器被调试组件访问后会影响到此处Burst传输呢?关于这点,我是这样理解的。本来DMAR寄存器是专门给DMA访问来实现定时器寄存器与内存间的Burst传输的。在这个过程中,DMA Index基于DMA访问自动调整从而实现Burst传输。如果说,在这个过程中调试组件也参与进来对DMAR寄存器进行访问,这时可能导致DMA Index变更的混乱,从而导致对定时器寄存器访问序列的混乱,最后导致3路PWM输出的混乱。


审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 寄存器
    +关注

    关注

    30

    文章

    5028

    浏览量

    117722
  • PWM
    PWM
    +关注

    关注

    114

    文章

    4900

    浏览量

    209906
  • STM32
    +关注

    关注

    2239

    文章

    10671

    浏览量

    348745
  • 定时器
    +关注

    关注

    23

    文章

    3147

    浏览量

    112037
  • PWM输出
    +关注

    关注

    1

    文章

    61

    浏览量

    5053
  • HAL库
    +关注

    关注

    1

    文章

    112

    浏览量

    5878

原文标题:STM32 TIMER+DMA输出PWM异常二案例

文章出处:【微信号:stmcu832,微信公众号:茶话MCU】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    STM32U5系列TIMER+DMA+DAC应用演示

    有人使用STM32U575芯片的DAC功能。他希望使用TIMER事件触发DMA,并通过DMA传输内存数据到DAC输出寄存器,进而产生相应的D
    的头像 发表于 01-24 09:10 521次阅读
    <b class='flag-5'>STM32</b>U5系列<b class='flag-5'>TIMER+DMA</b>+DAC应用演示

    STM32F051C8 PA0不能以DMA的方式输出PWM,没有正确波形输出是哪里出了问题?

    ,新建工程,选择型号STM32F051C8; 选择内部时钟,配置时钟为48Mhz, 配置TIM2 CH1为DMA PWM输出; 生成代码后,加入WS2812b的应用代码;在m
    发表于 03-13 06:20

    f446rct6在使用dma控制pwm占空比时,pwm波形异常的原因?

    单片机:f446rct6 系统:freertos 库:hal 程序逻辑: 1.初始化timer输出pwm波同时初始化dma并连接到Capture/Compare 寄存器 2.启动
    发表于 04-09 07:45

    STM32F103 timer8配置PWM输出中间出现无法输出PWM现象

    我使用STM32F103中的timer8作为PWM的定时器,来驱动电机的控制桥,发现有的时候修改占空比后,配置的IO口无法输出PWM波形,并
    发表于 05-03 16:15

    STM32如何输出精确的PWM波形

    of half PWM period in center-aligned mode. 3、DMA方式送数。 将DMA与Tim的CCR绑定,通过控制DMA的数据数量,
    发表于 11-01 16:10

    如何使用STM32DMA功能自动更新PWM输出

    如何使用STM32DMA功能自动更新PWM输出呢?求解答
    发表于 11-12 06:47

    如何使用Timer输出PWM信号?

    如何使用Timer输出PWM信号?
    发表于 01-21 07:19

    STM32F030的定时器PWM使用设置与ADC的dma代码

    里面是STM32F030的定时器PWM使用设置与ADC的dma代码
    发表于 03-21 15:29 151次下载

    2021-06-05 GD32F405VG 调试过程关于DAC/DMA/TIMER等问题的解决

    ,比如STM32中的TIMER1的地址映射,对应的是GD32的TIMER0,STM32的DAC1对应GD32的DAC0,等等诸如此类。STM32
    发表于 12-03 09:06 12次下载
    2021-06-05 GD32F405VG 调试过程关于DAC/<b class='flag-5'>DMA</b>/<b class='flag-5'>TIMER</b>等问题的解决

    [笔记]|[stm32]|[寄存器存储器区别]|[PWM]|[串口]|[Timer]stm32f103笔记

    [笔记]|[stm32]|[寄存器存储器区别]|[PWM]|[串口]|[Timer]stm32f103笔记此笔记为18.12.21笔者期末复习所写 ——仅作为自己期末复习以及过后查阅
    发表于 12-06 18:51 10次下载
    [笔记]|[<b class='flag-5'>stm32</b>]|[寄存器存储器区别]|[<b class='flag-5'>PWM</b>]|[串口]|[<b class='flag-5'>Timer</b>]<b class='flag-5'>stm32</b>f103笔记

    stm32F4的ADC+DMA+Timer,实现2MHz连续采样。1LSB分辨率,极低噪声。

    1. stm32F4的ADC+DMA+Timer的实现原理stm32F4的ADC参数
    发表于 12-20 19:48 56次下载
    <b class='flag-5'>stm32</b>F4的ADC+<b class='flag-5'>DMA+Timer</b>,实现2MHz连续采样。1LSB分辨率,极低噪声。

    [STM32F1官方例程讲解1] TIM外设输出PWM

    [STM32F1官方例程讲解1]TIMER输出PWM波第一章 PWM波是什么第二章 相关函数配置第三章 整体代码第一章
    发表于 12-31 19:21 5次下载
    [<b class='flag-5'>STM32</b>F1官方例程讲解1] TIM外设<b class='flag-5'>输出</b><b class='flag-5'>PWM</b>波

    使用MM32F0270 定时器DMA方式输出PWM

    使用MM32F0270 定时器DMA方式输出PWM
    的头像 发表于 10-17 14:47 529次阅读
    使用MM32F0270 定时器<b class='flag-5'>DMA</b>方式<b class='flag-5'>输出</b><b class='flag-5'>PWM</b>

    TIM DMA burst输出变频PWM波形

    电子发烧友网站提供《TIM DMA burst输出变频PWM波形.pdf》资料免费下载
    发表于 09-19 17:06 2次下载
    TIM <b class='flag-5'>DMA</b> burst<b class='flag-5'>输出</b>变频<b class='flag-5'>PWM</b>波形

    应用笔记 | STM32使用DMA产生PWM时波形异常分析

    关键字:回调函数,HAL库   目录预览 1.前言 2.实验 3.使用实例 4.小结 0 1 前言 有客户反馈,使用STM32F4的TIM2结合DMA,产生的PWM波形不符合预期,但是相同的配置
    的头像 发表于 09-22 17:05 1603次阅读
    应用笔记 | <b class='flag-5'>STM32</b>使用<b class='flag-5'>DMA</b>产生<b class='flag-5'>PWM</b>时波形<b class='flag-5'>异常</b>分析