F280025的时钟设置

定时器的时间问题:

F280025C的时钟:最大时钟频率为100M

​关键宏​​:

  • DEVICE_OSCSRC_FREQ:外部晶振或内部振荡器频率(如 10 MHz)。

  • DEVICE_SYSCLK_FREQ:预期的系统时钟频率(如 100 MHz)。

  • DEVICE_LSPCLK_FREQ:预期的低速外设时钟频率(如 25 MHz,即 100 MHz / 4)。

1. 代码功能分解​

​(1) 配置主时钟(PLL 和分频器)​
SysCtl_setClock(DEVICE_SETCLOCK_CFG);
  • ​作用​​:设置 PLL(锁相环)和系统时钟分频器。

  • ​关键点​​:

    • DEVICE_SETCLOCK_CFG是一个宏,定义在 device.h中,指定了 ​​时钟源、PLL 倍频系数、系统时钟分频比​​。

    • 实际频率值(如 SYSCLK)需要通过 DEVICE_SYSCLK_FREQ计算。

​(2) 配置低速外设时钟(LSPCLK)​
SysCtl_setLowSpeedClock(SYSCTL_LSPCLK_PRESCALE_4);
  • ​作用​ ​:设置低速外设时钟(如 SCI、SPI 等)的分频系数为 ​​4 分频​​。

  • ​计算公式​ ​:LSPCLK = SYSCLK / 4

PLLSYSCLK = 20MHz (XTAL_OSC) * 30 (IMULT) / (2 (REFDIV) * 3 (ODIV) * 1(SYSDIV))

2. 如何查看实际配置的时钟频率?​

​(1) 检查 device.h中的定义​

打开 device.h文件,查找以下宏:

#define DEVICE_OSCSRC_FREQ 10000000UL // 例如:外部晶振 10 MHz #define DEVICE_SYSCLK_FREQ 100000000UL // 例如:系统时钟 100 MHz #define DEVICE_LSPCLK_FREQ (DEVICE_SYSCLK_FREQ / 4) // 例如:25 MHz #define DEVICE_SETCLOCK_CFG (SYSCTL_OSCSRC_OSC1 | SYSCTL_PLL_ENABLE | SYSCTL_PLL_MULT_10 | SYSCTL_SYSDIV_1)

  • DEVICE_SETCLOCK_CFG的组成​​:

    • SYSCTL_PLL_MULT_10:PLL 倍频系数为 10(假设输入 10 MHz,则 PLL 输出 100 MHz)。

    • SYSCTL_SYSDIV_1:系统时钟不分频(SYSCLK = PLL 输出 = 100 MHz)。

​(2) 运行时动态获取时钟频率​

在调试时,可以通过以下函数实时读取时钟值

uint32_t sysclk = SysCtl_getClock(DEVICE_OSCSRC_FREQ); // 获取 SYSCLK 实际值 uint32_t lspclk = SysCtl_getLowSpeedClock(DEVICE_OSCSRC_FREQ); // 获取 LSPCLK 实际值

  • 在 CCS 的 ​​Expressions 窗口​​ 添加这些变量,观察其数值是否符合预期。
​(3) 使用 CCS 的时钟树工具​
  • 在 CCS 中,通过 ​​Tools → Clock Tree​​ 可视化查看时钟配置(需芯片支持)。

​3. 关键计算公式​

​(1) 系统时钟(SYSCLK)​

SYSCLK = (OSCSRC_FREQ × PLL_MULT) / SYSDIV

  • 示例:

    • OSCSRC = 10 MHz, PLL_MULT = 10, SYSDIV = 1 → SYSCLK = 100 MHz.
​(2) 低速外设时钟(LSPCLK)​

LSPCLK = SYSCLK / LSPCLK_PRESCALE

  • 示例:

    • SYSCLK = 100 MHz, PRESCALE = 4 → LSPCLK = 25 MHz.

3. 我顶一个定时器为10ms的中断:

cpp 复制代码
void CPUTimer0_Init(void)
{
    InitCpuTimers();

//    ConfigCpuTimer(&CpuTimer0, 100, 500000);  // 100MHz 500ms
    ConfigCpuTimer(&CpuTimer0, 100, 10000);  // 100MHz 10ms

    // 指定中断服务函数地址
    EALLOW;
    PieVectTable.TIMER0_INT = &cpuTimer0ISR;
    EDIS;

    // 使能定时器中断
    CpuTimer0Regs.TCR.bit.TIE = 1;

    // Enable CPU INT1 which is connected to CPU-Timer 0:
    IER |= M_INT1;

    // Enable TINT0 in the PIE: Group 1 interrupt 7
    PieCtrlRegs.PIEIER1.bit.INTx7 = 1;

    CpuTimer0Regs.TCR.bit.TSS = 0;
}

​这段代码的作用和与 DEVICE_SYSCLK_FREQ的关系​

​1. 函数功能解析​

ConfigCpuTimer()函数用于配置 C2000 DSP 的 CPU 定时器(如 CpuTimer0),其参数和关键操作如下:

​参数/操作​ ​说明​
Timer 定时器结构体(如 CpuTimer0),包含寄存器地址、中断计数等。
Freq CPU 时钟频率(单位 MHz),此处传入 100,表示 ​​100MHz​​。
Period 定时器周期(单位 μs),此处传入 10000,表示 ​​10ms(10000μs)​​。
Timer->RegsAddr->PRD.all = temp 设置定时器周期值,temp = Freq * Period = 100 * 10000 = 1,000,000
Timer->RegsAddr->TPR.all = 0 预分频器 = 1(不分频),直接使用 SYSCLKOUT(100MHz)。
Timer->RegsAddr->TCR.bit.TIE = 1 使能定时器中断。

​2. 定时器周期计算​
  • ​输入参数​​:

    • Freq = 100(即 DEVICE_SYSCLK_FREQ = 100MHz)。

    • Period = 10000(10ms)。

  • ​计算公式​​:

    复制代码
    temp = Freq * Period;  // 100MHz × 10000μs = 1,000,000
    Timer->RegsAddr->PRD.all = temp;  // 写入周期寄存器
    • ​定时器实际周期​​:

      复制代码
      T=SYSCLKPRD+1​=100,000,0001,000,000​=0.01秒=10ms
    • ​关键点​ ​:PRD的值是基于 SYSCLK(100MHz)计算的,因此必须与 DEVICE_SYSCLK_FREQ一致!


​3. 与 DEVICE_SYSCLK_FREQ的关系​
  • Freq参数必须等于 DEVICE_SYSCLK_FREQ(单位 MHz)​

    如果 DEVICE_SYSCLK_FREQ定义为 100MHz,则 Freq应传入 100

    若二者不匹配(例如 DEVICE_SYSCLK_FREQ=80MHzFreq=100),定时器实际周期会错误:

    复制代码
    T实际​=80,000,0001,000,000​=12.5ms(非预期的10ms)
  • ​如何确保一致性?​

    推荐直接使用 DEVICE_SYSCLK_FREQ传入参数:

    复制代码
    ConfigCpuTimer(&CpuTimer0, DEVICE_SYSCLK_FREQ / 1000000, 10000);  // 100MHz → Freq=100

​4. 关键代码验证​
  • ​检查 device.h中的定义​​:

    复制代码
    #define DEVICE_SYSCLK_FREQ  100000000UL  // 必须是 100MHz
  • ​运行时验证定时器配置​​:

    复制代码
    printf("PRD = %lu, 预期周期 = %.2f ms\n", 
           CpuTimer0.RegsAddr->PRD.all,
           (float)(CpuTimer0.RegsAddr->PRD.all + 1) / (DEVICE_SYSCLK_FREQ / 1000000));

    ​输出​​:

    复制代码
    PRD = 1000000, 预期周期 = 10.00 ms

​5. 常见问题​
​Q1:如果 DEVICE_SYSCLK_FREQ不是 100MHz,如何调整?​
  • 修改 device.h中的定义,并同步调整 ConfigCpuTimerFreq参数:

    复制代码
    #define DEVICE_SYSCLK_FREQ  80000000UL  // 80MHz
    ConfigCpuTimer(&CpuTimer0, 80, 10000);  // 80MHz → 10ms 定时器
    • 此时 PRD = 80 * 10000 = 800,000
​Q2:为什么 PRD要设为 Freq * Period?​
  • 因为定时器每个时钟周期(1/SYSCLK)计数一次,PRD表示计数值:

    复制代码
    Period=(PRD+1)×SYSCLK1​
    • SYSCLK=100MHzPRD=999,999对应 10ms:

      复制代码
      999,999+1=1,000,000⇒T=100,000,0001,000,000​=0.01秒
​Q3:预分频器(TPR)为什么设为 0?​
  • TPR=0表示分频系数 = 1(不分频),定时器直接使用 SYSCLKOUT(100MHz)。

    若需更长的周期,可增大 TPR(例如 TPR=1表示分频系数 = 2)。


​总结​

  • ConfigCpuTimer(&CpuTimer0, 100, 10000)的作用​​:

    配置一个基于 100MHz 系统时钟的 10ms 定时器中断。

  • ​与 DEVICE_SYSCLK_FREQ的关系​​:

    Freq参数必须与 DEVICE_SYSCLK_FREQ(单位 MHz)严格一致,否则定时器周期会错误。

  • ​验证方法​​:

    检查 PRD寄存器的值是否符合预期计算(PRD = Freq * Period)。

相关推荐
GilgameshJSS4 小时前
STM32H743-ARM例程30-Modbus
c语言·arm开发·stm32·单片机·嵌入式硬件
nassi_5 小时前
开发板网络配置
linux·网络·嵌入式硬件
申克Lab5 小时前
STM32 系统定时器(精准延迟)
stm32·单片机·嵌入式硬件
瑞江无限5 小时前
南麟NP3401MR-M-G技术规格与应用全解析
单片机·嵌入式硬件
qq_401700416 小时前
自恢复保险丝
单片机·嵌入式硬件
三佛科技-134163842126 小时前
暖手宝方案开发,暖手宝MCU控制方案开发设计
单片机·嵌入式硬件·智能家居·pcb工艺
物随心转8 小时前
ARM的中断模式与快速中断模式
嵌入式硬件
朱嘉鼎10 小时前
寄存器编写LED程序
stm32·单片机·架构·keilmdk
点灯小铭11 小时前
基于单片机的智能厨房环境控制系统设计
单片机·嵌入式硬件·毕业设计·课程设计·期末大作业