当前位置: 首页 > news >正文

恶补DSP:2.F28335的定时器系统

一、定时器原理

        F28335 城市的三座时钟塔(Timer0、Timer1、Timer2)是城市时间管理的核心设施,每座均为32位精度,依靠城市能源脉冲(系统时钟 SYSCLKOUT,典型频率为150 MHz)驱动。它们由两个核心模块组成:节奏调节站(预分频模块)计时核心站(定时/计数模块),协同工作以实现精确计时。

  • 节奏调节站(预分频模块)

    • 节奏分频器(16位定时器分频寄存器 TDDRH:TDDR):决定城市能源脉冲的“放慢”倍数。例如,若 TDDR=9,则每10个脉冲(从0到9)产生一次有效信号,相当于将脉冲频率除以10。
    • 节奏计数器(16位预定标计数器 PSCH:PSC):记录收到的脉冲数。每次脉冲到来,PSC 减1;当 PSC 减到0时,触发“下溢”,向计时核心站发送信号,并重新装载 TDDR 的值,开始下一轮计数。
  • 计时核心站(定时/计数模块)

    • 周期蓝图(32位周期寄存器 PRDH:PRD):定义一次完整计时周期的长度,决定时钟塔多久敲响一次“钟声”。
    • 计时器(32位计数寄存器 TIMH:TIM):记录当前计时进度。每次从节奏调节站收到信号,TIM 减1;当 TIM 减到0时,触发“下溢”,产生“钟声”(中断信号),并重新装载 PRD 的值。

工作流程如下:

  1. 城市能源脉冲(SYSCLKOUT)每跳动一次,节奏计数器(PSC)减1。
  2. 当 PSC 减到0,触发下溢,向计时器(TIM)发送信号,TIM 减1,同时 PSC 重新装载 TDDR 的值。
  3. 当 TIM 减到0,触发下溢,产生中断信号(TINT0、TINT1 或 TINT2),通知中央政府(CPU),并重新装载 PRD 的值,循环往复。

        时钟塔的“钟声”通过城市通信网络(PIE 中断系统)传递,Timer0 的中断(TINT0)属于第一组第七个小信号(PIEIER1.bit.INTx7)。中断信号经过 PIE 模块处理后到达中央政府,确保任务按时执行。

周期计算公式


定时周期 = (PRD + 1) × (TDDR + 1) × (1 / SYSCLKOUT)


例如,若 SYSCLKOUT=150 MHz(周期6.67 ns),PRD=14999999,TDDR=9,则定时周期为:
(14999999 + 1) × (9 + 1) × 6.67 ns = 15000000 × 10 × 6.67 ns = 1秒。

二、具体代码

2.1 ConfigCpuTimer 函数

void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)
{Uint32 temp;// Initialize timer period:Timer->CPUFreqInMHz = Freq;Timer->PeriodInUSec = Period;temp = (long)(Freq * Period);Timer->RegsAddr->PRD.all = temp;// Set pre-scale counter to divide by 1 (SYSCLKOUT):Timer->RegsAddr->TPR.all = 0;Timer->RegsAddr->TPRH.all = 0;// Initialize timer control register:Timer->RegsAddr->TCR.bit.TSS = 1;      // 1 = Stop timer, 0 = Start/Restart TimerTimer->RegsAddr->TCR.bit.TRB = 1;      // 1 = reload timerTimer->RegsAddr->TCR.bit.SOFT = 0;Timer->RegsAddr->TCR.bit.FREE = 0;     // Timer Free Run DisabledTimer->RegsAddr->TCR.bit.TIE = 1;      // 0 = Disable/ 1 = Enable Timer Interrupt// Reset interrupt counter:Timer->InterruptCount = 0;
}
功能概述

ConfigCpuTimer 是城市提供的一套标准管理工具(库函数),用于配置任意一座时钟塔(Timer0、Timer1 或 Timer2)的运行参数。根据城市需求调整时钟塔的节奏和计时周期,确保其“钟声”(中断信号)按预期时间响起。该函数接受三个参数:

  • Timer:指向时钟塔管理结构(CPUTIMER_VARS)的指针,包含时钟塔的寄存器地址、频率、周期等信息。
  • Freq:城市能源脉冲频率(单位:MHz,例如 150 MHz)。
  • Period:期望的计时周期(单位:微秒,例如 500000 表示 500ms)。
详细分析
  1. 参数存储

Timer->CPUFreqInMHz = Freq;
Timer->PeriodInUSec = Period;
    • 将输入的频率和周期存储到 Timer 结构中,便于后续管理和调试。
    • 例如,若 Freq=150,Period=500000,则记录 CPU 频率为 150 MHz,周期为 500ms。
  1. 计算周期蓝图(PRD 值)

temp = (long)(Freq * Period);
Timer->RegsAddr->PRD.all = temp;
  • 计算周期寄存器(PRD)的值,决定时钟塔敲响“钟声”的时间间隔。
  • 公式:PRD = Freq * Period,其中 Freq(MHz)× Period(微秒)= 周期脉冲数。
  • 示例:若 Freq=150 MHz,Period=500000 微秒(500ms),则:
PRD = 150 * 500000 = 75000000
    • 表示时钟塔需要计数 75000000 个脉冲(每个脉冲 6.67 ns,150 MHz 的倒数),对应 500ms。
    • 注意:实际硬件实现中,PRD 寄存器从 0 计数到 PRD 值(含 0,共 PRD+1 次),但此处代码直接使用 Freq * Period,未减 1,可能导致周期略偏,实际周期为 (PRD+1) × (1/SYSCLKOUT)。开发者需根据硬件手册验证是否需要调整。
  1. 设置节奏调节站(TPR/TPRH)

Timer->RegsAddr->TPR.all = 0;
Timer->RegsAddr->TPRH.all = 0;
  • 将预定标寄存器(TPR/TPRH)清零,表示不使用分频(TDDR=0,PSC=0)。
  • 此时,SYSCLKOUT 的每个脉冲直接驱动 TIM 计数器减 1,分频系数为 1。
  • 公式:定时周期 = (PRD+1) × (TDDR+1) × (1/SYSCLKOUT),由于 TDDR=0,周期简化为:

定时周期 = (PRD+1) × (1/SYSCLKOUT)
示例:PRD=75000000,SYSCLKOUT=150 MHz(周期 6.67 ns),则:

定时周期 = (75000000+1) × 6.67 ns ≈ 500000006.67 ns ≈ 500ms
4.配置时钟塔控制面板(TCR)

Timer->RegsAddr->TCR.bit.TSS = 1;      // 停止时钟塔
Timer->RegsAddr->TCR.bit.TRB = 1;      // 启用重载
Timer->RegsAddr->TCR.bit.SOFT = 0;     // 非软启动
Timer->RegsAddr->TCR.bit.FREE = 0;     // 非自由运行
Timer->RegsAddr->TCR.bit.TIE = 1;      // 启用中断
  • TSS=1:停止时钟塔(Timer Stop Status),确保在配置期间不运行。
  • TRB=1:启用重载(Timer Reload Bit),当 TIM 计数器归零时,自动从 PRD 重新装载值。
  • SOFT=0, FREE=0:禁用软启动和自由运行模式,确保时钟塔在调试时暂停,适合精确控制。
  • TIE=1:启用中断(Timer Interrupt Enable),允许时钟塔在 TIM 归零时产生“钟声”(中断信号)。

5.重置中断计数

Timer->InterruptCount = 0;
  • 清零中断计数器,记录时钟塔触发的中断次数(用于调试或统计)。

2.2 TIM0_Init 函数

void TIM0_Init(float Freq, float Period)
{EALLOW;SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; // CPU Timer 0EDIS;EALLOW;PieVectTable.TINT0 = &TIM0_IRQn;EDIS;CpuTimer0.RegsAddr = &CpuTimer0Regs;CpuTimer0Regs.PRD.all = 0xFFFFFFFF;CpuTimer0Regs.TPR.all = 0;CpuTimer0Regs.TPRH.all = 0;CpuTimer0Regs.TCR.bit.TSS = 1;CpuTimer0Regs.TCR.bit.TRB = 1;CpuTimer0.InterruptCount = 0;ConfigCpuTimer(&CpuTimer0, Freq, Period);CpuTimer0Regs.TCR.bit.TSS = 0;IER |= M_INT1;PieCtrlRegs.PIEIER1.bit.INTx7 = 1;EINT;ERTM;
}
详细分析
  1. 启动能源供应

    EALLOW; SysCtrlRegs.PCLKCR3.bit.CPUTIMER0ENCLK = 1; EDIS;
    • 打开 Timer0 的能源开关(PCLKCR3.bit.CPUTIMER0ENCLK=1),连接城市电力网络(SYSCLKOUT)。
    • EALLOW 和 EDIS 用于解除和恢复寄存器写保护,确保安全操作。
  2. 设置中断通信地址

    EALLOW; PieVectTable.TINT0 = &TIM0_IRQn; EDIS;
    • 将 Timer0 的“钟声”(TINT0 中断)映射到中断服务函数 TIM0_IRQn 的地址(中断向量表 INT1)。
    • 确保中央政府(CPU)在收到 TINT0 信号时调用正确的响应程序。
  3. 初始化 Timer0 寄存器

    CpuTimer0.RegsAddr = &CpuTimer0Regs; CpuTimer0Regs.PRD.all = 0xFFFFFFFF; CpuTimer0Regs.TPR.all = 0; CpuTimer0Regs.TPRH.all = 0; CpuTimer0Regs.TCR.bit.TSS = 1; CpuTimer0Regs.TCR.bit.TRB = 1; CpuTimer0.InterruptCount = 0;
    • CpuTimer0.RegsAddr:指定 Timer0 的寄存器地址,绑定管理结构。
    • PRD.all = 0xFFFFFFFF:初始化周期蓝图为最大值(32位全1),为后续配置留空间。
    • TPR.all = 0, TPRH.all = 0:清零节奏调节站(TDDR 和 PSC),默认不分频。
    • TCR.bit.TSS = 1:停止时钟塔,确保配置期间不运行。
    • TCR.bit.TRB = 1:启用重载功能。
    • InterruptCount = 0:清零中断计数。
  4. 调用 ConfigCpuTimer

    ConfigCpuTimer(&CpuTimer0, Freq, Period);
    • 调用 ConfigCpuTimer 设置 Timer0 的周期(PRD = Freq × Period)和运行参数(TCR、TPR/TPRH)。
    • 示例:Freq=150 MHz,Period=500000 微秒,PRD=75000000,对应 500ms。
  5. 启动时钟塔并启用中断

    CpuTimer0Regs.TCR.bit.TSS = 0; IER |= M_INT1; PieCtrlRegs.PIEIER1.bit.INTx7 = 1; EINT; ERTM;
    • TCR.bit.TSS = 0:启动 Timer0 时钟塔,开始计数。
    • IER |= M_INT1:启用 CPU 第一组中断(INT1,包含 TINT0)。
    • PieCtrlRegs.PIEIER1.bit.INTx7 = 1:启用 PIE 第一组第七小中断(TINT0)。
    • EINT:启用全局中断。
    • ERTM:启用实时中断模式,确保中断处理不被调试暂停。

3. TIM0_IRQn 中断

interrupt void TIM0_IRQn(void)
{EALLOW;LED2_TOGGLE;PieCtrlRegs.PIEACK.bit.ACK1 = 1;EDIS;
}

TIM0_IRQn 是 Timer0 的中断服务函数(ISR),相当于时钟塔敲响“钟声”时中央政府的响应程序。它在 Timer0 计数器(TIM)归零时触发,负责翻转 D2 信号灯状态并清除中断标志,确保下次“钟声”正常触发。

详细分析
  1. 解除写保护

    EALLOW;
    • 解除寄存器写保护,允许操作 PIE 寄存器。
  2. 翻转 D2 信号灯

    LED2_TOGGLE;
    • 调用宏 LED2_TOGGLE,翻转 D2 信号灯的电平(高变低,低变高)。
    • 实现效果:每次中断触发,D2 信号灯状态切换,周期为 500ms(由 ConfigCpuTimer 设置),即每 500ms 点亮或熄灭。
  3. 清除中断标志

    PieCtrlRegs.PIEACK.bit.ACK1 = 1;
    • 清除 PIE 第一组中断的确认标志(ACK1),通知通信网络(PIE)已处理本次中断。
    • 若不清除,PIE 将阻止下一次 TINT0 中断触发,导致时钟塔“钟声”失效。
  4. 恢复写保护

    EDIS;
    • 恢复寄存器写保护,确保系统安全。

TIM0_IRQn 是 Timer0 中断的响应核心,简洁高效地处理 D2 信号灯的闪烁任务,并通过清除标志位保证中断系统的正常运行。其执行时间需尽量短,以避免影响其他任务。


综合流程:

  1. 初始化(TIM0_Init)

    • 打开 Timer0 能源(PCLKCR3),设置中断地址(TINT0 → TIM0_IRQn)。
    • 初始化寄存器(PRD=0xFFFFFFFF,TPR/TPRH=0,TSS=1,TRB=1)。
    • 调用 ConfigCpuTimer 设置 PRD=75000000(500ms),启用中断(TIE=1)。
    • 启动 Timer0(TSS=0),启用 PIE 中断(INT1、INTx7)和全局中断。
  2. 运行

    • Timer0 接收 SYSCLKOUT 脉冲(150 MHz),TIM 计数器从 75000000 减到 0。
    • 每 500ms(75000001 × 6.67 ns),TIM 归零,触发 TINT0 中断。
  3. 中断处理(TIM0_IRQn)

    • 翻转 D2 信号灯状态。
    • 清除 PIEACK 标志,准备下次中断。
http://www.dtcms.com/a/341690.html

相关文章:

  • 买返商城网站源码多平台购物返现搭建图解源码二开
  • 万象生鲜配送系统 2025 年 8 月 15 日更新日志
  • 八月月报丨MaxKB在教育及教学科研领域的应用进展
  • Hadoop学习
  • 达梦数据库-实时主备集群部署详解(附图文)手工搭建一主一备数据守护集群DW
  • HyDE vs HyPE:AI检索界的‘假想敌’革命,如何让RAG系统从‘找资料’变成‘懂你心’?”
  • Firefox 142 引入 CRLite 用于私有证书撤销
  • 【AI应用】部署AI向量数据库Milvus
  • Oracle:配置让插入语句时id自动输入
  • Sora网页打不开怎么办?常见原因与解决方法
  • 从零开始:打造一个现代化的BMI计算器Web应用
  • JVM面试精选 20 题(终)
  • 数据结构之排序大全(2)
  • 【科研绘图系列】R语言绘制平滑曲线折线图
  • 2025招商铸盾车联网CTF竞赛初赛题解
  • Vue 3 高性能实践 全面提速剖析!
  • 基于SpringBoot+Vue的吴韵苏香文旅小程序(协同过滤算法、Echarts图形化分析、腾讯地图API、二维码识别)
  • Linux KGDB 内核调试完全指南:原理、架构与应用
  • ADG duplicate实施方案详细教程(单机版)
  • 基于STM32单片机智能药盒定时吃药喂水蓝牙APP设计
  • abc Replace
  • cadence16.6修改原理图的Page Number过程中遇到问题
  • 工地智能安全带让高空作业更安全
  • PCB题目基础练习3
  • 前端项目面试分析
  • 解决 nginx: [warn] “ssl_stapling“ ignored, issuer certificate not found 报错
  • cobbler
  • 连续空间强化学习:策略输出的两种形态 —— 概率分布与确定性动作
  • 智慧城市SaaS平台/市政设施运行监测系统之排水管网运行监测、综合管廊运行监测
  • lesson43:Python操作MongoDB数据库完全指南