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=80MHz但 Freq=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中的定义,并同步调整 ConfigCpuTimer的 Freq参数:

    复制代码
    #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=100MHz,PRD=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)。

相关推荐
女神下凡1 小时前
芯参谋(26):DDR4_软件设计规范
arm开发·单片机·嵌入式硬件
zd8451015001 小时前
DSLogic逻辑分析仪连接失败
嵌入式硬件
国科安芯2 小时前
星载通信载荷信号处理中抗辐射微控制器的选型与适应性分析
人工智能·嵌入式硬件·mcu·信号处理·risc-v·抗辐射·空间信息
AOI小白新手上路3 小时前
韦东山 3-5 I.MX6ULL 的 LED 编程 · 学习笔记
arm开发·笔记·单片机·学习·架构·硬件架构
测试学习test3 小时前
SPI读取W25Q64硬件驱动(HAL库)
数据库·stm32·嵌入式硬件·算法
xingzhemengyou14 小时前
STM32对函数进行CRC校验
stm32·单片机·嵌入式硬件
FPGA小徐4 小时前
STM32引脚详解:PC13-TAMPER-RTC 多功能复用引脚完全剖析(踩坑+配置+布线)
单片机·嵌入式硬件
M78佐菲4 小时前
ARM学习笔记(9)
linux·arm开发·笔记·嵌入式硬件·学习
铅笔小新z4 小时前
【stm32】中断与异常
stm32·单片机·嵌入式硬件
沐欣工作室_lvyiyi5 小时前
无线遥控电动阀门开关模块设计(论文+源码)
单片机·无线遥控