
本帖最后由 toofree 于 2019-1-15 12:32 编辑 ' a8 z. t9 Y' @' d% A4 U NUCLEO-G071RB之——3、32位定时器TIM2测试 STM32G071有一个32位定时器TIM2,有必要测试一下。 直接使用STM32CubeMX中下载的STM32Cube_FW_G0_V1.0.0软件包,复制样例程序“STM32Cube_FW_G0_V1.0.0\Projects\NUCLEO-G071RB\Examples\TIM\TIM_TimeBase”,改名为“TIM_TimeBase_TIM2_32bits”进行测试。
* G* d1 d( |: R& K4 k' {1 z6 n 打开STM32CubeMX工程文件“TIM_TimeBase.ioc”,TIM2参数设置,预分频系数和自动装载值在程序中做了宏定义。
使用TIM2中断功能
使用设置内部时钟,设置系统时钟和TIM2时钟为56MHz。为了确定TIM2的时钟源,有必要在用户手册中确认。
在用户手册中时钟树关系,找到TIM2时钟源,对应为STM32CubeMX中的TPCLK。
! p7 k6 t$ V7 k3 N. }; T 用户手册中可以看到,TIM2和TIM3几乎相同,除了TIM2的计数寄存器和自动装载寄存器是32位。 TIM2的计数寄存器为32位
) I* @7 x0 y# i, ` TIM2的自动装载寄存器为32位,TIM2/TIM3的预分频寄存器均为16位。
6 y |% C* G) y& }+ `$ W5 q8 D 打开Keil工程,打开"readme.txt"文件,有本工程相关说明。虽是英文,但不难看懂,故无需解释。
, j+ y3 f# f; a, |7 @ “main.c”文件中,主函数main,套路比较清晰。无非是设置时钟、设置LED、初始化设置TIM2、中断方式开启TIM2。
3 |% _: r# W0 b6 A- @& x 系统时钟设置,可对照上面STM32CubeMX工程文件中的时钟树理解。
TIM2初始化函数中,使用了两个关键的宏定义,预分频和自动装载值。TIM2的中断回调函数,进一次中断,LED4状态翻转一次。
' P* x/ A; p: V# J5 |, b0 F, s 在“main.h”文件中有预分频和自动装载值宏定义。调用SystemCoreClock来计算预分频系数,预分频寄存器为16位,系数最小为0,最大为65535,因此这里的“10000”也不是乱选。相对来说自动装载参数设置就比较随意一些,32位数,从0到4294967295随意搞。只要这两个宏定义中的“10000”被相同的数代替,那得到的计数器中断频率始终保持1Hz。
* o. D/ u) l9 [% _( ]- b 先按编译默认工程,下载到开发板,可以看到时钟初始化完成后的SystemCoreClock时钟,的确为56MHz。
$ O: Q* t+ v4 b! H2 h 修改两个宏定义中的常数“10000”为“56000000”,这里用56000000,因为此数大于24位的最大值16777216,为了验证TIM2计数器的确为32位,而不是16位或24位。
$ F6 N1 w1 G$ L3 I; b 重新编译工程,Debug跟踪执行,可以看到TIM2的自裁装载寄存器ARR值为“3567DFF”,SystemCoreClock时钟为“3567E00”。
% J( C8 ]8 K# r& j0 P. H. m1 Q SystemCoreClock时钟“3567E00”,对应十进制的“56000000”。
全速运行程序,可以看到板上LD4以0.5Hz的频率在闪烁。 本实验验证TIM2定时器的确为32位,32位定时器的好处就是,可以定好长好长的时间。16位的预分频寄存器和32位计数器配合,相当于一个48位的计数器,即便定时器时钟为100MHz,那么最大计数周期为(2^48-1)/100000000 = 2814749秒 = 32.5天。 (相同的方法,也可以测试TIM3为16位定时器。) ) C' b2 Z8 v+ R/ v" W |
硬件定时器精度,取决于晶振精度和频度稳定度。