本帖最后由 toofree 于 2019-1-15 12:32 编辑 $ [3 ^9 w" v* n# C0 J$ D 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”进行测试。
2 ^! q+ ^9 _& x4 d. |+ b 打开STM32CubeMX工程文件“TIM_TimeBase.ioc”,TIM2参数设置,预分频系数和自动装载值在程序中做了宏定义。
使用TIM2中断功能
使用设置内部时钟,设置系统时钟和TIM2时钟为56MHz。为了确定TIM2的时钟源,有必要在用户手册中确认。
! r+ O/ s. O$ [8 q; J 在用户手册中时钟树关系,找到TIM2时钟源,对应为STM32CubeMX中的TPCLK。
# ~& K6 t& Y( Q' k 用户手册中可以看到,TIM2和TIM3几乎相同,除了TIM2的计数寄存器和自动装载寄存器是32位。 TIM2的计数寄存器为32位
- a; e3 S7 K# T6 Y1 Z TIM2的自动装载寄存器为32位,TIM2/TIM3的预分频寄存器均为16位。
打开Keil工程,打开"readme.txt"文件,有本工程相关说明。虽是英文,但不难看懂,故无需解释。
" F5 N$ e3 K: V “main.c”文件中,主函数main,套路比较清晰。无非是设置时钟、设置LED、初始化设置TIM2、中断方式开启TIM2。
+ n8 T& H& e$ F- \ w% [ 系统时钟设置,可对照上面STM32CubeMX工程文件中的时钟树理解。
TIM2初始化函数中,使用了两个关键的宏定义,预分频和自动装载值。TIM2的中断回调函数,进一次中断,LED4状态翻转一次。
在“main.h”文件中有预分频和自动装载值宏定义。调用SystemCoreClock来计算预分频系数,预分频寄存器为16位,系数最小为0,最大为65535,因此这里的“10000”也不是乱选。相对来说自动装载参数设置就比较随意一些,32位数,从0到4294967295随意搞。只要这两个宏定义中的“10000”被相同的数代替,那得到的计数器中断频率始终保持1Hz。
先按编译默认工程,下载到开发板,可以看到时钟初始化完成后的SystemCoreClock时钟,的确为56MHz。
修改两个宏定义中的常数“10000”为“56000000”,这里用56000000,因为此数大于24位的最大值16777216,为了验证TIM2计数器的确为32位,而不是16位或24位。
" L4 U. s, b4 n- I 重新编译工程,Debug跟踪执行,可以看到TIM2的自裁装载寄存器ARR值为“3567DFF”,SystemCoreClock时钟为“3567E00”。
9 e7 E. }8 f' U" M0 q: n2 t" o SystemCoreClock时钟“3567E00”,对应十进制的“56000000”。
全速运行程序,可以看到板上LD4以0.5Hz的频率在闪烁。 本实验验证TIM2定时器的确为32位,32位定时器的好处就是,可以定好长好长的时间。16位的预分频寄存器和32位计数器配合,相当于一个48位的计数器,即便定时器时钟为100MHz,那么最大计数周期为(2^48-1)/100000000 = 2814749秒 = 32.5天。 (相同的方法,也可以测试TIM3为16位定时器。) ! ^9 A& _4 N+ u" n! l+ C' e$ @% Q8 _1 {9 l |
硬件定时器精度,取决于晶振精度和频度稳定度。