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

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

3天内不再提示

STM32定时器BURST传输介绍及示例

茶话MCU 来源:ST MCU 信息交流 2020-05-14 09:15 次阅读

STM32定时器应用中,我们有时希望基于某定时器事件同时对定时器的多个寄存器进行读写访问。为此,STM32芯片设计了专门应对定时器的多寄存器访问应用的DMA Burst传输。

高级定时器和部分通用定时器都支持针对定时器寄存器访问的BURST传输。所谓定时器的BURST传输,就是指当产生某定时器事件时,可以产生多个DMA请求,并触发多次DMA传输,访问多个定时器寄存器实现从内存到寄存器或从寄存器到内存的数据传输。这里的定时器事件可以是更新事件、比较匹配事件、换相事件以及触发事件。

我们知道,各定时器的所有寄存器都存放在片内某一固定地址开始的连续空间内。下图是我从STM32G4系列定时器地址分布图中截取的一部分,不同的定时器所拥有的寄存器个数可能有差异,但每个定时器的寄存器地址映射表的第一个寄存器一定是TIMx_CR1,所有寄存器在内存空间以字对齐的方式按顺序依次存放。【后面都以TIM2为例来说】

显然,我们在做定时器的DMA BURST传输时,除了配置基本的源地址、目的地址等DMA传输所需的通用配置信息外,还得告知DMA BURST传输模块每次传输时从哪个寄存器开始,连续访问几个寄存器,比方访问上图中圈出来的从TIMx_CCR1开始的连续4个寄存器。

这里有两个专门用于定时器BURST传输的寄存器,分别是TIM2_DCR和TIM2_DMAR. 其中TIM2_DCR就是用来配置从哪个定时器寄存器开始访问、连续访问几个寄存器的问题。【下面截图来自STM32G4参考手册】

DBA:被访问的第一个定时器寄存器相对于定时器地址映射表中的TIMx_CR1的地址偏移量【偏移量从0开始计算】。

DBL:每组BURST访问的寄存器个数【从0开始计算】。

仍然按照上面所说,访问从TIM2_CCR1开始的连续4个寄存器,可得知TIM2_CCR1位于寄存器地址映射表中的第14号位置,则DBA= 14-1;用于BURST分组访问的寄存器个数为4个,则DBL=4-1。

另外一个寄存器就是TIM2_DMAR。那它是干什么的呢?上面TIM2_DCR寄存器只是配置了被访问的首个定时器寄存器地址相对于TIMx_CR1的地址偏移量和每组要访问的寄存器个数。其中地址偏移量还只是个相对数,DMA访问最终是需要绝对地址的,而TIM2_DMAR就是来解决DMA访问时所需的绝对地址的。

DMA访问DMAR寄存器时,按照如下算式得到绝对地址实现对寄存器的逐个访问。(TIM2_CR1address) + (DBA + DMA index)x 4

[Index是DMA Burst访问时硬件自动生成的动态索引号,按0~DBL依次实现对多个寄存器的连续访问而完成BUSRT传输】

也就是说,对于定时器DMA BURST传输,外设地址一定是TIM2_DMAR寄存器的地址【或许是源地址,或许是目的地址】,DMA通过访问它,并根据上面算式实现对实际寄存器的访问。所以TIM2_DMAR寄存器又可称之为专门用于定时器DMA Burst传输的虚拟寄存器。

总的来讲,我们在做基于定时器的DMA BURST传输时,除了使用正确的DMAR寄存器地址作为外设地址外,再就是配置好DCR寄存器中的DBA与DBL参数,弄清从哪个寄存器开始访问,访问几个寄存器。其它配置环节跟通用DMA传输配置一样。

下面用个例子来演示相关用法。后面的验证基于STM32G474 Nucleo板。使用TIM2输出4路PWM,根据更新事件同步变化占空比,实现PWM占空比呈规律性的宽窄变化。即每次发生更新事件时,DMA到内存区取走4个对应于4个通道的比较寄存器的值赋给对应的比较寄存器[CCR1/CCR2/CCR3,CCR4],如下图所示,多组数据传输完毕后循环重来。

下面使用STM32CubeMx工具进行基本的初始化配置。

配置TIM2_CH1/CH2/CH3/CH4的PWM输出:

对定时器时基单元进行配置:

对TIM2更新事件的DMA传输做基本配置:

这里配置为循环模式,具体应用时可以根据具有应用来选择模式。将其它时钟、GPIO配置完毕后即可生成初始化工程文件。

在工程里添加用户应用代码。关于定时器BURST传输有专门的库函数可以给我们直接调用。它们分别是:

HAL_TIM_DMABurst_WriteStart() ----(1)

HAL_TIM_DMABurst_ReadStart() ----(2)

第一个函数用于将内存数据以DMA 分组模式写入寄存器的功能函数;

第二个用于将多个寄存器内容以DMA 分组模式读取到内存的功能函数;

不过呢,如果我们简单套用这两个函数有些时候可能出问题,或者遇到障碍。我们不妨一起来看看。

显然,我们要用到第一个函数。当我们进一步打开该函数时,发现它只是再调用了另外一个函数。

即它调用了HAL_TIM_DMABurst_MultiWriteStart()函数。这里就该函数用到的几个变量一起看下。

htim:即指向定时器结构体的地址,就不多说了。

BurstBaseAddress:前面提到过的第一个被访问寄存器的地址偏移量,即给到DCR寄存器中DBA的值。这里第一个被访问的是TIM2_CCR1,所在地址偏移量为13.

BurstRequestSrc:即触发DMA Burst传输的定时器事件源。这里是更新事件。

BurstBuffer:这个是存放数据的内存起始地址,如用户定义的数组地址。

BurstLength:就是前面提到的对应于DCR寄存器中DBL的值,即每组Burst传输的数据个数。具体到这里DBL应该是4-1,即3.

上面是固件里对该变量的定义。数据为什么这样定义,整整往左移了8位。看看上面DCR寄存器中DBL段所处位置就明白了。

最后看看紧随其后的另外一个数据量 ((BurstLength) >> 8U) + 1U;结合前面BurstLength的数据,该计算结果就是给到DMA的传输数据个数,数值等于每组 Burst传输的数据个数。具体到这里就是4。换言之,若我们将每组Burst传输的数据个数设为6,则这里的值就是6。这就意味着,如果按照该函数的现有用法,无论发生多少次Busrt传输只能用到一组数据。如果我希望在Burst传输中使用到多组不同数据【可能部分不同或全部不同】,就像上面示例所期望的那样,那怎么办呢?

这时我们可以基于现有库函数,在BURST传输需要用到多组不同数据时,直接使用

HAL_TIM_DMABurst_MultiWriteStart()函数并将其最后一个表示DMA传输长度的那个变量做适当修改。

比方在应用中每组BURST传输m个数据,一轮DMA传输过程中对应n个触发事件,在不同的触发时刻,每组传输的数据内容并不全部相同,这时总的DMA传输数据个数就是m*n。具体到这里,我要用到11组不同的数据,每组传输4个数据,即一轮DMA传输用到4*11个数据。

好,到此基本介绍和分析都差不多了,再看看具体用户代码。代码很简单,基于STM32HAL库的。

下面是用来调整不同时刻各个通道PWM占空比的内存数据,共11组。

要添加的用户参考代码都在下面,几行代码,应该说明白如画。主要是那个关于定时器DMA分组传输的那个函数,上面也已经详细解释了。

最后看看运行后的演示结果。

示波器只接了2个通通,目的就是演示同时修改4个通道的占空比,实现pwm占空比由窄到宽的规律性变化。

到此,关于定时器DMA Burst传输的介绍及示例就聊到这里。稍事小结:

1、从定时器DMA Burst传输原理的理解上讲,稍显小复杂。需要我们对定时器相关原理和DMA基础知识有较好的了解。在阅读STM32参考手册相关章节时,除了看正文部分外,还需细看TIMx_DMAR和TIMx_DCR寄存器的描述。但从实现代码角度看,使用CubeMx和固件库,其功能代码还是很简单的,将相关变量值对应地填进去即可。

2、STM32固件库的有些例程或函数侧重点在演示相应的功能或特性,但它不能包罗万象或保证适用于任何场景。有时我们可以在基于现有函数的前提下适当地做些改写调整,甚至完全重写代码以满足实际需求。

3、在做定时器DMA Burst传输时,用来被成组访问的定时器寄存器应该是同一定时器的而且是地址连续的寄存器,不可跳跃访问。

4、上面的示例只是个示范,旨在了解该功能的用法和基本特性。实际应用中,往往还要涉及更多细节,比方各个定时器事件的特性、寄存器的预装功能的开或关、DMA相关知识等,最终结合实际需求加以灵活运用。

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

    关注

    30

    文章

    5183

    浏览量

    118343
  • STM32
    +关注

    关注

    2249

    文章

    10725

    浏览量

    350313
  • 定时器
    +关注

    关注

    23

    文章

    3178

    浏览量

    112678

原文标题:STM32定时器BURST传输介绍及示例

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

收藏 人收藏

    评论

    相关推荐

    STM32定时器时间计算方法

    将详细介绍STM32定时器时间计算方法。 STM32定时器基本结构 STM32
    的头像 发表于 12-19 11:31 7300次阅读

    stm32一个定时器能同时控制两个灯以不同频率闪烁吗?

    STM32定时器功能强大,**STM32定时器可以同时控制两个灯以不同频率闪烁** 。
    的头像 发表于 12-13 10:43 989次阅读

    STM32如何使用定时器实现微秒(us)级延时?

    STM32如何使用定时器实现微秒(us)级延时? 在STM32微控制器中,可以使用定时器实现微秒级延时。具体来说,可以使用定时器的计数器和自
    的头像 发表于 11-06 11:05 4135次阅读

    STM32速成笔记(6)—定时器

    关于什么是定时器,简单来讲,就是是用来定时的。STM32F103ZET6有两个基本定时器TIM6和TIM7,四个通用定时器TIM2~TIM5
    的头像 发表于 10-24 09:41 2921次阅读
    <b class='flag-5'>STM32</b>速成笔记(6)—<b class='flag-5'>定时器</b>

    STM32 HRTIM Burst输出模式应用演示

    有人使用STM32G474芯片的片上高精度定时器HRTIM,他想使用其输出功能的Burst Mode。但不知如何使用,想找找参考例程。我这里就使用STM32G474芯片做下应用演示。
    的头像 发表于 10-13 09:07 2905次阅读
    <b class='flag-5'>STM32</b> HRTIM <b class='flag-5'>Burst</b>输出模式应用演示

    Linux驱动定时器使用示例

    定时器使用示例 使用步骤: 1、调用 init_timer 初始化一个定时器,给 struct timer_list 各成员赋值。 2、调用 add_timer 将定时器添加到内核
    的头像 发表于 10-04 15:47 446次阅读

    STM32各类系列定时器概览

    本文档:概述了 STM32F1xx、STM32F2xx、STM32F4xx、STM32L1xx 和 STM32F30/31/37/38x微控
    发表于 08-31 10:49 0次下载

    STM32L4定时器(TIMER)介绍

    电子发烧友网站提供《STM32L4定时器(TIMER)介绍.pdf》资料免费下载
    发表于 08-01 14:24 0次下载
    <b class='flag-5'>STM32</b>L4<b class='flag-5'>定时器</b>(TIMER)<b class='flag-5'>介绍</b>

    STM32 TIM—基本定时器

    STM32F4xx系列控制器有共有14个TIM定时器。其中2个高级控制定时器TIM1和TIM8、10 个通用定时器TIM2TIM5和TIM9TIM14、 2个基本
    的头像 发表于 07-22 17:05 3871次阅读
    <b class='flag-5'>STM32</b> TIM—基本<b class='flag-5'>定时器</b>

    STM32定时器(三)输入捕获

    STM32定时器是支持信号输入捕获的,何为输入捕获?主要做什么应用?
    的头像 发表于 07-21 14:58 3207次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>定时器</b>(三)输入捕获

    STM32定时器(一)PWM输出

    STM32定时器分类众多,按照内核、外核标准分为两部分:核内定时器+核外定时器
    的头像 发表于 07-21 14:51 3409次阅读
    <b class='flag-5'>STM32</b><b class='flag-5'>定时器</b>(一)PWM输出

    STM32CubeMx入门教程(3):定时器的使用

    导语“ 使用STM32CubeMx 生成初始化定时器代码,实现定时器特定定时
    发表于 07-11 15:22 2832次阅读
    <b class='flag-5'>STM32</b>CubeMx入门教程(3):<b class='flag-5'>定时器</b>的使用

    一个定时器输出4路不同频率波形的应用示例

    一般来讲,一个STM32定时器输出基于同一频率的各路信号比较方便。但经常也会有人问使用STM32一个定时器是否可以实现多路不同频率的输出。
    的头像 发表于 07-06 15:57 1469次阅读
    一个<b class='flag-5'>定时器</b>输出4路不同频率波形的应用<b class='flag-5'>示例</b>

    STM32F407 基本定时器使用

    介绍STM32F407基本定时器的配置方法,分别介绍轮询方式、中断方式使用定时器完成定时
    的头像 发表于 07-06 14:32 2451次阅读
    <b class='flag-5'>STM32</b>F407 基本<b class='flag-5'>定时器</b>使用

    STM32F407 滴答定时器

    介绍STM32F407滴答定时器配置方法、使用方式,封装延时函数得到精确的时间。
    的头像 发表于 07-06 14:32 1492次阅读
    <b class='flag-5'>STM32</b>F407 滴答<b class='flag-5'>定时器</b>