CpuTimer0Regs.TCR.all =TSS _MASK;
注意:对没有位域结构体和共用体定义的寄存器,不能使用*.bit或*.all名称进行访问。 2.3、关于ConfigCpuTimer()函数的说明
在DSP2833x_CpuTimers.c中,包含了两个函数:一个是定时器初始化函数InitCpuTimers(),另一个是CPU定时器的配置函数ConfigCpuTimer()。
1、对指令 Timer->RegsAddr->TCR.bit.TRB = 1; 的注解 “struct CPUTIMER_VARS *Timer”
*为指针运算符,Timer是一个具有CPUTIMER_VARS结构体类型的指针变量,它指向结构体CPUTIMER_VARS。通过
(*Timer).xxx可以访问CPUTIMER_VARS结构体中的xxx成员。在C语言中,为使用方便和使之直观,可以把(*Timer).xxx用Timer->xxx来代替。“->”是成员选择指针。看下面指令:
Timer->RegsAddr->TCR.bit.TRB = 1;
为了弄清楚前面两个指针的的含义,先引入结构体CPUTIMER_VARS有关定义。
// CPU Timer Support Variables: //
struct CPUTIMER_VARS //该函数由DSP2833x_CpuTimers.h文件建立 {
volatile struct CPUTIMER_REGS *RegsAddr; Uint32 InterruptCount; float CPUFreqInMHz; float PeriodInUSec; };
这个结构体列出了CPU定时器所支持的变量,其第一个成员是一个包含CPU定时器所有专用寄存器的结构体(CPUTIMER_REGS),RegsAddr是一个具有CPUTIMER_REGS结构体类型的指针变量,InterruptCount是定时器中断计算器,另外两个的乘积构成定时器的周期。
现在再引入CPU定时器寄存器结构体CPUTIMER_REGS的有关定义: // CPU Timer Register File: //
struct CPUTIMER_REGS // 该定义由由DSP2833x_CpuTimers.h文件建立 {
union TIM_GROUP TIM; // Timer counter register union PRD_GROUP PRD; // Period register union TCR_REG TCR; // Timer control register Uint16 rsvd1; // reserved
union TPR_REG TPR; // Timer pre-scale low 定时器预定标计数低位 union TPRH_REG TPRH; // Timer pre-scale high };
这个结构体声明有6个成员,除第4个成员保留外,其余5个均属于CPU定时器专用寄存器,其中“union TCR_REG TCR;”声明TCR_REG是一种共用体类型,同时定义相应的共用体变量TCR,以便引用。下面列出TCR_REG共用体类型定义及TCR控制寄存器位域结构体(TCR_BITS)定义。
// CPU Timer Register Bit Definitions: // TCR: Control register bit definitions:
struct TCR_BITS //该定义由由DSP2833x_CpuTimers.h文件建立 { // bits description
Uint16 rsvd1:4; // 3:0 reserved
Uint16 TSS:1; // 4 Timer Start/Stop Uint16 TRB:1; // 5 Timer reload Uint16 rsvd2:4; // 9:6 reserved
Uint16 SOFT:1; // 10 Emulation modes Uint16 FREE:1; // 11
Uint16 rsvd3:2; // 12:13 reserved Uint16 TIE:1; // 14 Output enable Uint16 TIF:1; // 15 Interrupt flag };
//定义TCR_REG共用体类型。包含2个成员,一个是16位无符号整数all,一个是16位TCR_BITS结构体,他们占用同一个内存单元
union TCR_REG //该定义由由DSP2833x_CpuTimers.h文件建立 {
Uint16 all; struct TCR_BITS bit; };
现在再来看指令:“Timer->RegsAddr->TCR.bit.TRB = 1; ”这条指令最终访问的是TCR寄存器的TRB位。其中Timer指向CPU定时器变量 ( CPUTIMER_VARS),RegsAddr指向CPUTIMER_VARS中的CPU定时器寄存器结构体(CPUTIMER_REGS)。这种访问方法从外层入手,一层一层地进入内存。
2. ConfigCpuTimer()函数 // ConfigCpuTimer:
//--------------------------------------------------------------------------- // This function initializes the selected timer to the period specified // by the \// and the period in \// after configuration. //
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;k
// 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 Timer
Timer->RegsAddr->TCR.bit.TRB = 1; // 1 = reload timer Timer->RegsAddr->TCR.bit.SOFT = 1;
Timer->RegsAddr->TCR.bit.FREE = 1; // Timer Free Run
Timer->RegsAddr->TCR.bit.TIE = 1; // 0 = Disable/ 1 = Enable Timer Interrupt
// Reset interrupt counter: Timer->InterruptCount = 0; }
//=========================================================================== 2.4、定时器0中断启动程序实例(CpuTimer.c) 1. CpuTimer.c文件要点
(1)标题:定时器0中断启动程序
(2)说明:该程序需要DSP28xV1.00头文件支持,可将其配置为boot to H0操作方式,除了boot方式配置外,不需要进行其他硬件的配置。
(3)功能:本示例对CPU定时器0进行配置,定时器0每产生一次中断,中断计数器加1.本示例的前面部分加入了IQMATH的简单示例,供参考。
(4)决定定时器0中断响应快慢的几个因素:
系统时钟SYSCLKOUT。系统时钟受锁相环控制寄存器(PLLCR)位域DIV及外部晶振的控制。参见“DSP2833x_SysCtrl.c”文件中的InitSysCtrl()函数。
装入计数器TIM的计数周期值PRD。该值通过对“ConfigCpuTimer(&CpuTimer0,x,y); ”函数后两个形参的赋值得到,其关系式为PRD=x*y。
定时器时钟周期。该值是通过定时器分频器(TDDRH:TDDR)对系统时钟SYSCLKOUT分频得到。设SYSCLKOUT=150Mhz(晶振为30Mhz,DIV=10),则决定定时器0中断响应快慢的只有PRD及(TDDRH:TDDR).
2. CpuTimer.c文件
// FILE: DSP2833x_CpuTimers.c //
// TITLE: CPU 32-bit Timers Initialization & Support Functions. //
// 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.
//########################################################################### #include \ // Headerfile Include File头文件包含文件 #include \ // Examples Include File示例包含文件
struct CPUTIMER_VARS CpuTimer0; //定义CpuTimer0是一个具有CPUTIMER_VARS结构体类型的变量
// When using DSP BIOS & other RTOS, comment out CPU Timer 2 code. struct CPUTIMER_VARS CpuTimer1; struct CPUTIMER_VARS CpuTimer2;
//---------------------------------------------------------------------------
// InitCpuTimers:
//--------------------------------------------------------------------------- // This function initializes all three CPU timers to a known state. //
void InitCpuTimers(void) //定时器初始化函数 {
// CPU Timer 0
// Initialize address pointers to respective timer registers:
CpuTimer0.RegsAddr = &CpuTimer0Regs; //把CpuTimer0Regs的地址赋给具有CPUTIMER_VARS结构体类型的变量
CpuTimer0中的成员,即具有CPUTIMER_REGS结构体类型的指针变量。 // Initialize timer period to maximum:
CpuTimer0Regs.PRD.all = 0xFFFFFFFF; // CpuTimer0Regs是具有CPUTIMER_REGS结构体类型的变量,给其成员周
期寄存器PRD的值赋为0xFFFFFFFF
// Initialize pre-scale counter to divide by 1 (SYSCLKOUT):
CpuTimer0Regs.TPR.all = 0; 预定标计数器低位寄存器TPR,由8位TDDR(TPR[7:0])定时器分频器低位和8位
PSC(TPR[15:8])定时器预定标计数器低位组成,全置为0. CpuTimer0Regs.TPRH.all = 0; // Make sure timer is stopped:
CpuTimer0Regs.TCR.bit.TSS = 1; //(定时器启止状态位)停止定时器 // Reload all counter register with period value:
CpuTimer0Regs.TCR.bit.TRB = 1; //(定时器重装位)(PRDH:PRD)的值装入(TIMH:TIM),并且把定时器分频器(TDDRH:TDDR)的值装入预定标计数器(PSCH:PSC) // Reset interrupt counters:
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.
// Initialize address pointers to respective timer registers: CpuTimer1.RegsAddr = &CpuTimer1Regs; CpuTimer2.RegsAddr = &CpuTimer2Regs; // Initialize timer period to maximum: CpuTimer1Regs.PRD.all = 0xFFFFFFFF; CpuTimer2Regs.PRD.all = 0xFFFFFFFF; // Make sure timers are stopped: CpuTimer1Regs.TCR.bit.TSS = 1; CpuTimer2Regs.TCR.bit.TSS = 1;
// Reload all counter register with period value: CpuTimer1Regs.TCR.bit.TRB = 1; CpuTimer2Regs.TCR.bit.TRB = 1; // Reset interrupt counters: CpuTimer1.InterruptCount = 0; CpuTimer2.InterruptCount = 0;