单片机学习小组
直播中

感谢相遇

9年用户 959经验值
擅长:嵌入式技术 制造/封装 控制/MCU
私信 关注

如何使用STM32定时器的基本计数定时功能,周期性地让一个LED灯闪烁?

如何使用STM32定时器的基本计数定时功能,周期性地让一个LED灯闪烁?

回帖(1)

王辉

2022-2-8 14:34:09
STM32定时器是 ST MCU 内部最基础且常用的外设,实际应用尤为普遍。去年,电堂推出了《STM32 TIMER基础及常规应用介绍》,为大家梳理了 STM32 TIMER 的庞大内容,涵盖 TIMER 的基本应用原理、常规应用等。现在将课程内容整理为文章,针对STM32定时器有基本了解的用户,分享具体的应用实现环节及常见问题解决。
实验内容:
使用STM32定时器的基本计数定时功能,周期性地让一个LED灯闪烁,具体就是1s亮1s暗。
涉及到的开发板:
STM32F411 Nucleo 板 【实验对开发板并无特别要求】,集成开发环境不限。
实验目的:
1、熟悉定时器时基单元的基本寄存器及相关数据的拟定。
2、比较通用定时器与高级定时器在时基单元组成上的差异。
3、熟悉定时器的不同时钟源及使用。
4、为后面的其它实验做铺垫。
本次实验分三组来完成,实验结果都一样,只是实现方式上有些差异。
第一组:使用通用定时器3来完成,选用定时器的内部时钟做计数器时钟源,在定时器的更新中断里做某GPIO的翻转实现LED的闪烁。
第二组:使用高级定时器1来完成,选用定时器的内部时钟做计数器时钟源,在定时器的更新中断里做某GPIO的翻转实现LED的闪烁。
第三组:使用通用定时器3来完成,选用定时器的一外部时钟做计数器时钟源,在定时器的更新中断里做某GPIO的翻转实现LED的闪烁。
实验一
TIM3/ 每1s切换PA5输出电平驱动LED灯
1、选择定时器内部时钟作为时钟源,STM32F411芯片定时器内部时钟为100Mhz;
2、设置分频比,选择计数模式、设置计数脉冲个数;
先对时钟源10000分频、即PSC=10000-1;
选择向上计数模式up counting;
计数器基于分频后的脉冲每计数10000个,发生溢出并产生更新事件及中断。
则:ARR=10000-1
按照上面的参数来设计的话,定时器的定时计数周期或者说溢出周期就是1s.

   

   
通过STM32CUBEMX依据上述参数完成配置,并开启TIM3的中断使能,然后生成工程。再在工程的用户代码里添加应用代码。
HAL_TIM_Base_Start_IT(&htim3);
该函数使能了TIM3的更新中断位,并软件启动定时器的工作。
在中断服务程序里添加切换LED亮暗的代码:

   
整个过程比较简单,配置完成,只需添加简单的用户代码,然后编译、下载就可以看结果。第一个实验就算完成了,接着来看第2个实验。
实验二
TIM1/每1s切换PA5输出电平驱动LED灯
这次是使用高级定时器,时钟源不变。但我们这次想用一下高级定时器才有RCR寄存器。实验的内容一样的。
我们知道,RCR寄存器是用来对计数器的溢出次数进行统计的,计数器每发生RCR+1次溢出时,定时器会产生更新事件触发更新中断。
上面的实验中是定时器基于计数时钟每1秒钟发生一次溢出并产生更新事件,那么,这里我们可以让定时器溢出多次,比方4次、5次都可以,然后定时器才产生更新事件并触发中断,同样我们在更新中断里做GPIO的翻转实现LED的闪烁。至于溢出几次产生更新事件,我们通过RCR寄存器来配置,比如希望每溢出5次产生更新事件,那么RCR就设置为5-1,也就是4.
具体结合到这里的实验,我们希望每1s发生5次溢出后才产生更新事件及中断。这也就意味着定时器每200ms发生一次溢出,那相应的时基寄存器的参数我们可以做些调整.显然,相比上一个实验,定时器单次计数周期变得短多了,我们可以将PSC/ARR/RCC做适当调整。比如我们这样配置:
1、选择定时器内部时钟作为计数器时钟源,100Mhz;
2、设置分频比,选择计数模式、设置计数脉冲个数、RCR的值
先对时钟源2000分频、即PSC=2000-1;
选择向上计数模式up counting;
计数器基于分频后的脉冲每计数10000个发生溢出。则:ARR=10000-1
每发生5次溢出产生更新事件,则: RCR=5-1
按照上面的参数来设计的话,定时器的定时计数溢出周期就是0.2s,但每5次溢出才产生一次更新事件,即1s中才产生更新事件及中,并在中断里完成PA5的电平翻转。

   

   

   
通过CUBEMX依据上述参数完成配置,并开启TIM1的更新中断使能,然后生成工程。

   
再在用户代码里添加应用代码:
HAL_TIM_Base_Start_IT(&htim1);
该函数使能TIM1的更新中断允许位,并软件启动定时器TIM1计数器的工作。
跟实验1一样,还是在中断服务程序里添加切换LED亮暗的代码。编译下载后即可看结果了。最终,可以看出,虽然定时器的时基参数不一样,最后结果跟实验1是完全一样的。
实验三
TIM1/ 每1s切换PA5电平驱动LED灯
还是使用高级定时器TIM1,不过时钟源这次选择来自于定时器外部的触发输入脚,即ETR脚。这里我们用定时器3的PWM输出模式输出10MHz的脉冲信号并通过连线连接到TIM1的外部触发输入端ETR脚,并作为TIM1的计数器时钟源。
前面在介绍时钟源时,提到过来自ETR脚的时钟信号有两路走法。
一路走法是:
来自引脚ETR过来的信号经过极性选择、分频、滤波后的信号并连接到从模式控制器,为计数器提供时钟源。此时定时器工作在从模式。
另外一路走法是:
来自ETR脚的时钟信号经过极性选择、分频、滤波后不连接到从模式控制器,而像内部时钟源一样为计数器提供时钟;这时基于该时钟定时器工作在主模式。
顺便提醒下,这里提到的分频跟后面连接到时基单元后的分频不是一回事。这里的分频是指对来自ETR脚的时钟信号在连接到计数器之前做分频,当然这个分频也不是必须的,要视具体信号频率来定。
我们这里使用第2种用法,即来自ETR脚的时钟信号经过极性选择、分频、滤波后不连到从模式控制器,而是直接提供给计数器时钟控制单元,并在连接到计数器之前也不对其做分频。

   
TIM1的时基参数的配置
1、来自ETR脚的外部时钟作为计数器时钟源,10Mhz。
2、设置计数器的分频比,选择计数模式、设置计数脉冲个数、RCR的值【这个RCR不是必须
  用的】
先对时钟源100分频、即PSC=100-1;
选择向上计数模式up counting;
计数器基于分频后的脉冲每计数10000个就发生溢出,则:ARR=10000-1
计数器每发生10次溢出动作产生更新事件,则: RCR=10-1
这样的话,每两次更新事件所对应的时间间隔也正好是1s.

   

   
通过STM32CUBEMX依据上述参数完成配置,注意在NVIC设置栏开启TIM1的更新中断使能,然后生成工程。再在用户代码里添加应用代码。
HAL_TIM_Base_Start_IT(&htim1);
在该代码里使能TIM1的更新中断允许位,并软件启动计数器的工作。
同样,在更新中断服务程序里添加切换LED亮暗的代码。编译下载后即可看结果了。照样可以看到跟上面两个实验完全相同的结果。
三个实验的比较小结:

   
到此定时器基本定时功能实验就完毕了。主要目的希望通过实验了解时基单元里几个寄存器的配置和使用。实验中涉及到定时器时钟源、更新事件等概念,希望通过实验加深印象和理解,也希望就实验中涉及的概念做些整理、回顾。比方定时器时钟源,前面在做了原理性介绍时,提到过定时器时钟源一般来讲有多种,这里只用到两类,其它的一般用在什么场合呢。当然,这些基础的东西,在后面实验中肯定会再次提到或用到。
另外,就今天的实验以及涉及到的内容做几点提醒:
1、在对时钟源做分频时,注意实际分频比等于分频寄存器PSC+1;
2、计数器使用单向计数【向上或向下计数】时,实际计数脉冲个数等于ARR+1;
3、使用高级定时器的RCR寄存器时,注意,是每发生RCR+1次溢出才产生更新事件并可以触
  发更新中断;
4、使用定时器内部时钟源时,其时钟频率并不一定等于与其相连的总线时钟,它完全可能高
  于与其相连的总线时钟;因为外设总线时钟与定时器内部时钟之间往往有个倍频器。
最后留下几个思考题,有兴趣的话可以去自行回顾与思考:
1、上面的实验用到哪几种定时器时钟源?还有哪些没用到?
2、定时器的溢出发生在什么时刻?重装又发生在什么时刻?重装些什么?
3、定时器的溢出事件与更新事件是什么关系?差别是什么?
4、通用定时器与高级定时器因溢出而发生更新事件有什么差异?
对于上述问题可以自行查看手册或之前的原理介绍。今天就聊到这里,下期会就定时器的输入捕获测量脉冲宽度及占空比的实验做些分享介绍,敬请关注。谢谢!
举报

更多回帖

发帖
×
20
完善资料,
赚取积分