基于keil5梁山派GD32F450的定时器配置&相关实验
说明:
上一期我们通过外部中断在主函数跑流水灯同时在外部中断服务函数中添加按键触发串口打印功能,理解了中断的原理和机制,这一期我们将从定时器配置开始讲起,同时配置定时器中断服务函数,到点执行对应功能,同时主函数流水灯和外部中断不受影响,功能一起同时实现。 首先,第一步我们先对定时器进行有个基本的认识,第二步我们需要对定时器进行相关的初始化配置,第三步编写定时器中断服务函数,第四步,查看现象我们预设的现象应该是定时器到点执行串口打印,主函数流水灯不受影响正常执行,外部中断通过按键触发中断请求去执行相应的中断功能。
文章目录
- 系列文章目录
- 一、定时器的基础知识
- 1、什么是定时器
- 2、GD32 定时器
- 3、定时器基本参数
- 二、定时器初始化相关配置
- 1.开启定时器时钟
- 2.配置定时器参数
- 3.配置中断优先级
-
4.使能中断和定时器
- 三、定时器中断功能实验
- 1、定时器中断服务函数
- 2、功能添加
- 3、主函数调用定时器timer5初始化函数
- 四、现象
- 总结
提示:以下部分参考于梁山派开发板学习指南,代码如有更有解可在评论区一起沟通交流哈。
一、定时器的基础知识
1、什么是定时器
定时器是单片机内部集成,可以通过编程控制。单片机的定时功能是通过计数来实现的,当单片机每一个机器周期产生一个脉冲时,计数器就加一。定时器的主要功能是用来计时,时间到达之后可以产生中断,提醒计时时间到,然后可以在中断函数中去执行功能。比如我们想让一个 led
灯1
秒钟翻转一次,就可以使用定时器配置为 1
秒钟触发中断,然后在中断函数中执行
led
翻转的程序。
2、GD32 定时器
GD32F450ZGT6 一共有 14
个定时器,可以分为五种类型,高级定时器
0/7
、通用定时器
(L0)1-4
、通用定时器(L1)8/11
、通用定时器
(L2)9/10/12/13
和基本定时器
5/6
。不同类型的定时器所拥有的功能数量不同,一般高级定时器的功能最多,通用定时器次之,基本定时器功能最少。具体功能对照可以查看用户手册的第 356
页。
3、定时器基本参数
预分频
预分频器可以将定时器的时钟(TIMER_CK)
频率按
1
到
65536
之间的任意值分频,分频后的时钟PSC_CLK 驱动计数器计数。分频系数受预分频器
TIMERx_PSC
控制。这个控制寄存器带有缓冲器,它能够在运行时被改变。新的预分频器的参数在下一次更新事件到来时被采用。
分频器的分频公式为:
PSC_CLK = TIMER_CK/ (TIMERx_PSC +1)
向上计数模式
计数器从 0
开始向上连续计数到自动加载值(定义在
TIMERx_CAR
寄存器中),一旦计数器计数到自动加载值,会重新从 0
开始向上计数并产生上溢事件。
更新事件
更新事件是当计数器上溢或者下溢而开始新的计数周期时触发的。更新事件可以触发 DMA
请
求,以用于在下一个计数周期开始时及时更新定时器的运行参数,特别适合用于实时控制。
二、定时器初始化相关配置
说明:接下来以定时器5为例:
1.开启定时器时钟

从用户手册时钟树可以看到
14
个定时器的时钟来源主要分为两部分,第一部分来源于
CK_APB1
,第二部分来源于 CK_APB2
。然后经过时钟配置寄存器(
RCU_CFG1
)决定是
APB
频率的
2
倍还是
4
倍,但这个频率不能超过 AHB
(
max = 200MHZ
)。
这里使用 TIMER5
,就要先使能
TIMER5
的时钟,又因为
TIMER5
时钟来源于
CK_APB1
,
CK_APB1的时钟在 system_gd32f4xx.c 中定义
。
可以看到
APB1
的时钟等于
AHB 的
时钟 4
分频,
AHB
的时钟等于系统时钟
SYSCLK
。
可以看到系统时钟等于__SYSTEM_CLOCK_200M_PLL_25M_HXTAL
,跳转到这个宏定义可以得知,这个宏定义的
值就是
(uint32_t)(200000000)
,可见系统时钟为
200MHZ
。回过来看
CK_APB1
的时钟为
200MHZ
的
4 分频等于 50MHZ
。要设置定时器的时钟为
200MHZ
,从时钟树上可以看到还需要进行
4
倍频处理,因此我们在代码里面还需要配置为 4
倍频。




2.配置定时器参数
配置结构体的参数说明:
*prescaler:这个参数是时钟的预分频值,是 16 位的,取值范围为 1-65535。从图 1-2-1 可以看到,TIMER_CK 经过预分频之后得到 PSC_CLK。每经过一个 PSC_CLK 都会产生一个计数周期,prescaler 参数将决定一个计数周期的时间。设预分频值为 pre,则计数器时钟频率 PSC_CLK=TIMER_CK / (pre + 1)。
*alignedmode:对齐模式暂没用到。
*counterdirection:计数模式,基本定时器只有向上计数模式,所以配置TIMER_COUNTER_UP。
*period:周期值,是一个 16 位的计数器,最大值为 65535,当计数器达到设置的周期数值(自动 重装载寄存器)时数值清零,配合计数器时钟频率可以计算中断时间。
*clockdivision:时钟分频,在输入捕获的时候使用,定时器时钟频率与死区发生器和数字滤波器使
用的采样频率之间的分频比。
*repetitioncounter:
重复计数器(只有高级定时器有),取值范围为
0-255
,配置为
x
,就重复
x+1
次才进入中断
3.配置中断优先级

4.使能中断和定时器

说明:
void timer_interrupt_enable(uint32_t timer_periph, uint32_t interrupt);
这个函数是使能定时器中断,有两个参数,第一个参数就是定时器外设,第二个参数是中断源的选择,这里我们选择TIMER_INT_UP,即选择更新事件中断源:
三、定时器中断功能实验
1、定时器中断服务函数
在中断处理函数里需要检测中断标志位是否被置位。
FlagStatus timer_interrupt_flag_get(uint32_t timer_periph, uint32_t interrupt);
这个函数是获取中断标志位。有两个参数,第一个参数就是要检测的定时器外设,第二个参数就是触发的中断源。有一个返回值 FlagStatus
,返回值的状态为
SET
和
RESET
。需要注意的是每次中断执行完毕之后都需要清除一下中断标志位等待下一次中断发生。

2、功能添加
我们分别在主函数死循环、外部中断和定时器中断都添加对应功能,其中外部中断和主函数延续上一期的功能就行,然后我们在定时器添加到点打印的功能:

3、主函数调用定时器timer5初始化函数
给定参数设置1秒进1次定时器5中断,在主函数while(1)实现流水灯功能,继续上一期外部中断的功能:


四、现象
主函数正常跑流水灯,外部中断按键触发中断请求打印按键信息,定时器每1秒打印数据:
总结
这一期是定时器的相关初始化配置,以及实现了中断的简单实验,让我们更清楚的体会到定时器和中断的原理和机制,在单片机应用中定时器的使用是非常广泛的,学透定时器的原理也需要在实战中多运用多体会。