TMS320F280013x CPU定时器与设备配置寄存器深度解析与实战

📅 2026/7/20 10:57:18
TMS320F280013x CPU定时器与设备配置寄存器深度解析与实战
1. 项目概述与核心价值在嵌入式实时控制领域尤其是工业电机驱动、数字电源和自动化设备中对时间的精准掌控是系统稳定和性能卓越的基石。TMS320F280013x作为德州仪器TIC2000系列中的一款高性能实时微控制器其内置的CPU定时器CPUTIMER是构建系统心跳、实现任务调度、生成PWM以及处理通信协议时序的核心硬件资源。然而仅仅知道定时器能“计时”是远远不够的真正的高手都懂得如何通过直接操作其底层寄存器来解锁最极致的性能、最灵活的配置以及最高效的中断管理。很多开发者习惯于依赖厂商提供的驱动库如TI的DriverLib进行开发这固然快捷但在遇到复杂时序要求、需要极致优化中断响应时间、或者排查一些玄学般的定时问题时往往就会感到力不从心。这时深入理解CPUTIMER以及与之相关的系统配置寄存器DEV_CFG_REGS就成为了从“会用”到“精通”的关键跨越。本文将以TMS320F280013x的数据手册为蓝本结合我多年在电机控制项目中的实战经验为你彻底拆解这些寄存器的每一个比特位。我们不仅会讲清楚它们是什么更会重点剖析为什么这么设计以及在实际编程中如何配置、有哪些坑需要避开。无论你是正在编写自己的裸机驱动还是想优化现有代码这篇文章都将提供你所需的底层细节和实战技巧。2. CPU定时器CPUTIMER_REGS寄存器深度解析CPU定时器是C2000内核的一个标准外设通常用于产生操作系统的时基或作为通用的高精度定时器。TMS320F280013x的CPUTIMER是一个32位递减计数器其工作时钟源于系统时钟SYSCLK经过一个可配置的预分频器。理解其寄存器组是进行精准定时控制的第一步。2.1 定时器寄存器总览与内存映射CPUTIMER_REGS寄存器组通过内存映射方式访问这意味着我们可以像操作普通变量一样通过指针来读写这些寄存器。其基地址由芯片的内存映射表定义通常在头文件如F280013x_Device.h中以类似CPUTIMER1_BASE的宏形式给出。整个寄存器组非常精简主要包含五个寄存器偏移地址从0h到7h。表2-1: CPUTIMER_REGS 寄存器映射表偏移地址 (Offset)缩写 (Acronym)寄存器全名 (Register Name)关键特性0hTIMCPU-Timer, Counter Register32位计数器当前值低16位在TIM高16位在TIMH2hPRDCPU-Timer, Period Register32位周期值低16位在PRD高16位在PRDH4hTCRCPU-Timer, Control Register控制寄存器包含中断使能、标志位、启停控制等6hTPRCPU-Timer, Prescale Register预分频计数器PSC和分频因子TDDR的低8位7hTPRHCPU-Timer, Prescale Register High预分频计数器PSCH和分频因子TDDRH的高8位注意数据手册中明确提到所有未在表中列出的偏移地址都是保留位置其内容不应被修改。在编程时务必确保只访问已知的寄存器地址避免对保留区域进行写操作这可能导致不可预测的行为。2.2 TIM与PRD计数器与周期寄存器的协同工作原理TIM计数器寄存器和PRD周期寄存器是定时器工作的核心。它们都是32位寄存器但在内存中分别由两个16位的寄存器TIM/TIMH, PRD/PRDH组成以适应C2000的16位数据总线架构。这种设计在访问时需要特别注意。TIM寄存器计数器这是一个递减计数器。上电或软复位后TIMH:TIM会被加载为0x0000FFFF即TIMH0TIM0xFFFF。定时器启动后在每个经过预分频后的时钟周期后面会详细解释这个32位的计数值会减1。PRD寄存器周期值这是定时器的“目标值”。当TIMH:TIM递减到0时在下一个定时器输入时钟周期开始时硬件会自动将PRDH:PRD的值重新加载到TIMH:TIM中同时产生定时器中断TINT信号。因此定时器的中断周期由以下公式决定中断周期 (PRDH:PRD 1) * (TDDRH:TDDR 1) * T_sysclk其中T_sysclk是系统时钟SYSCLK的周期。实操要点与常见误区初始化顺序在启动定时器前必须先配置PRD和TDDR预分频因子最后再配置TIM。一个常见的错误是先启动定时器再配置周期这会导致定时器从一个未知的计数值开始递减第一个中断周期是不确定的。32位访问虽然寄存器是16位的但TIM和PRD在功能上是32位实体。在C代码中我们通常使用联合体union和结构体struct来方便地以32位形式访问。例如TI的官方头文件会定义类似CPUTimer1Regs.TIM.all的变量来代表整个32位计数器。直接操作TIM和TIMH时需要注意字节序C2000是小端模式低字节在低地址。重载时机重载发生在计数器归零后的下一个定时器时钟边沿。这意味着从计数器归零到重新加载之间有一个时钟周期的“间隙”。在计算极精确的延时或测量高频信号时这个细节需要考虑进去。2.3 TCR控制寄存器的位级精解TCRTimer Control Register是定时器的“大脑”它控制着定时器的启停、中断管理以及仿真行为。每一位都至关重要。表2-2: TCR寄存器位功能详解位字段名类型复位值功能描述与操作指南15TIFR/W1C0h定时器溢出标志位。当TIMH:TIM递减到0时此位由硬件自动置1。它不会自动清零必须由软件写1来清除W1C: Write-1-to-Clear。关键点即使不清除TIF下一次定时器溢出仍然会发生并置位此位。中断服务程序ISR中通常首先要清除此位。14TIER/W0h定时器中断使能位。0禁止定时器中断1使能定时器中断。当TIE1且TIMH:TIM递减到0时定时器会向CPU发出中断请求。11FREER/W0h仿真运行控制位高位。与SOFT位共同决定在代码调试遇到断点时定时器的行为。10SOFTR/W0h仿真运行控制位低位。FREE和SOFT的组合决定了仿真行为FREE1自由运行Free Run。遇到断点时定时器继续计数。这是最常用的调试模式不影响定时器的实时性。FREE0, SOFT0硬停止Hard Stop。遇到断点时定时器在当前递减操作完成后立即停止。FREE0, SOFT1软停止Soft Stop。遇到断点时定时器继续运行直到计数归零即产生一次中断后停止。5TRBR/W0h定时器重载位。这是一个“脉冲”式操作位。软件向此位写1后会立即将PRDH:PRD的值加载到TIMH:TIM同时将TDDRH:TDDR的值加载到PSCH:PSC预分频计数器。写0无效读取此位永远为0。应用场景在需要同步或立即重启定时器时使用例如在改变周期值后手动触发一次重载使新周期立即生效。4TSSR/W0h定时器停止状态位。这是定时器的启停开关。0定时器正在运行/启动定时器1定时器已停止/停止定时器。特别注意芯片复位后TSS默认为0这意味着如果PRD和TDDR不是0定时器会立即开始递减因此安全的初始化流程是先停止定时器TSS1再配置PRD和TDDR最后启动定时器TSS0。经验分享中断标志位TIF的“陷阱”很多新手会在中断服函数ISR中忘记清除TIF位或者错误地写0来清除它。由于TIF是W1C类型写0是无效的。正确的做法是CPUTimer1Regs.TCR.bit.TIF 1;。虽然读取TIF位可以判断中断是否发生但在使能了中断的情况下通常进入ISR就意味着中断已发生直接清除即可。另外在轮询查询方式使用定时器时检测到TIF为1后也必须用同样的方式清除它。2.4 TPR与TPRH预分频机制全揭秘TPRPrescale Register和TPRH是其高位部分这两个寄存器共同实现了定时器的预分频功能极大地扩展了定时器的定时范围。预分频器由两部分组成预分频计数器PSC/PSCH和分频因子寄存器TDDR/TDDRH。工作原理分步解析时钟源定时器的原始时钟是SYSCLK。第一级分频预分频计数器PSC/PSCH是一个8位的递减计数器通过TPR和TPRH访问。它的初始值来自TDDR/TDDRH。SYSCLK每来一个脉冲PSC就减1。第二级分频产生定时器时钟只有当PSC/PSCH减到0时在下一个SYSCLK周期才会发生两件事a) 将TDDR/TDDRH的值重新载入PSC/PSCHb)主计数器TIMH:TIM减1。公式推导因此TIMH:TIM每递减1所经历的SYSCLK周期数 (TDDRH:TDDR 1)。这就是预分频系数。假设SYSCLK100MHzTDDR99那么定时器时钟频率 100MHz / (991) 1MHz定时器计数周期为1us。寄存器字段详解TDDR (TPR[7:0]) / TDDRH (TPRH[7:0])可读写。这是你设置的分频因子。有效范围是0-2558位因此预分频系数范围为1-256。实际分频系数 TDDRH:TDDR 1。PSC (TPR[15:8]) / PSCH (TPRH[15:8])只读。这是当前预分频计数器的值。你不能直接写入PSC它的值只能通过写入TDDR后由硬件在特定时刻PSC减到0或TRB置位加载。你可以读取它来了解预分频计数器的当前状态这在某些精细调试场合有用。配置示例假设需要产生一个1ms的中断SYSCLK 100MHz (周期10ns)。选择预分频系数为了不让32位周期值PRD过大我们可以先分频。设 TDDR 99则定时器时钟周期 (991)*10ns 1000ns 1us。计算PRD值1ms / 1us 1000次计数。因为计数器从PRD值递减到0所以需要计数的次数是PRD 1。因此PRD 1000 - 1 999 (0x3E7)。配置代码思路// 假设寄存器已通过头文件映射 CpuTimer1Regs.TCR.bit.TSS 1; // 1. 停止定时器 CpuTimer1Regs.PRD.all 999; // 2. 设置周期值 CpuTimer1Regs.TPR.all 99; // 3. 设置分频因子 (TDDR99, PSC会自动加载) CpuTimer1Regs.TIM.all 0xFFFFFFFF; // 4. 可选将计数器初始化为最大值或PRD值 CpuTimer1Regs.TCR.bit.TRB 1; // 5. 手动触发重载将PRD和TDDR值载入TIM和PSC CpuTimer1Regs.TCR.bit.TSS 0; // 6. 启动定时器 CpuTimer1Regs.TCR.bit.TIE 1; // 7. 使能定时器中断需配合PIE模块3. 设备配置DEV_CFG_REGS寄存器详解与应用DEV_CFG_REGS寄存器组提供了关于芯片身份、模块软件复位以及一些特定配置的接口。这些寄存器在系统初始化、故障恢复和功能配置中扮演着重要角色。3.1 器件标识与版本寄存器PARTIDL, PARTIDH, REVID这三个寄存器是只读的用于在软件中识别具体的芯片型号、封装和版本信息。这对于实现同一份代码兼容不同型号芯片、或者在生产测试中进行器件校验非常有用。PARTIDL (Part Identification Low) PARTIDH (Part Identification High)共同组成一个64位的器件部件号。其中包含关键信息FAMILY (PARTIDH[15:8])固定为0x05代表C2000系列下的特定子系列。PARTNO (PARTIDH[23:16])具体的部件编号需要对照数据手册查询用于区分F2800135, F2800137等具体型号。PIN_COUNT (PARTIDL[10:8])封装引脚数编码。例如056-pin QFN 380-pin QFP。你的代码可以根据这个值来动态配置GPIO复用实现硬件兼容。QUAL (PARTIDL[7:6])芯片质量等级。0工程样片(TMX)1试生产片(TMP)2完全合格片(TMS)。在量产软件中可以加入对此位的检查避免工程样片流入市场。INSTASPIN (PARTIDL[14:13])指示是否支持InstaSPIN-FOC电机控制库。1支持。REVID (Revision ID)器件版本ID。这个值在芯片出厂时被写入Flash的特定区域并由Boot ROM在启动时加载到该寄存器。不同版本的芯片可能在硅片上有细微修正驱动代码在极少数情况下可能需要根据REVID进行差异化处理。实战应用在系统初始化InitSysCtrl()函数中可以添加一段器件检查代码Uint16 partIdHigh DevCfgRegs.PARTIDH.all; Uint16 partIdLow DevCfgRegs.PARTIDL.all; Uint16 pinConfig (partIdLow 8) 0x07; // 提取PIN_COUNT if (pinConfig ! EXPECTED_PIN_COUNT) { // 处理错误硬件板卡使用的芯片封装与软件预期不符 handleError(ERR_WRONG_PACKAGE); }3.2 软件复位寄存器簇SOFTPRESx这是DEV_CFG_REGS中最实用的一组寄存器。它们允许软件独立地复位某个外设模块而无需触发整个芯片的复位。当某个外设如ADC、SPI出现异常“卡死”状态时软件复位是首选的恢复手段。核心特性写1复位向对应外设的位写1会使该外设进入复位状态其所有寄存器恢复为默认值内部状态机清零。手动清零复位操作不会自动结束。软件必须在延时一段时间确保复位完成后手动向该位写0以释放该外设的复位。这是一个常见的遗漏点导致外设无法正常工作。EALLOW保护大多数SOFTPRES寄存器受EALLOW保护意味着在写它们之前必须先执行EALLOW指令在C中通常用EALLOW;宏写完之后再执行EDIS指令。关键寄存器概览SOFTPRES2控制EPWM1-EPWM7模块的复位。SOFTPRES3控制ECAP1-ECAP2模块的复位。SOFTPRES4控制EQEP1模块的复位。SOFTPRES7控制SCI-A, SCI-B, SCI-C模块的复位。SOFTPRES8控制SPI-A模块的复位。SOFTPRES9控制I2C-A, I2C-B模块的复位。SOFTPRES10控制CAN-A模块的复位。SOFTPRES13控制ADC-A, ADC-C模块的复位。SOFTPRES14控制CMPSS1-CMPSS4模块的复位。SOFTPRES28控制Flash模块的复位。特别注意数据手册注明对Flash的复位信号会被内部拉伸到约15us。在操作Flash如擦写前后进行复位时需要考虑到这个延迟。软件复位ADC的典型流程EALLOW; DevCfgRegs.SOFTPRES13.bit.ADC_A 1; // 1. 置位ADC模块复位 EDIS; // 2. 等待足够长的复位时间几个NOP指令或短延时即可 DELAY_US(1); // 例如延时1微秒 EALLOW; DevCfgRegs.SOFTPRES13.bit.ADC_A 0; // 3. 清零释放ADC模块 EDIS; // 4. 重新初始化ADC配置 InitAdc();警告滥用软件复位尤其是在通信过程中可能导致数据丢失。应将其作为错误恢复机制而非常规配置步骤。3.3 其他关键配置寄存器TRIMERRSTS (Trim Error Status)这个寄存器报告了芯片启时从Flash加载微调Trim信息和SRAM修复数据时的错误状态。Trim值用于校准内部振荡器、ADC基准等模拟参数。如果加载出错可能导致芯片性能不达标。位域LERR指示错误类型0x1表示可纠正的单比特错误0x2表示不可纠正的双比特错误0x20表示加载超时。在要求高可靠性的应用中可以在启动后检查此寄存器如果发现非零错误特别是不可纠正错误应触发安全处理流程。TAP_STATUS反映了JTAG调试接口的状态机状态和调试器连接状态。DCON位指示调试器是否连接。TAP_STATE位域反映了JTAG TAP控制器的当前状态如Test-Logic-Reset, Run-Test/Idle, Shift-DR等。这部分内容通常由调试工具如CCS管理应用层代码很少直接操作但在深度调试或自定义调试工具时有用。ECAPTYPE用于配置增强型捕捉模块ECAP的类型。其TYPE字段为01时ECAP的相关寄存器将受到EALLOW保护这增加了配置的安全性防止误写。LOCK位一旦置位将锁定对该寄存器的写操作。这通常由Bootloader或安全启动代码在初始化阶段配置并锁定。4. 系统集成与实战配置指南理解了单个寄存器后如何将它们组合起来完成一个稳定可靠的定时器及系统初始化是工程实现的关键。4.1 CPU定时器初始化标准流程与最佳实践基于上述分析一个健壮的CPU定时器初始化流程应遵循以下步骤我称之为“启停-配置-装载-启动”四步法强制停止Halt无论定时器当前状态如何首先将TCR.bit.TSS置1确保定时器停止计数。这是一个安全习惯。参数配置Configure设置预分频寄存器TPR.all即TDDR值和周期寄存器PRD.all。根据你的中断周期需求计算好这两个值。手动重载Load将TCR.bit.TRB置1。这个操作会立即将PRD值载入TIM计数器并将TDDR值载入PSC预分频计数器。这确保了定时器从一个已知的、正确的初始状态开始。启动与使能Start Enable将TCR.bit.TSS清0以启动计数。如果需要中断则配置PIE外设中断扩展控制器将定时器中断向量指向你的服务函数最后将TCR.bit.TIE置1。示例代码配置CPU Timer1产生1ms中断// 宏定义和计算 #define CPU_FREQ_MHZ 100.0F // 假设系统时钟100MHz #define TIMER_PERIOD_MS 1.0F // 定时周期1ms #define TIMER_PRESCALE 99 // 预分频系数-1即100分频 // 计算周期值 (PRD) // 定时器时钟频率 CPU_FREQ / (TIMER_PRESCALE 1) // 定时器计数次数 (定时器时钟频率 * TIMER_PERIOD_MS) - 1 Uint32 periodCount (Uint32)((CPU_FREQ_MHZ * 1000000.0F / (TIMER_PRESCALE 1)) * (TIMER_PERIOD_MS / 1000.0F)) - 1; void InitCpuTimer1(void) { // 1. 停止定时器 CpuTimer1Regs.TCR.bit.TSS 1; // 2. 配置定时器参数 CpuTimer1Regs.PRD.all periodCount; // 设置周期值 CpuTimer1Regs.TPR.all TIMER_PRESCALE; // 设置预分频低8位为TDDR高8位PSC只读会由TDDR加载 // 3. 初始化计数器并手动重载 CpuTimer1Regs.TIM.all 0; // 也可以初始化为PRD值但TRB会覆盖它 CpuTimer1Regs.TCR.bit.TRB 1; // 执行重载TIM和PSC被更新 // 4. 复位中断标志并配置仿真模式 CpuTimer1Regs.TCR.bit.TIF 1; // 清除可能存在的悬挂中断标志 CpuTimer1Regs.TCR.bit.FREE 1; // 设置仿真模式为自由运行调试时定时器不停 CpuTimer1Regs.TCR.bit.SOFT 0; // FREE1时SOFT无关 // 注意TIE中断使能通常在PIE配置完成后最后开启 // CpuTimer1Regs.TCR.bit.TIE 1; } // 在main函数或系统初始化中调用InitCpuTimer1()后还需要配置PIE void main(void) { InitSysCtrl(); // 初始化系统时钟、PLL等 DINT; // 禁用全局中断 InitPieCtrl(); // 初始化PIE控制寄存器 InitPieVectTable(); // 初始化PIE向量表 InitCpuTimer1(); // 初始化定时器1 // 将CPU Timer1的中断服务程序地址填入PIE向量表 EALLOW; PieVectTable.TIMER1_INT cpuTimer1Isr; EDIS; // 使能PIE组1中的CPU Timer1中断 (INT 13) PieCtrlRegs.PIEIER1.bit.INTx7 1; // TIMER1属于PIE GROUP 1, INT7 // 使能CPU级中断(INT1)和全局中断 IER | M_INT1; EINT; // 启用全局中断 ERTM; // 启用实时中断 // 最后启动定时器中断 CpuTimer1Regs.TCR.bit.TIE 1; for(;;) { // 主循环 } } // 中断服务程序 __interrupt void cpuTimer1Isr(void) { // 1. 清除定时器中断标志 (W1C) CpuTimer1Regs.TCR.bit.TIF 1; // 2. 执行你的周期性任务例如翻转一个GPIO用于测量中断周期 GpioDataRegs.GPATOGGLE.bit.GPIO0 1; // 3. 确认响应此PIE组中断 PieCtrlRegs.PIEACK.all PIEACK_GROUP1; }4.2 外设软件复位的通用模式与注意事项软件复位是解决外设“死锁”的利器但需规范使用。一个通用的外设软件复位函数模板如下void peripheralSoftReset(volatile Uint16* regPtr, Uint16 bitMask) { EALLOW; *regPtr | bitMask; // 置位启动复位 EDIS; // 等待复位完成。延迟时间需参考具体外设的数据手册。 // 对于大多数数字外设几个CPU周期即可对于Flash可能需要15us。 asm( RPT #10 || NOP); // 例如执行10个NOP指令进行短延时 EALLOW; *regPtr ~bitMask; // 清零释放复位 EDIS; // 强烈建议复位后重新初始化该外设的所有配置寄存器 // 因为复位已将其恢复为默认值。 }使用示例复位SPI-A模块// 假设有宏定义 SPI_A_RESET_BIT peripheralSoftReset(DevCfgRegs.SOFTPRES8.all, SPI_A_RESET_BIT); InitSpi(); // 重新初始化SPI配置关键注意事项延时在置位复位位和清零之间必须加入延时。延时长度取决于外设。对于逻辑模块几个到几十个CPU周期通常足够对于模拟模块如ADC或Flash则需要更长时间微秒级。具体请查阅数据手册的时序参数。重新初始化软件复位会将外设的所有寄存器恢复为复位默认值。因此复位操作后必须重新配置该外设否则它将无法按预期工作。中断与DMA如果外设正在产生中断或进行DMA传输执行软件复位前最好先禁用相关中断和DMA通道以避免产生错误的中断或DMA请求。EALLOW保护操作前务必使用EALLOW。4.3 调试技巧与常见问题排查即使按照手册配置有时定时器也可能不按预期工作。以下是一些实战中总结的排查思路问题1定时器中断根本进不去。检查顺序确认初始化流程是否正确特别是TIE定时器中断使能是否在PIE和CPU级中断IER都配置好之后才开启的。一个常见的错误是过早开启了TIE而此时中断向量表还未配置可能导致意外中断或中断被屏蔽。检查PIE配置确认PIE向量表中对应中断向量的入口地址是否正确指向了你的ISR函数。确认PIEIERx中对应的位是否已使能。检查全局中断EINT指令是否执行调试时可以查看ST1寄存器中的INTM位是否为0。检查PRD值PRD值是否为0如果PRD为0计数器从0递减会立即触发中断但行为可能异常。通常PRD应设置为大于0的值。使用仿真器检查寄存器在调试器中直接查看CPUTIMER1.TCR.bit.TIF位。如果定时器在运行该位会周期性置1。如果它从不置1说明定时器没跑起来检查TSS位和时钟源。问题2中断周期不准确比预期快或慢一倍。公式核对再次核对中断周期计算公式。最容易出错的地方是忘记“1”。记住中断周期 (PRD 1) * (TDDR 1) * T_sysclk。32位溢出如果计算的周期值超过了32位计数器所能表示的范围约42.9亿次计数定时器会溢出。确保你的PRD值小于0xFFFFFFFF。SYSCLK频率确认你计算所使用的SYSCLK频率与实际系统配置是否一致。检查PLL、时钟分频器的配置。问题3在调试器设置断点后定时器行为异常。检查FREE和SOFT位如果你在调试时单步执行或暂停希望定时器继续运行以维持系统时序请确保TCR.bit.FREE设置为1自由运行。如果设置为硬停止断点会导致定时器停止影响依赖于定时器的外设如PWM。问题4对SOFTPRES寄存器写操作没有效果。EALLOW保护绝大多数SOFTPRES寄存器受EALLOW保护。检查你的写操作是否包裹在EALLOW和EDIS宏之间。位操作错误确保你操作的是正确的位。例如复位ADC-A是SOFTPRES13.bit.ADC_A而不是SOFTPRES13.bit.ADC_C。查看寄存器值在调试器中写操作后立即读取该寄存器确认位值是否已被修改。有些寄存器可能需要等待几个时钟周期才能生效。5. 高级应用与性能优化掌握了基础配置后我们可以探讨一些更深入的应用和优化点以充分发挥CPU定时器的潜力。5.1 实现高分辨率延时与时间戳虽然C2000有专用的DCSMDedicated Capture and Compare模块用于高精度延时但CPU定时器也可以用于实现微秒级甚至纳秒级的软件延时或者为系统提供一个高精度的时间戳。高分辨率延时函数 思路是使用一个辅助定时器如CPU Timer2将其配置为最高分辨率即TDDR0不分频PRD设置为最大值0xFFFFFFFF然后使其自由运行。通过读取其TIM计数器值来计算时间差。// 初始化一个用于高分辨率计时的定时器 void InitHighResTimer(void) { CpuTimer2Regs.TCR.bit.TSS 1; CpuTimer2Regs.PRD.all 0xFFFFFFFF; // 最大周期使其几乎不溢出 CpuTimer2Regs.TPR.all 0; // 不分频最高分辨率 CpuTimer2Regs.TCR.bit.TRB 1; CpuTimer2Regs.TCR.bit.TSS 0; // 启动自由运行 // 注意不要使能它的中断 } // 获取当前“滴答”数 Uint32 getTickCount(void) { return (0xFFFFFFFF - CpuTimer2Regs.TIM.all); // 因为是递减用最大值减当前值得到递增的tick } // 实现一个延时微秒函数假设SYSCLK100MHz即10ns每tick void delayUs(Uint32 us) { Uint32 startTick getTickCount(); Uint32 delayTicks us * 100; // 100MHz下1us 100个SYSCLK周期 (因为不分频) while((getTickCount() - startTick) delayTicks) { // 空循环等待 } }注意这种方法会占用一个CPU定时器资源且delayUs函数是忙等待会阻塞CPU。仅适用于短延时或对时序要求极其严格的场景。5.2 动态调整定时周期与PWM频率在一些应用中可能需要运行时动态改变定时器的中断周期例如实现可变频率的PWM输出如果PWM由定时器中断软件产生。直接修改PRD寄存器可能不会立即生效因为当前计数周期仍在进行。安全动态修改PRD的流程关闭定时器中断TIE0防止在修改过程中发生中断。停止定时器TSS1。写入新的PRD值。执行手动重载TRB1将新周期值立即加载到计数器。重新启动定时器TSS0。重新使能中断TIE1。void changeTimerPeriod(Uint32 newPeriod) { // 1. 禁用中断 CpuTimer1Regs.TCR.bit.TIE 0; // 2. 停止定时器 CpuTimer1Regs.TCR.bit.TSS 1; // 3. 更新周期值 CpuTimer1Regs.PRD.all newPeriod; // 4. 手动重载使新值生效 CpuTimer1Regs.TCR.bit.TRB 1; // 5. 重启定时器 CpuTimer1Regs.TCR.bit.TSS 0; // 6. 清除可能因停止/启动产生的悬挂标志并重新使能中断 CpuTimer1Regs.TCR.bit.TIF 1; CpuTimer1Regs.TCR.bit.TIE 1; }5.3 多定时器协同与系统时基架构在复杂的系统中可能需要多个定时器为不同任务提供时基。例如CPU Timer1作为系统主时基产生1ms中断用于任务调度、LED闪烁等。CPU Timer2作为高精度计时器用于软件延时或性能测量。CPU Timer0通常被TI的实时操作系统如TI-RTOS或BIOS占用。架构建议分层定时主定时器如1ms中断中可以维护一个软件计数器如sysTick用于提供更长的定时秒、分。这可以减轻中断负担。中断优先级通过PIE和CPU的IER/IER1寄存器合理设置不同定时器中断的优先级。高优先级、对实时性要求苛刻的任务如电机电流环应使用更高优先级的定时器。资源分配规划好三个CPU定时器的用途避免冲突。如果使用TI的库或操作系统需查阅其文档了解其对定时器资源的占用情况。5.4 低功耗模式下的定时器行为TMS320F280013x支持多种低功耗模式如STANDBY, HALT。在这些模式下CPU时钟可能停止或大幅降低这直接影响CPU定时器的工作。IDLE模式外设时钟包括CPU定时器的时钟源通常仍在运行因此定时器会继续计数并可能产生中断中断可以唤醒CPU。STANDBY/HALT模式大多数时钟停止CPU定时器也会停止计数。如果需要定时唤醒应使用专用的低功耗定时器如LPM Timer或外部看门狗定时器WDG。在进入低功耗模式前需要根据应用需求决定是保持CPU定时器运行用于定时唤醒还是将其关闭以节省功耗。如果关闭在退出低功耗模式后需要重新初始化定时器。