3. 时钟与延时
本节介绍
📝本节您将了解 F28P550 的时钟树,以及如何配置系统时钟频率,并且了解 SDK 下封装好的延时功能。
🏆本章⽬标
1️⃣了解主控 F28P550 的 时钟树。
2️⃣了解如何使用已经封装好的延时函数功能。
3️⃣了解如何通过图形化代码生成工具 sysconfig 配置时钟频率。
4️⃣应用以上知识配置为指定时钟频率,并实现 LED 间隔 1 秒闪烁。
时钟树介绍
时钟源
芯片上所有的时钟均来自四个时钟源中的一个,分别是INTOSC2、INTOSC1、AUXCLKIN、XTAL。
INTOSC2
INTOSC2 为主内部振荡器。上电时,器件由片内10MHz振荡器(INTOSC2)提供时钟。INTOSC2是主要的内部时钟源,也是复位时的默认系统时钟。该振荡器用于运行引导ROM,并可作为应用程序的系统时钟源。
需注意:INTOSC2的频率容差范围较宽,无法满足CAN模块的时序要求。使用CAN模块时必须外接振荡器。当INTOSC2作为系统时钟源时,GPIO19(X1)和GPIO18(X2)可作为通用GPIO引脚使用。
INTOSC1
INTOSC1 为备份内部振荡器,一个冗余的片上10MHz振荡器。INTOSC1作为备用时钟源,默认仅用于看门狗定时器和缺失时钟检测电路(MCD)的时钟供给。若启用MCD功能且检测到系统时钟丢失,则系统PLL会被旁路,所有系统时钟会自动连接到INTOSC1。此外,开发者也可手动选择INTOSC1作为系统时钟源,用于调试目的。
AUXCLKIN
AUXCLKIN 为辅助时钟输入。器件支持通过 GPIO29(AUXCLKIN)引脚接入额外的外部时钟源。该时钟必须为单端3.3V的外部时钟信号,可用作MCAN模块的时钟源。其频率限制和时序要求详见《TMS320F28P55x实时微控制器数据手册》。该外部时钟可直接连接至GPIO29引脚。
XTAL
XTAL 为外部时钟源。可以作为主系统和CAN1位时钟源使用。外部时钟源使用 X1/GPIO19 和 X2/GPIO18 引脚输入。它支持3种输入信号的方式:
- 一个单端3.3V外部时钟,可以直接连到X1,X2可以作为GPIO使用。
- 一个外部晶振,该晶振可通过X1和X2连接起来,同时负载电容也需要连接到位。
- 一个外部谐振器,通过X1和X2与地相连。
开发板在GPIO18 和 GPIO19 接了一个 20MHz 的无源晶振。
完整时钟树
![]() |
---|
延时介绍
在 TI 的工程模板中,给我们准备好了一个可以微秒时间的延时函数:DEVICE_DELAY_US(x)
。
![]() |
---|
使用方法也很简单,要延时多少微秒,就往里面填多少值就好了。
说明
需要注意的是其参数中 DEVICE_SYSCLK_FREQ
为默认的150MHz,如果我们的主频被修改了,它就不准确了。除非我们主动修改 DEVICE_SYSCLK_FREQ
为我们修改后的主频。
功能扩展
后面的代码可以以微秒作为基数,将其再度封装出延时毫秒、秒的功能。这样在处理一些软件时序时就有了延时功能。
void delay_ms(int x)
{
while(x--)
{
DEVICE_DELAY_US(1000);
}
}
void delay_s(int x)
{
while(x--)
{
delay_ms(1000);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
案例实验介绍
使用外部时钟源:20MHz 的外部晶振输入,将工程原本的 150MHz 主频配置为 50MHz,通过 CCS 自带的 CIO 功能输出当前主频,并在主循环中执行 LED 间隔 1 秒闪烁的代码。
工程创建
打开CCS,创建一个新的基于 F28P55X 的工程。
![]() | ![]() |
---|---|
工程配置
配置工程选项,将我们后面写好的代码烧录到 FLASH 中,并且使用的烧录模式是 cJTAG(1149.7)2-pin 模式。
![]() | ![]() |
---|---|
时钟主频配置
打开工程下的 .syscfg 文件。该文件为该工程的图形化代码生成工具的索引文件。
如果有弹出 Select Device 提示框,则依次选择 TMS320F28P550SJ - 128PDT - TMS320F28P550SJ9 选项。
![]() |
---|
在时钟树选项页下,选择 CPUCLK 选项,开始对 CPUCLK 时钟树进行配置。
使能
XTAL
时钟源,其输入频率为 20MHz。XRAL_OR_X1
中选择 XTAL。OSCLKSRCSEL
中选择使用 X1_XTAL。在 SYSPLL 中的
PLL_REFDIV
中,选择 1 分频。在 SYSPLL 中的
PLL_IMULT
中,选择 30 倍频。在 SYSPLL 中的
PLL_ODIV
中,选择 2 分频。在
SYSCLKDIVSEL
中,选择 6 分频。最终得到主频
CPUCLK
频率为 50MHz。
![]() |
---|
![]() |
---|
LED灯配置
配置板载的蓝灯引脚 GPIO20 为输出模式。
![]() |
---|
开启 CIO 功能
CIO 是 CCS 中自带的一个 C语言输入输出操作。想必大家应该知道 C语言 的经典 printf()
,在以前我们想要使用printf输入调试日志,还需要调配串口通信外设功能。而在 CCS 中,只要你开启了堆栈,你就可以使用 CCS 内部的 printf 输出,输出在 CCS 的 CIO 显示框中。关于 CIO 的使用参考 TI 原文:Tips for Using Printf
使用 CIO 的步骤:
导入 stdio.h 文件
include "stdio.h"
每个使用C I/O函数的模块都应该包含
stdio.h
。如果不这样做,可能会使C I/O函数,特别是 printf 失败,而不会由编译器、链接器或调试器产生警告。printf 函数是一个可变函数,在没有有效原型的情况下调用这样的函数会导致未定义的行为。设置堆栈为
0x400
大多数标准的C I/O函数都操作于流。流是指stdout、stdin、stderr或任何用fopen打开的文件。每个流都需要自己的I/O缓冲区,如果用户没有提供,系统会在用户第一次读或写时自动动态地为用户分配一个。该缓冲区的大小为BUFSIZ(在stdio.h中定义),对于所有目标默认为256字节。
对于不使用TI-RTOS的项目:在 项目右键 -> Properties... -> Build -> C2000 Linker -> Basic Options->堆大小(- Heap)输入堆大小,建议为0x400
打开 CIO 显示栏
在 查看 -> Console -> CIO 中打开CIO显示栏。
显示栏在CCS的下方:使用 printf
在项目中直接 printf
使用即可。
相关函数介绍
//******************************************************************************
//
//! 计算系统时钟频率(SYSCLK)。
//!
//! \param clockInHz 为振荡器时钟源(OSCCLK)的频率。
//!
//! 本函数根据振荡器时钟源频率(来自\e clockInHz)以及PLL和时钟分频器配置寄存器,
//! 确定系统时钟频率。
//!
//! \return 返回系统时钟频率。若检测到时钟缺失,函数将返回INTOSC1频率。在再次调用
//! 本函数前,需先修正并清除该错误(参见SysCtl_resetMCD())。
//
// *****************************************************************************
extern uint32_t SysCtl_getClock(uint32_t clockInHz);
//******************************************************************************
//
//! 配置设备时钟系统。
//!
//! \param config 为设备时钟系统的所需配置。
//!
//! 本函数用于配置设备时钟系统。输入晶振频率、使用的振荡器、PLL的使用以及系统时钟
//! 分频器等均通过此函数配置。
//!
//! \e config参数为多个不同值的逻辑或组合,其中许多值分组设置,每组仅能选择一项。
//!
//! - 系统时钟分频器通过宏\b SYSCTL_SYSDIV(x)选择,其中x为1或最大至126的偶数值。
//!
//! - PLL使用方式通过下列选项之一选择:
//! \b SYSCTL_PLL_ENABLE - 启用PLL时钟作为系统时钟
//! 或
//! \b SYSCTL_PLL_BYPASS - 旁路PLL时钟至系统(若用户需要启动PLL但不用于系统)
//! 或
//! \b SYSCTL_PLL_DISABLE- 关闭PLL并旁路PLL时钟至系统
//!
//! - 整数倍频器通过\b SYSCTL_IMULT(x)选择,其中x为1至127的数值。
//!
//! - 振荡器源可选择:
//! \b SYSCTL_OSCSRC_OSC2、\b SYSCTL_OSCSRC_XTAL、
//! \b SYSCTL_OSCSRC_XTAL_SE或\b SYSCTL_OSCSRC_OSC1。
//!
//! 本函数使用DCC校验PLLRAWCLK是否以预期速率运行。若使用DCC,必须在调用本函数前
//! 备份其配置,并在调用后恢复。仅当倍频器更新时才执行PLL锁定序列。
//!
//! \note 有关锁定PLL的详细信息,请参阅设备勘误表。
//!
//! \return 若检测到时钟缺失错误返回\b false(需先调用SysCtl_resetMCD()清除)。
//! 若PLLRAWCLK未按预期速率运行也返回\b false。否则返回\b true。
//
//******************************************************************************
extern bool SysCtl_setClock(uint32_t config);
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
案例验证
时钟初始化修改
我们修改的时钟树配置代码生成在 clocktree.h 文件中,主要是其中的 DEVICE_OSCSRC_FREQ
、DEVICE_SETCLOCK_CFG
、DEVICE_SYSCLK_FREQ
宏定义。
而工程下有一个默认配置文件 device.h,其中进行了工程默认时钟主频的配置,它也定义了 DEVICE_SETCLOCK_CFG
等3个宏定义。为了不冲突,我们将 clocktree.h 中定义的频率调整后的宏定义直接覆盖更新到 device.h 中。
#define MY_DEVICE_OSCSRC_FREQ 20000000U
//
// Define to pass to SysCtl_setClock(). Will configure the clock as follows:
// SYSPLL ENABLED
// SYSCLK = 50 MHz = 20 MHz (OSCCLK) * 30 (IMULT) / (1 (REFDIV) * 2 (ODIV) * 6 (SYSCLKDIVSEL))
#define MY_DEVICE_SYSCLK_FREQ ((DEVICE_OSCSRC_FREQ * 30) / (1 * 2 * 6))
//
#define MY_DEVICE_SETCLOCK_CFG (SYSCTL_OSCSRC_XTAL | SYSCTL_IMULT(30) | \
SYSCTL_REFDIV(1) | SYSCTL_ODIV(2)| \
SYSCTL_SYSDIV(6) | SYSCTL_PLL_ENABLE | \
SYSCTL_DCC_BASE_0)
2
3
4
5
6
7
8
9
10
11
![]() | ![]() |
---|---|
更新主函数代码
更新工程的 empty_driverlib_main.c
文件为以下代码:
#include "driverlib.h"
#include "device.h"
#include "board.h"
#include "c2000ware_libraries.h"
#include "stdio.h" //导入用以支持 printf
//任意毫秒延时
void delay_ms(int x)
{
while(x--)
{
//调用 TI 自带的微秒延时
DEVICE_DELAY_US(1000);
}
}
void main(void)
{
Device_init();
Device_initGPIO();
Interrupt_initModule();
Interrupt_initVectorTable();
Board_init();
C2000Ware_libraries_init();
EINT;
ERTM;
//重新配置系统时钟
SysCtl_setClock(DEVICE_SETCLOCK_CFG);
//获取当前主频并输出
printf("clk = %ld\r\n", SysCtl_getClock(DEVICE_OSCSRC_FREQ) );
while(1)
{
GPIO_togglePin(GPIO_BLUE);//蓝灯的引脚状态切换
delay_ms(1000);//延时1000ms
}
}
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
下载器连接
XDS110下载器 | 开发板 |
---|---|
SWD | SWD/TMS |
CLK | CLK/TCK |
GND | GND |
5V | 5V |
代码烧录
GIF 动图
案例现象
CIO显示栏会输出当前主频为 50MHz(50000000),同时板载的蓝色LED灯以 1秒 的间隔进行闪烁。