DSP

TMS320F28335之定时器

2019-07-13 19:55发布

  1. 定时器系统原理介绍 
    TMS320F28335的CPU Time有三个,分别为Timer0,Timer1,Timer2,其中Timer2是为操作系统DSP/BIOS保留的,当未移植操作系统时,可用来做普通的定时器。这三个定时器的中断信号分别为TINT0, TINT1, TINT2,分别对应于中断向量INT1,INT13,INT14。图4-2为定时器的结构框图,图中TIMH:TIM为计数寄存器,PRDH:PRD为周期寄存器,形如AH格式:A的形式表示一个32位的寄存器,是由两个16位的寄存器构成,AH是高16位,A是低16位。 
    这里写图片描述
CPU定时器的计数复位时,计数寄存器TIMH:TIM加载周期寄存器PRDH:PRD所设定的值,经历一个计数器时钟后,TIMH:TIM内的值就减1,一直减到0,这时产生定时器周期中断事件,并重新装载PRDH:PRD所设定的值,重新开始计数。至于每隔多少时间,计数寄存器TIMH:TIM的值才会减1则由预分频寄存器TPRH:TPR来决定。 
TPRH和TPR这两个寄存器由两部分组成,高8位为定时器预分频计数器PSC,低8位是定时器分频TDDR。也即是说,TPRH是由PSCH和TDDRH构成,而TDDR由PSC和TDDR构成。且其工作的原理与51系列单片机定时器计数器类似,复位时,PSCH:PSC加载TDDRH:TDDR所设定的值,然后经过一个CPU时钟,PSCH:PSC的值减1,当PSCH:PSC的值减到0时,会再次装载TDDRH:TDDR所设定的值,并且产生一个计数器时钟,TIMH:TIM减1。CPU定时器0、1、2配置和控制寄存器如表4-1所示 
这里写图片描述 2.定时器定时时间的公式计算 
以上寄存器测值在配置函数ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)中设置。形参Timer为第几位定时器,Freq为定时频率,Period为计时周期。 
假若Freq为15,Period为1000000,则时间t = 1*15*1000000/150M = 0.1s (系统时钟频率为150M)。不过这个算式的成立是有条件的,这个条件就是以下两条语句: Timer->RegsAddr->TPR.all = 0 Timer->RegsAddr->TPRH.all = 0 上文曾提及,定时器的计数时钟是有预分频寄存器TPRH:TPR决定的。CpuTimerxRegs.TPR.all = 0, CpuTimerxRegs.TPRH.all = 0这两句话决定了1个时钟源周期为定时器的时钟周期(即一个SYSCLKOUT,TIMH:TIM减1),若CpuTimerxRegs.TPR.all = y,CpuTimerxRegs.TPRH.all = 0,则计y+1个时钟周期为定时器的时钟周期。X表示0,1,2中的任意值(任意定时器)。 因此,真正的定时时间为:time =TPRH:TPR/SYSCLKOUT*Freq*Peroid。只有当TPRH:TPR=0时,SYSCLKOUT直接作为TIMH:TIM的时钟周期,time =Freq*Peroid/SYSCLKOUT。另外,在定时器配置函数中, Timer->RegsAddr->TCR.bit.TSS = 1 表示停止定时器 ; Timer->RegsAddr->TCR.bit.TRB = 1 表示重装定时器; Timer->RegsAddr->TCR.bit.FREE = 1 表示定时器自由运行; Timer->RegsAddr->TCR.bit.TIE = 1 表示使能定时器中断。 如果要利用定时器产生一定周期的时间中断,别忘了在主函数中设置响应的中断向量即可。 TI官方头文件DSP2833x_CpuTimers.h程序如下: // TI File $Revision: /main/4 $ // Checkin $Date: March 20, 2007 15:33:42 $ //########################################################################### // // FILE: DSP2833x_CpuTimers.h // // TITLE: DSP2833x CPU 32-bit 定时器寄存器定义. // // NOTES: CpuTimer1 and CpuTimer2 are reserved for use with DSP BIOS and // other realtime operating systems. // // Do not use these two timers in your application if you ever plan // on integrating DSP-BIOS or another realtime OS. // // For this reason, comment out the code to manipulate these two timers // if using DSP-BIOS or another realtime OS. // //########################################################################### // $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $ // $Release Date: August 4, 2009 $ //########################################################################### #ifndef DSP2833x_CPU_TIMERS_H #define DSP2833x_CPU_TIMERS_H #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------------- // CPU 定时器寄存器位定义: // // // TCR: 定时器控制寄存器定义: struct TCR_BITS { // bits 描述 Uint16 rsvd1:4; // 3:0 保留 Uint16 TSS:1; // 4 定时器启动/停止 Uint16 TRB:1; // 5 定时器重载 Uint16 rsvd2:4; // 9:6 保留 Uint16 SOFT:1; // 10 运行模式 Uint16 FREE:1; // 11 运行模式 Uint16 rsvd3:2; // 12:13 保留 Uint16 TIE:1; // 14 中断使能 Uint16 TIF:1; // 15 中断标志位 }; //定时器控制寄存器 union TCR_REG { Uint16 all; struct TCR_BITS bit; //定时器控制寄存器定义 }; // TPR: 预分频低电平寄存器定义: struct TPR_BITS { // bits 描述 Uint16 TDDR:8; // 7:0 定时计数寄存器 Uint16 PSC:8; // 15:8 预分频计数器低位 }; //预分频低电平寄存器 union TPR_REG { Uint16 all; struct TPR_BITS bit; //预分频低电平寄存器定义 }; // TPRH: 预分频高电平寄存器定义: struct TPRH_BITS { // bits 描述 Uint16 TDDRH:8; // 7:0 定时计数器寄存器 Uint16 PSCH:8; // 15:8 预分频计数器高位 }; //预分频寄存器高电平寄存器 union TPRH_REG { Uint16 all; struct TPRH_BITS bit; //预分频高电平寄存器定义 }; // TIM, TIMH: 计数器寄存器定义: struct TIM_REG { Uint16 LSW; //低位 Uint16 MSW; //高位 }; //计数器寄存器 union TIM_GROUP { Uint32 all; struct TIM_REG half; //计数器寄存器定义 }; // PRD, PRDH: 周期寄存器定义: struct PRD_REG { Uint16 LSW; //低位 Uint16 MSW; //高位 }; //周期寄存器 union PRD_GROUP { Uint32 all; struct PRD_REG half; //周期寄存器定义 }; //--------------------------------------------------------------------------- // CPU 定时器寄存器文件: // struct CPUTIMER_REGS { union TIM_GROUP TIM; // 计数器寄存器 union PRD_GROUP PRD; // 周期寄存器 union TCR_REG TCR; // 定时器控制寄存器 Uint16 rsvd1; // 保留 union TPR_REG TPR; // 预分频低电平寄存器 union TPRH_REG TPRH; // 预分频高电平寄存器 }; //--------------------------------------------------------------------------- // CPU 定时器支持的变量: // struct CPUTIMER_VARS { volatile struct CPUTIMER_REGS *RegsAddr; //定时器结构体 Uint32 InterruptCount; //中断计数器 float CPUFreqInMHz; //频率 float PeriodInUSec; //周期 }; //--------------------------------------------------------------------------- // 函数原型和外部定义: // extern void InitCpuTimers(void); //初始化定时器 void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period); //定时器配置函数 extern volatile struct CPUTIMER_REGS CpuTimer0Regs; extern struct CPUTIMER_VARS CpuTimer0; //CpuTimer 1和CpuTimer2预留给DSP BIOS和其他操作系统 如果使用DSP BIOS或其他操作系统注释掉CpuTimer1 CpuTimer2 extern volatile struct CPUTIMER_REGS CpuTimer1Regs; extern volatile struct CPUTIMER_REGS CpuTimer2Regs; extern struct CPUTIMER_VARS CpuTimer1; extern struct CPUTIMER_VARS CpuTimer2; //--------------------------------------------------------------------------- // 实用定时器操作: // // 启动定时器0: #define StartCpuTimer0() CpuTimer0Regs.TCR.bit.TSS = 0 // 停止定时器0: #define StopCpuTimer0() CpuTimer0Regs.TCR.bit.TSS = 1 // 重载定时器周期值: #define ReloadCpuTimer0() CpuTimer0Regs.TCR.bit.TRB = 1 // 读取定时器0计数器寄存器的值: #define ReadCpuTimer0Counter() CpuTimer0Regs.TIM.all // 读取定时器0周期寄存器的值: #define ReadCpuTimer0Period() CpuTimer0Regs.PRD.all // CpuTimer 1 and CpuTimer2 are reserved for DSP BIOS & other RTOS // Do not use these two timers if you ever plan on integrating // DSP-BIOS or another realtime OS. // // For this reason, comment out the code to manipulate these two timers // if using DSP-BIOS or another realtime OS. // 启动定时器1、2: #define StartCpuTimer1() CpuTimer1Regs.TCR.bit.TSS = 0 #define StartCpuTimer2() CpuTimer2Regs.TCR.bit.TSS = 0 // 停止定时器1、2: #define StopCpuTimer1() CpuTimer1Regs.TCR.bit.TSS = 1 #define StopCpuTimer2() CpuTimer2Regs.TCR.bit.TSS = 1 // 重载定时器周期值1、2: #define ReloadCpuTimer1() CpuTimer1Regs.TCR.bit.TRB = 1 #define ReloadCpuTimer2() CpuTimer2Regs.TCR.bit.TRB = 1 // 读取定时器1、2计数器寄存器的值: #define ReadCpuTimer1Counter() CpuTimer1Regs.TIM.all #define ReadCpuTimer2Counter() CpuTimer2Regs.TIM.all // 读取定时器1、2周期寄存器的值: #define ReadCpuTimer1Period() CpuTimer1Regs.PRD.all #define ReadCpuTimer2Period() CpuTimer2Regs.PRD.all #ifdef __cplusplus } #endif /* extern "C" */ #endif // end of DSP2833x_CPU_TIMERS_H definition //=========================================================================== // End of file. //=========================================================================== 其中的实例程序如下: // TI File $Revision: /main/4 $ // Checkin $Date: July 9, 2009 10:51:59 $ //########################################################################### // // FILE: DSP2833x_CpuTimers.c // // TITLE: CPU 32-bit Timers 初始化 & 支持功能. // // NOTES: CpuTimer2 is reserved for use with DSP BIOS and // other realtime operating systems. // // Do not use these this timer in your application if you ever plan // on integrating DSP-BIOS or another realtime OS. // //########################################################################### // $TI Release: DSP2833x/DSP2823x C/C++ Header Files V1.31 $ // $Release Date: August 4, 2009 $ //########################################################################### #include "DSP2833x_Device.h" // Headerfile Include File #include "DSP2833x_Examples.h" // Examples Include File struct CPUTIMER_VARS CpuTimer0; // 当使用DSP BIOS和其他操作系统,CPU定时器2的代码注释掉 struct CPUTIMER_VARS CpuTimer1; struct CPUTIMER_VARS CpuTimer2; //--------------------------------------------------------------------------- // InitCpuTimers: //--------------------------------------------------------------------------- // 改函数将三个CPU的定时器初始化到一个已知状态. // void InitCpuTimers(void) //初始化定时器寄存器 { // CPU 定时器 0 // 寄存器地址指针和各自计时器初始化: CpuTimer0.RegsAddr = &CpuTimer0Regs; // 定时器周期寄存器最大值初始化: CpuTimer0Regs.PRD.all = 0xFFFFFFFF; // 预分频寄存器初始化为1 (SYSCLKOUT): CpuTimer0Regs.TPR.all = 0; CpuTimer0Regs.TPRH.all = 0; // 确保定时器0停止: CpuTimer0Regs.TCR.bit.TSS = 1; // 重加载计数器周期值: CpuTimer0Regs.TCR.bit.TRB = 1; // 复位中断计时器: CpuTimer0.InterruptCount = 0; // CpuTimer2 is reserved for DSP BIOS & other RTOS // Do not use this timer if you ever plan on integrating // DSP-BIOS or another realtime OS. // 寄存器地址指针和各自计时器初始化: CpuTimer1.RegsAddr = &CpuTimer1Regs; CpuTimer2.RegsAddr = &CpuTimer2Regs; // 定时器1、2周期最大值初始化: CpuTimer1Regs.PRD.all = 0xFFFFFFFF; CpuTimer2Regs.PRD.all = 0xFFFFFFFF; // 确保定时器停止: CpuTimer1Regs.TCR.bit.TSS = 1; CpuTimer2Regs.TCR.bit.TSS = 1; // 重加载计数器周期值: CpuTimer1Regs.TCR.bit.TRB = 1; CpuTimer2Regs.TCR.bit.TRB = 1; // 复位中断计时器: CpuTimer1.InterruptCount = 0; CpuTimer2.InterruptCount = 0; } //--------------------------------------------------------------------------- // 配置CpuTimer: //--------------------------------------------------------------------------- // 这个函数初始化,选择定时器,周期参数指定“频率”和“时间”参数. // 频率为MHz,时间为us级,定时器配置后保存在停止状态 // void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period) { Uint32 temp; // 定时器周期参数初始化: Timer->CPUFreqInMHz = Freq; //频率 Timer->PeriodInUSec = Period; //周期 temp = (long) (Freq * Period); Timer->RegsAddr->PRD.all = temp; //周期寄存器设定值为timer // 预分频寄存器初始化为1 (SYSCLKOUT): Timer->RegsAddr->TPR.all = 0; Timer->RegsAddr->TPRH.all = 0; // 定时器控制寄存器初始化: Timer->RegsAddr->TCR.bit.TSS = 1; // 1 = 停止定时器, 0 = 启动/重启定时器 Timer->RegsAddr->TCR.bit.TRB = 1; // 1 = 重载计时器 Timer->RegsAddr->TCR.bit.SOFT = 1; // 定时器自由运行 Timer->RegsAddr->TCR.bit.FREE = 1; // 定时器自由运行 Timer->RegsAddr->TCR.bit.TIE = 1; // 0 = 禁止/ 1 = 定时器中断使能 // 复位中断计数器: Timer->InterruptCount = 0; } //=========================================================================== // End of file. //===========================================================================