《TMS 320 F28x源码解读》第1章DSP F28x 使用入门,通过位域结构体的方法为F28x

提供了一个完整的头文件体系,并且针对F28x 的外围设备给出了20 个外设示例,这是DSP

控制类芯片在软件领域的一大进步。本节为大家介绍传统#define 方法。

1.2.1 传统#define 方法

C代码访问寄存器的传统方法是使用#define宏为每一个寄存器分配一个地址。例如:

/

{

PAGE 1:

CPU_TIMER0 :origin=0x000C00,length=0x000008

}

SECTIONS

{

CpuTimer0RegsFile :>CPU_TIMER0,PAGE=1

}

通过把变量直接映射到外设寄存器的同一内存地址,用户采用C

代码对寄存器进行访问,只需要通过访问变量中所需的成员即可进行。例如,要对CPU-Timer0TCR

寄存器进行写操作,只需访问CpuTimer0Regs 变量中的TCR 成员,如以下代码所示:

//***********************************************

******************************

//用户源文件

//**************************************************

***************************

CpuTimer0Regs.TCR.all=TSS_MASK; //访问TCR 寄存器示例

1.2.3

添加位域结构体

1.2.3 添加位域结构体

1)增加位域定义

我们经常需要直接访问寄存器中的某个位域。C281x

C/C++头文件及外设示例所涉及的位域结构体方法,为多数片上外设寄存器提供了位域定义。例如,可以为CPU

定时器(CPU-Timer)中的每个寄存器定义一个位域结构体类型。CPU

定时器(CPU-Timer)控制寄存器的位域定义如下所示:

//*****************************************************************************

//DSP281x_headers\include\DSP281x_CpuTimers.h CPU 定时器头文件

//*****************************************************************************

struct TCR_BITS //定义一个TCR_BITS 结构体类型(不是变量)

{ Uint16 rsvd1:4; //3:0 保留,从最低位开始,顺序取位到最高位。取低4 位

Uint16 TSS:1; //4 定时器开始/停止,取第5 位

Uint16 TRB:1; //5 定时器重装,取第6 位

Uint16 rsvd2:4; //9:6 保留,取第7 位到第10 位

Uint16 SOFT:1; //10 仿真模式,取第11 位

Uint16 FREE:1; //11 仿真模式,取第12 位

Uint16 rsvd3:2; //12:13 保留,取第13 位到第14 位

Uint16 TIE:1; //14 输出使能,取第15 位

Uint16 TIF:1; //15 中断标志,取第16 位

};

然后,通过共用体进行声明,以便访问位域结构体定义的各个成员或者16

位或32位寄存器的值。例如,定时器的控制寄存器共用体如下所示:

//*****************************************************************************

//DSP281x_headers\include\DSP281x_CpuTimers.h CPU 定时器头文件

//*****************************************************************************

union TCR_REG //定义共用体类型TCR_REG(不是变量)

{ Uint16 all;

struct TCR_BITS bit; //bit 是一个具有TCR_BITS 结构体类型的变量

};

//all 和bit 是共用体的两个成员,它们都是16 位结构,占用内存的同一单元

一旦每个寄存器的位域结构体类型和共用体的定义都建立起来了,则在CPU

定时器(CPU-Timer)的寄存器结构体类型中,各个成员可通过采用共用体定义的形式重写:

//*****************************************************************************

//DSP281x_headers\include\DSP281x_CpuTimers.h CPU 定时器头文件

//*****************************************************************************

struct CPUTIMER_REGS

{ union TIM_GROUP TIM; //定时器计数寄存器,TIM 是一个具有 TIM_GROUP 共

//用体类型的变量

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

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

Uint16 rsvd1; //保留

union TPR_REG TPR; //定时器预定标寄存器低位

union TPRH_REG TPRH; //定时器预定标寄存器高位

};

现在,既可以通过C 代码以位域的方法访问CpuTimer

寄存器中的某位,也可以对整个寄存器进行访问:

//*****************************************************************************

//用户源文件

//*****************************************************************************

CpuTimer0Regs.TCR.bit.TSS=1; //访问一个单独的位域的示例

CpuTimer0Regs.TCR.all=TSS_MASK; //访问整个寄存器的示例

采用位域结构体的方法具有以下优点:

(1)无须用户确定掩模值,就可对位域进行操作;

(2)可在CCS 观察窗中看到寄存器和位域的值;

(3)当使用CCS

时,编辑器会提供一张现有结构体/位域成员的列表以供选择。这一功能是CCS

自动完成的,它使编写代码变得更容易,而不必查阅寄存器和位域名文件。

掩模值是指位掩码(位屏蔽码),在下面的代码段中,常数TCR_MASK

是位掩码是用于置位或清除较大字段中的一个特殊位的常数值。

#define TCR_MASK 0x0010

CpuTimer0Regs.TCR.all=TCR_MASK;

2)使用位域时,“读—修改—写”的注意事项当对寄存器中的单个位域进行写操作时,硬件将执行一个读—修改—写的操作,即读出寄存器中的内容,修改单个位域的值及回写整个寄存器。上述操作在F28x

上的单个周期内完成。当发生回写操作时,寄存器内的其他位将被写入读出时所读到的同一个数值。有些寄存器没有采用共用体定义,是因为不推荐采用这种方式访问,也存在一些例外情况,包括:

(1)具有写1 清除位的寄存器,如事件管理标志寄存器;

(2)无论在什么时候访问寄存器,都必须用特殊方式对位进行写入操作的寄存器,如看门狗控制寄存器。

没有位域结构体和共用体定义的寄存器,不使用*.bit 或*.all

名称进行访问,例如:

//*****************************************************************************

//用户源文件

//*****************************************************************************

SysCtrlRegs.WDCR=0x0068;

3)代码长度考量

采用位域定义访问寄存器,可使代码变得易读、易修改和易维护。当需要对寄存器中单独某位域进行访问或者查询时,使用这种方法也非常有效。然而,值得注意的是:当对一个寄存器进行一定数量的访问时,使用*.bit

位域定义形式进行访问将导致比使用*.all 形式对寄存器进行写操作需要更多的代码,例如:

//*****************************************************************************

//用户源文件

//*****************************************************************************

CpuTimer0Regs.TCR.bit.TSS=1; //1= 停止定时器

CpuTimer0Regs.TCR.bit.TRB=1; //1= 重装定时器

CpuTimer0Regs.TCR.bit.SOFT=1; //当SOFT=1且FREE=1时,定时器自由运行

CpuTimer2Regs.TCR.bit.FREE=1;

CpuTimer2Regs.TCR.bit.TIE=1; //1= 使能定时器中断

采用上述的方法,可以得到可读性非常强并且易于修改的代码。不足是代码有些长。如果用户更加关心代码的长度,可使用*.all

结构对寄存器进行一次性的写操作。

//*****************************************************************************

//用户源文件

//*****************************************************************************

CpuTimer0Regs.TCR.all=TCR_MASK; //TCR_MASK 可在文件头部用#define 定义

1.2.4

共用体结构体位域的应用实例

1.2.4 共用体结构体位域的应用实例

【例】设count 是一个16

位的无符号整型计数器,最大计数为十六进制0xffff,要求将这个计数值以十六进制半字节的形式分解出来。

对于上述实例通常采用移位的方法求解,而采用共用体结构体位域的方法不需要通过移位运算。以下,对CCS

在头文件中大量使用的共用体结构体位域进行注解。

先定义一个共用体结构体位域:

Uint16 cont,g,s,b,q; //16 位无符号整型变量定义

cont=0xfedc; //对cont 赋值

union //共用体类型定义

{ Uint16 i; //定义i 为16 位无符号整型变量

struct //结构体类型定义

{

Uint16 low:4; //最低4 位在前。从最低4 位开始,取每4 位构成半字节

Uint16 mid0:4;

Uint16 mid1:4;

Uint16 high:4; //最高4 位在后

}HalfByte; //HalfByte 为具有所定义的结构体类型的变量

}Count; //Count为具有所定义的共用体类型的变量

union 定义一个共用体类型,它包含两个成员:一个是16

位无符号整型变量i,另一个是包含4

个半字节变量(low,mid0,mid1,high)的结构体类型。它们占用同一个内存单元,通过对i(Count.i)进行赋值,可以完成对结构体4

个变量的赋值。

上面的程序,在定义共用体类型和结构体类型的同时,直接完成了这两个类型变量的定义,而未定义共用体和结构体类型名。即HalfByte

是一个具有所定义的结构体类型的变量,Count

是一个具有所定义的共用体类型的变量。理解了共用体与结构体之间的关系,下面的赋值指令就清楚了。

Count.i = cont; //对共用体类型成员i 进行赋值

g=Count.HalfByte.low; //将cont 的0~3 位赋值给g,g=0x000c

s=Count.HalfByte.mid0; //将cont 的4~7 位赋值给s,s=0x000d

b=Count.HalfByte.mid1; //将cont 的8~11 位赋值给b,b=0x000e

q=Count.HalfByte.high; //将cont 的12~15 位赋值给q,q=0x000f

通过共用体结构体定义,当对共用体类型成员i

进行赋值时,由于结构体类型变量HalfByte 与i 占用同一个内存单元,因此,也就完成了对HalfByte 的各成员的赋值。

C

语言的共用体结构体位域定义,可以完成对寄存器位域的访问。至于被访问的位域在内存中的具体位置则由编译器安排,编程者可以不必关注。

下面是一个访问寄存器位域的例子,供读者参考。

先建立一个共用体结构体位域定义,将某个寄存器的16

位,从最低位到最高位分别

定义为Bit1,Bit2,…,Bit16。

union //共用体类型定义

{ Uint16 all; //定义all 为16 位无符号整型变量

struct //结构体类型定义

{

Uint16 Bit1:1; //0 位Bit1 取寄存器最低位0 位,以下顺序取1 位直到最高位

Uint16 Bit2:1; //1

Uint16 Bit3:1; //2

Uint16 Bit4:1; //3

Uint16 Bit5:1; //4

Uint16 Bit6:1; //5

Uint16 Bit7:1; //6

Uint16 Bit8:1; //7

Uint16 Bit9:1; //8

Uint16 Bit10:1; //9

Uint16 Bit11:1; //10

Uint16 Bit12:1; //11

Uint16 Bit13:1; //12

Uint16 Bit14:1; //13

Uint16 Bit15:1; //14

Uint16 Bit16:1; //15

}bit; //bit为具有所定义的结构体类型的变量

}CtrlBit; //CtrlBit 为具有所定义的共用体类型的变量

有了上面的定义之后,要访问某一个位或某些位就很容易了。比如要置Bit4,Bit8,Bit12 及Bit16

为1,可用两种方法进行:

方法一:

CtrlBit.bit.Bit4=1;

CtrlBit.bit.Bit8=1;

CtrlBit.bit.Bit12= 1;

CtrlBit.bit.Bit16= 1;

方法二:

CtrlBit.all=0x8888;

来源:http://book.51cto.com/art/201012/237937.htm

ccs中c语言定义布尔常量,CCS中寄存器定义方法相关推荐

  1. ccs中c语言定义布尔常量,ccs库里面有变量的定义,我在添加了头文件后编译显示没有定义变量呢...

    用CCS6.0编译总是出类似的错误,最近写一个I2C的代码一直弄不好,请大神们知道一下吧这个是库里面的例子加载编译出来都是错 #include #include #include #include & ...

  2. java定义字符串常量_Java中的字符串常量池

    ava中字符串对象创建有两种形式,一种为字面量形式,如String str = "droid";,另一种就是使用new这种标准的构造对象的方法,如String str = new ...

  3. 计算机中c语言的应用特点,计算机中C语言的应用特点分析

    计算机中C语言的应用特点分析 阮鹏飞 (荆楚理工学院湖北·荆门448000) 摘要在计算机的应用过程中,C语言是一门十分常用的语言.和其他的语言相比较而言,C语言是一门面向过程的语言,其中的各个环节的 ...

  4. 计算机中c语言的应用特点,计算机中C语言应用特点.doc

    计算机中C语言应用特点 计算机中C语言应用特点 摘 要 在计算机应用过程中,C语言是一门比较常用的语言,其为各个环节的操作提供了便利.与其他高级计算机语言相比,C语言有其独特的应用特点,因为C语言语法 ...

  5. STM32中C语言知识点:初学者必看,老鸟复习(长文总结)

    说在前面的话 一位初学单片机的小伙伴让我推荐C语言书籍,因为C语言基础比较差,想把C语言重新学一遍,再去学单片机,我以前刚学单片机的时候也有这样子的想法. 其实C语言是可以边学单片机边学的,学单片机的 ...

  6. java堆和栈 常量池_GitHub - han-guang-xue/difference-of-stack-heap-pool: Java中堆、栈和常量池的区别...

    Java中堆.栈和常量池的区别 栈 堆 常量池的概念 首先我们先了解一下概念,Java把内存分成两种,一种叫做栈内存,一种叫做堆内存. 栈内存 存放基本类型的变量数据和对象类型的引用(请注意存放的是引 ...

  7. 高端网站建设中多语言网站本地化的实用技巧

    企业会随着业务市场的不断扩大而发生与其他国家或地区合作的情况,对于企业来说这即是机遇也是挑战,想要获得成功的企业应该认真的思考这些问题.企业想要向国外市场发展自己的网站多语言化,并做到合理的本地化. ...

  8. c语言的运用,解析计算机中C语言的运用

    摘 要:随着我国计算机水平的不断提升和计算机程序设计的持续完善,在计算机程序设计过程中C语言得到了越来越广泛的应用.本文从对C语言进行概述入手,对c语言应用特点和计算机中C语言的运用进行了分析. 关键 ...

  9. java 定义一组常量用什么最好_Java语言中定义常量注意事项解析

    一.常量定义的基本注意事项. 在Java语言中,主要是利用final关键字(在Java类中灵活使用Static关键字)来定义常量.当常量被设定后,一般情况下就不允许再进行更改.如可以利用如下的形式来定 ...

最新文章

  1. PHP面试MySQL数据库的索引
  2. android.xml设置全屏,Android全屏设置的方法总结
  3. 搭建elasticsearch测试工程
  4. 谈谈SQL Server高可用的常见问题
  5. windows 环境下Eclipse开发MapReduce环境设置
  6. 数字效率Evernote超效率数字笔记术
  7. 上周热点回顾(6.14-6.20)
  8. swagger默认访问路径_swagger 如何配置项目访问路径
  9. Javascript中的form
  10. 一加7T Pro最新渲染图曝光:背部有小改动
  11. c语言分治算法之归并排序,分治算法之归并排序
  12. I00026 计算数根
  13. Asp.net实用技巧
  14. 线程池合适的线程数量
  15. java中如何表示圆周率
  16. 黑马程序员---三天快速入门Python机器学习(第一天)
  17. opencv与vs的版本
  18. 用计算机抽样,利用计算机代替随机数骰子进行随机抽样
  19. 二阶梯度优化新崛起,超越 Adam,Transformer 只需一半迭代量
  20. 使用百度UNIT搭建智能对话系统_订火车票实例

热门文章

  1. 年终盘点丨2020边缘计算大事记
  2. MySQL细节篇02_modify和change的区别
  3. 发现今年是阿里和腾讯这么多年来最大规模的校招
  4. Windows Defender 防病毒发现威胁;关闭;
  5. 美团点评技术年货分享
  6. 3dmark android 中文,貌似不靠谱,Android平台3DMark测试版初体验
  7. YX4057C芯片资料
  8. 2019度小满秋招研发编程题_数字的情绪
  9. MacBook设置中国时区时间
  10. 算法小白鼠毒药c语言,EM笔试题收藏 .doc