定时器
本节介绍
📝本节您将了解 CPU 定时器以及使用方法,通过图形化代码生成工具配置实现定时1秒让LED闪烁的功能。
🏆本章⽬标
1️⃣了解CPU定时器。
2️⃣了解如何通过图形化代码生成工具 sysconfig 配置CPU定时器。
3️⃣应用以上知识实现定时1秒让LED闪烁的功能。
什么是定时器
定时器是单片机内部集成,可以通过编程控制。单片机的定时功能是通过计数来实现的
,当单片机每一个机器周期产生一个脉冲时,计数器就加一。所以定时器也可以说是计数器。定时器的主要功能是用来计时,时间到达之后可以产生中断,提醒计时时间到,然后可以在中断函数中去执行功能。比如我们想让一个led灯1秒钟翻转一次,就可以使用定时器配置为1秒钟触发中断,然后在中断函数中执行led翻转的程序。
F28P550的CPU定时器
F28P550的CPU定时器有3个,Timer0、Timer1和Timer2。 它们是完全一样的 32 位计时器
,具有可预设定周期
和 16 位时钟预分频
。此计时器具有 32 位递减计数寄存器,该寄存器在计数器达到 0 时生成一中断。
计数器以 CPU 时钟速度 除以 预分频值设置 形式递减。当计数器达到 0 时,则自动重新加载 32 位周期值。
CPU 计时器 0 用于普通用途并连接至 PIE 块。
CPU 计时器 1 也用于普通用途,并连接至 CPU 的 INT13。
CPU 计时器 2 为 TI-RTOS 保留。该计时器连接至 CPU 的 INT14。如果未使用 TI-RTOS ,CPU 计时器 2 也可用于普通用途。
![]() |
---|
计数与定时的转换
CPU 计时器 0 和 CPU 计时器 1 使用的是 SYSCLK 时钟,默认为150MHz。
![]() |
---|
CPU 计时器 2 的时钟可由下列任一时钟来源:
- SYSCLK(默认)
- 内部振荡器 1(INTOSC1)
- 内部振荡器 2(INTOSC2)
- X1 (XTAL)
定时器时间换算
假设使用CPU 计时器 0,其使用的时钟源是 SYSCLK,它默认的频率 = 150MHz
period 为设置的定时器周期
Prescaler 为时钟预分频
则定时时间为:
定时时间 = (Period + 1) * (Prescaler + 1) / 定时器频率
案例实验介绍
使用定时器每隔一秒让板载的蓝色LED灯状态切换一次,亮边灭,灭变亮。
工程创建
打开CCS,创建一个新的基于 F28P55X 的工程。
![]() | ![]() |
---|---|
工程配置
配置工程选项,将我们后面写好的代码烧录到 FLASH
中,并且使用的烧录模式是 cJTAG(1149.7)2-pin
模式。
![]() | ![]() |
---|---|
定时器的配置
打开工程下的 .syscfg 文件。找到 CPUTIMER 选项开始配置:
- 使用CPITIMER 0,则默认频率为150MHz
- 预分频值Prescaler = 0
- 周期Period = 149,999,999
- 开启定时器中断,并配置中断服务函数
![]() |
---|
图中,我们配置了 预分频值Prescaler = 0,周期Period = 149,999,999,则定时时间为:
定时时间 = (Period + 1) * (Prescaler + 1) / 定时器频率 = (149,999,999 + 1) * 1 / 150,000,000 = 1 秒
因为计数器是一个向下计数的模式,则计数器从 149,999,999 减到 0 时,一共会花费 1 秒的时间。
每记一个数所花费的时间 = 1 / 预分频后的定时器频率 = 1 / 150,000,000 = 6.6667 纳秒。
LED的配置
因为案例中用到了蓝色LED灯用来展示状态,所以还需要配置LED灯的引脚为输出模式。
![]() |
---|
相关函数介绍
//*****************************************************************************
//
//! 停止CPU定时器。
//!
//! \param base 是定时器模块的基地址。
//!
//! 该函数用于停止CPU定时器。
//!
//! \return 无。
//
//*****************************************************************************
static inline void CPUTimer_stopTimer(uint32_t base);
//*****************************************************************************
//
//! 启动(或重新启动)CPU定时器。
//!
//! \param base 定时器模块的基地址。
//!
//! 该函数用于启动(或重新启动)CPU定时器。
//!
//! 注意:此函数会重载定时器计数器。
//!
//! \return 无。
//
//*****************************************************************************
static inline void CPUTimer_startTimer(uint32_t base);
/*****************************************************************************
//
//! 启动(或恢复)CPU定时器。
//!
//! \param base 定时器模块的基地址。
//!
//! 该函数用于启动或恢复CPU定时器的运行。
//!
//! 注意:此函数不会重置定时器计数器。
//!
//! \return 无。
//
//*****************************************************************************/
static inline void CPUTimer_resumeTimer(uint32_t base);
//*****************************************************************************
//
//! 重载定时器计数器。
//!
//! \param base 定时器模块的基地址。
//!
//! 该函数将CPU定时器周期寄存器中的值重新加载到定时器计数器。
//!
//! \return 无。
//
//*****************************************************************************/
static inline void CPUTimer_reloadTimerCounter(uint32_t base);
//*****************************************************************************
//
//! 获取当前定时器计数值。
//!
//! \param base 定时器模块的基地址。
//!
//! 该函数返回当前CPU定时器计数器的数值。
//!
//! \return 返回当前定时器计数值。
//
//*****************************************************************************/
static inline uint32_t CPUTimer_getTimerCount(uint32_t base);
//*****************************************************************************
//
//! 获取定时器溢出状态。
//!
//! \param base 定时器模块的基地址。
//!
//! 该函数返回CPU定时器的溢出状态。
//!
//! \return 若定时器已溢出返回true,否则返回false。
//
//*****************************************************************************/
static inline bool CPUTimer_getTimerOverflowStatus(uint32_t base);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
案例验证
更新主函数代码
更新工程的 empty_driverlib_main.c 文件为以下代码:
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "c2000ware_libraries.h"
void main(void)
{
Device_init();
Device_initGPIO();
Interrupt_initModule();
Interrupt_initVectorTable();
Board_init();
C2000Ware_libraries_init();
EINT;
ERTM;
while(1)
{
}
}
//定时器中断服务函数
__interrupt void INT_myCPUTIMER0_ISR(void)
{
//蓝灯LED的状态翻转
GPIO_togglePin(GPIO_BLUE);
//清除中断标志位
Interrupt_clearACKGroup(INTERRUPT_ACK_GROUP1);
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
下载器连接
XDS110下载器 | 开发板 |
---|---|
SWD | SWD/TMS |
CLK | CLK/TCK |
GND | GND |
5V | 5V |
代码烧录
GIF 动图
案例现象
蓝色LED以1秒的间隔闪烁。