在STMCU中文社区有人咨询了类似下面的应用问题,有部分需求如下:
1.发送12个周期为500ns的脉冲(高电平200ns,低电平300ns),每隔4us发送一次,共计三次(36个脉冲,每12个脉冲之间间隔4us)。
2.在第一步中的每段12个脉冲的上升沿时,访问GPIO口,共计12个,三次共计36个。相关时序图如下:
这里,我们就该问题的部分需求聊聊它的大致实现。先整理下需求:
连续三组12个周期为500ns的指定个数的小脉冲;
一个固定时间间隔10us(含12个脉冲本身的时间);
每个小脉冲对应1次GPIO的访问;
显然,我们一般会很自然地想到通过TIMER来完成,可以使用1个TIMER,也可以通过2个TIMER来完成。
如果使用1个TIMER,我们可以考虑使用更新事件对脉冲个数的统计及时间间隔的控制,同时基于比较事件或更新事件来触发DMA来实行对GPIO的访问。不过,这里每个脉冲周期为500ns,势必会发生频繁进入更新中断。
如果使用2个TIMER来实现起来就更为方便点。2个TIMER实现主从级联,各自任务如下安排:
主TIMER做时间间隔的控制,每10us产生一次触发事件,并开启更新事件中断,每发生3次更新事件即为一个大周期,后续启动根据其它条件定,此处不表。
从ITMER工作在触发从模式,同时选择它的某一通道做PWM输出,并工作在单脉冲模式,同时每个脉冲的比较事件触发一次DMA实现GPIO与内存间的传输。
基于上面的需求及规划,下面简单介绍下实现过程。我们选用STM32G4系列的Nucleo板【Nucleo-G431RB】来进行验证测试。
选择TIM1工作在从模式,输出脉冲的比较事件触发DMA完成对GPIO的访问。DMA每传输12个数据后进入DMA传输完成中断,并进行相关数据处理。令TIM3工作在主模式,它的计时周期为10us,每个周期产生一次更新事件作为触发输出并与TIM1的触发输入相连,作为TIM1的启动触发信号。
通过查看STM32G4系列参考手册,我们可以得到如下片内定时器互联信号表。TIM3的TRGO信号可以作为TIM1的触发输入通道2的输入信号。
下面我们使用CubeMx进行配置。先看TIM1的相关配置【定时器计数时钟为10MHz】:
再看看看TIM3的基本配置:
完成相关初始化配置后创建工程,然后添加必要的用户代码。代码很简单,开启TIM1通道的pwm输出,使能TIM1-ch1比较事件的DMA触发功能,调用相关DMA功能函数,启动TIM3的计数器。
其中,TIM_DMAcptPro()为DMA传输完成中断的回调函数,负责做相关数据的处理。TIM1的启动靠TIM3的更新事件来触发实现。
稍作编译调试即可看到如下结果:
黄色的信号为TIM1周期的脉冲输出,小脉冲间的间隔为4us.
蓝色信号为通过DMA写到GPIO的数据,高、低电平均代表一个数据。这些只是模拟下操作过程。
显然,当弄清实现原理后,基于CubeMx进行配置,整个过程实现起来还是比较简单的。这里需要我们对定时器的主从级联、定时器各类事件、比较输出的单脉冲模式的特性及对DMA运用有些了解。上面主要演示基于定时器主从模式的实现过程,更多细节还得阅读相关技术手册。
最后提醒个地方,现在是TIM3的更新事件去触发启动TIM1,显然第一次启动TIM1时需等待TIM3一个计数周期,如果不希望这样的话,我们也可以在TIM3启动的同时启动TIM1计数,只需在启动TIM3的同时手动产生个更新事件来实现。
编辑:jq
-
定时器
+关注
关注
23文章
3236浏览量
114396 -
dma
+关注
关注
3文章
558浏览量
100384 -
代码
+关注
关注
30文章
4733浏览量
68291 -
GPIO
+关注
关注
16文章
1191浏览量
51869
原文标题:STM32定时器主从级联的又一应用示例
文章出处:【微信号:stmcu832,微信公众号:茶话MCU】欢迎添加关注!文章转载请注明出处。
发布评论请先 登录
相关推荐
评论