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的中断:
void CPUTimer0_Init(void)
{InitCpuTimers();// ConfigCpuTimer(&CpuTimer0, 100, 500000); // 100MHz 500msConfigCpuTimer(&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 7PieCtrlRegs.PIEIER1.bit.INTx7 = 1;CpuTimer0Regs.TCR.bit.TSS = 0;
}这段代码的作用和与 DEVICE_SYSCLK_FREQ的关系
1. 函数功能解析
ConfigCpuTimer()函数用于配置 C2000 DSP 的 CPU 定时器(如 CpuTimer0),其参数和关键操作如下:
参数/操作 | 说明 |
|---|---|
| 定时器结构体(如 |
| CPU 时钟频率(单位 MHz),此处传入 |
| 定时器周期(单位 μs),此处传入 |
| 设置定时器周期值, |
| 预分频器 = 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)。
