打印

TMS320F28x ConfigCpuTimer()函数

[复制链接]
2277|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
GG_GG|  楼主 | 2012-8-1 12:56 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
关于ConfigCpuTimer()函数的说明
在共享文件DSP281x_CpuTimers.c 中,包含了两个函数:一个是定时器初始化函数InitCpuTimers(),另一个就是CPU 定时器配置函数ConfigCpuTimer()。
这里将整个定时器配置函数列出,除了对指令进行注释之外,还对出现在函数中指针的用法进行说明,作为第1 章位域结构体访问方法的补充。
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 有关定义:
struct CPUTIMER_VARS //该函数由DSP281x_CpuTimers.h 文件建立
{
volatile struct CPUTIMER_REGS *RegsAddr;
Uint32 InterruptCount;
float CPUFreqInMHz;
float PeriodInUSec;
};

相关帖子

沙发
GG_GG|  楼主 | 2012-8-1 12:56 | 只看该作者
这个结构体列出了CPU 定时器所支持的变量,其第一个成员是一个包含CPU 定时器所有专用寄存器的结构体(CPUTIMER_REGS),RegsAddr 是一个具有CPUTIMER_REGS 结构体类型的指针变量,其他3 个成员与定时器寄存器有联系,但不属于定时器专用寄存器。InterruptCount 是定时器中断计数器,另外两个的乘积构成定时器的周期。这里把与一个结构体类型相关的变量归入一个结构体内,这种设计方法是值得借鉴的。

现在再引入CPU 定时器寄存器结构体CPUTIMER_REGS 的有关定义:

struct CPUTIMER_REGS //该定义由DSP281x_CpuTimers.h 文件建立

{

union TIM_GROUP TIM; //定时器计数寄存器

union PRD_GROUP PRD; //定时器周期寄存器

union TCR_REG TCR; //定时器控制寄存器

Uint16 rsvd1; //保留

union TPR_REG TPR; //定时器预定标计数低位

union TPRH_REG TPRH; //定时器预定标计数高位

};

这个结构体声明有6 个成员,除第4 个成员保留外,其余5 个均属CPU 定时器专用寄存器,其中“union TCR_REG TCR;”声明TCR_REG 是一种共用体类型,同时定义相应的共用体变量TCR,以便引用(注意:不可直接引用一个类型)。下面列

出TCR_REG共用体类型定义及TCR 控制寄存器位域结构体(TCR_BITS)定义。

使用特权

评论回复
板凳
GG_GG|  楼主 | 2012-8-1 12:56 | 只看该作者
/* 定义TCR_REG 共用体类型。它包含2 个成员,一个是16 位无符号整数all, */

/* 一个是16 位TCR_BITS 结构体,它们占用同一个内存单元 */

union TCR_REG //该定义由DSP281x_CpuTimers.h 文件建立

{

Uint16 all;

struct TCR_BITS bit;

};

/* TCR 控制寄存器位结构(TCR_BITS)定义。它是此类数据结构的底层定义 */

struct TCR_BITS //该定义由DSP281x_CpuTimers.h 文件建立

{

//位域描述

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

};

现在再来看指令:“Timer→RegsAddr→TCR.bit.TRB=1;”这条指令最终访问的是TCR寄存器的TRB 位。其中Timer 指向CPU 定时器变量(CPUTIMER_VARS),RegsAddr指向CPUTIMER_VARS 中的CPU 定时器寄存器结构体(CPUTIMER_REGS),后面的关系就比较清楚了。这种访问方法从外层入手,一层一层地进入内层。

使用特权

评论回复
地板
GG_GG|  楼主 | 2012-8-1 12:57 | 只看该作者
2.ConfigCpuTimer()函数


void ConfigCpuTimer(struct CPUTIMER_VARS *Timer, float Freq, float Period)

{

Uint32 temp;

/* 定时器周期初始化。将后两个实参的乘积作为定时器的周期值存入定时器周期寄存器 */

Timer->CPUFreqInMHz= Freq;

Timer->PeriodPeriodInUSec= Period;

temp= (long) (Freq * Period);

Timer->RegsAddr->PRD.all=temp;

//定时器周期PRD=Freq* Period。当定时器计数器(TIMH:TIM)减到0

//时的下一个定时器周期,PRD 值重新装入(TIMH:TIM)

/* 设置预定标计数器为129 个时钟源周期,即(129/SYSCLKOUT)*/

// Timer->RegsAddr->TPR.all=0x80;

// Timer->RegsAddr->TPRH.all=0x00;

使用特权

评论回复
5
GG_GG|  楼主 | 2012-8-1 16:44 | 只看该作者
/* 以下3 条指令可代替上面两条指令访问TPR */

CpuTimer0.RegsAddr= &CpuTimer0Regs;//取CpuTimer0Regs 地址

CpuTimer0Regs.TPR.all=0x80;//TDDR=0x0080

CpuTimer0Regs.TPRH.all=0x00;//TDDRH=0x0000

//分频器值TDDRH:TDDR=0x0080。该值决定定时器时钟周期。计数器TIM 以此

//为周期进行减1 计数。减到0 时的下一个定时器周期,PRD 值重新装入(TIMH:TIM)

/* 定时器控制寄存器初始化。“.”是成员(分量)运算符,它在所有运算符中优先级最高 */

Timer->RegsAddr->TCR.bit.TSS=1;//停止定时器

Timer->RegsAddr->TCR.bit.TRB=1; //重装定时器

Timer->RegsAddr->TCR.bit.SOFT=1;

Timer->RegsAddr->TCR.bit.FREE=1; //定时器自由运行

Timer->RegsAddr->TCR.bit.TIE=1; //使能定时器中断

Timer->InterruptCount=0; //复位中断计数器

}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

61

主题

893

帖子

7

粉丝