第2章 时钟树介绍及基础使用

第二章 时钟树介绍及基础使用

1. 时钟源

芯片上所有的时钟均来自四个时钟源中的一个,分别是INTOSC2、INTOSC1、AUXCLKIN、XTAL

1.1 INTOSC2

INTOSC2 为主内部振荡器。上电时,器件由片内10MHz振荡器(INTOSC2)提供时钟。INTOSC2是主要的内部时钟源,也是复位时的默认系统时钟。该振荡器用于运行引导ROM,并可作为应用程序的系统时钟源。

需注意:INTOSC2的频率容差范围较宽,无法满足CAN模块的时序要求。使用CAN模块时必须外接振荡器。当INTOSC2作为系统时钟源时,GPIO19(X1)和GPIO18(X2)可作为通用GPIO引脚使用。

1.2 INTOSC1

INTOSC1 为备份内部振荡器,一个冗余的片上10MHz振荡器。INTOSC1作为备用时钟源,默认仅用于看门狗定时器和缺失时钟检测电路(MCD)的时钟供给。若启用MCD功能且检测到系统时钟丢失,则系统PLL会被旁路,所有系统时钟会自动连接到INTOSC1。此外,开发者也可手动选择INTOSC1作为系统时钟源,用于调试目的。

1.3 AUXCLKIN

AUXCLKIN 为辅助时钟输入。器件支持通过 GPIO29(AUXCLKIN)引脚接入额外的外部时钟源。该时钟必须为单端3.3V的外部时钟信号,可用作MCAN模块的时钟源。其频率限制和时序要求详见《TMS320F28P55x实时微控制器数据手册》。该外部时钟可直接连接至GPIO29引脚。

1.4 XTAL

XTAL 为外部时钟源。可以作为主系统和CAN1位时钟源使用。外部时钟源使用 X1/GPIO19 和 X2/GPIO18 引脚输入。它支持3种输入信号的方式:

  1. 一个单端3.3V外部时钟,可以直接连到X1,X2可以作为GPIO使用。

  2. 一个外部晶振,该晶振可通过X1和X2连接起来,同时负载电容也需要连接到位。

  1. 一个外部谐振器,通过X1和X2与地相连。

2. 基于时钟的延时函数使用

在 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.1 硬件说明

使用外部时钟源:20MHz 的外部晶振输入,将工程原本的 150MHz 主频配置为 50MHz,通过 CCS 自带的 CIO 功能输出当前主频,并在主循环中执行 LED 间隔 1 秒闪烁的代码。

2.2 CCS工程

2.2.1 CCS&syscfg配置

在时钟树选项页下,选择 CPUCLK 选项,开始对 CPUCLK 时钟树进行配置。

  1. 使能 XTAL 时钟源,其输入频率为 20MHz。

  2. XRAL_OR_X1 中选择 XTAL。

  3. OSCLKSRCSEL 中选择使用 X1_XTAL。

  4. 在 SYSPLL 中的 PLL_REFDIV 中,选择 1 分频。

  5. 在 SYSPLL 中的 PLL_IMULT 中,选择 30 倍频。

  6. 在 SYSPLL 中的 PLL_ODIV 中,选择 2 分频。

  7. 在 SYSCLKDIVSEL 中,选择 6 分频。

  8. 最终得到主频 CPUCLK 频率为 50MHz。

配置板载的蓝灯引脚 GPIO20 为输出模式。

2.2.2 用户代码

我们修改的时钟树配置代码生成在 clocktree.h 文件中,主要是其中的 DEVICE_OSCSRC_FREQDEVICE_SETCLOCK_CFGDEVICE_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)

更新工程的 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
    }
}

3. 相关函数介绍

//******************************************************************************
//
//! 计算系统时钟频率(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);

posted @ 2025-07-19 16:18  hazy1k  阅读(17)  评论(0)    收藏  举报