IAR 430 头文件中#define定义的部分解释

IAR 430 头文件中#define定义的部分解释

今天在阅读RF_Example_Code_v1.0中头文件cc430x613x.h时发现了几部分的疑问。

 

首先来看一下cc430x613x.h 中的3#define的例子:

 

#define DEFC(name, address) __no_init volatile unsigned char name @ address;

 

 

#define DEFW(name, address) __no_init volatile unsigned short name @ address;

 

#define DEFCW(name, address) __no_init union \

 

{ \

 

 struct \

 

 { \

 

    volatile unsigned char name##_L; \

 

    volatile unsigned char name##_H; \

 

 }; \

 

 volatile unsigned short   name; \

 

} @ address;

 

 

 

前面的两个#define的用法是一样的。首先我可以发现,在宏定义里面都有一个关键字__no_init。查看了《MSP430 IAR C/EC++ Compiler Reference Guide》内的IAR Language Extension Overview 可以发现,__no_initIAR扩展语法里面的一个扩展关键字。作用是声明一个non-volatile类型的内存地址(Support non-valotile memory)。

 

于是解决了__no_init的问题。

 

再者对@这个字符存在一定的疑问,于是上网查了查资料。虽然对于@这个字符的用法还是不是很明确,但是可以明确的是:

 

#define DEFC(name, address) __no_init volatile unsigned char name @ address;

 

#define DEFC(name, address) sfrb name = address;

 

这两种定义是等价的,但是后者是基于汇编嵌入式编程的情况下才成立。也就是说“=”是MSP430汇编中数据分配伪指令中的一种。我们来看一下MSP430汇编的数据分配伪指令有哪些:

 

这类指令有以下一些:

 

SET (VAR, ASSIGN) 赋予一个临时值;

 

EQU (=) 在当前模块中赋予一个永久的值;

 

DEFINE 定义一个整个文件中都有效的值;

 

sfrb 寄存器类型的字节;

 

sfrw 寄存器类型的字。

 

使用语法如下:

 

label SET expr

 

label EQU expr

 

label = expr

 

label DEFINE expr

 

[const] sfrb register = value

 

[const] sfrw register = value

 

其中,

 

label 定义一个标志符、

 

expr 标志符的值、

 

register 特殊功能寄存器、

 

value 特殊功能寄存器的值。

 

在下面的例子中使用了局部变量与全局变量,在模块add1 中定义了符号value ,同样在

 

模块add2 中也定义了符号value,但它们表示两个不同的量,都只在各自的模块内部有效,

 

这是局部变量。而在模块add1 中定义的locn 则为全局变量,在两个模块中表示同一个值。

 

NAME add1

 

locn DEFINE 100H

 

value EQU 77

 

MOV locn,R4

 

ADD #value,R4

 

ENDMOD

 

NAME add2

 

value EQU 88

 

MOV locn,R5

 

ADD #value,R5

 

END

 

很明显,“=”也就是EQU,作用是:在当前模块中赋予一个永久的值。

 

至此,

 

#define DEFCW(name, address) __no_init union \

 

{ \

 

 struct \

 

 { \

 

    volatile unsigned char name##_L; \

 

    volatile unsigned char name##_H; \

 

 }; \

 

 volatile unsigned short   name; \

 

} @ address;

 

这种定义也变得相对好理解。以上的这种定义只是多了一个union的定义,将一个16位的地址存储空间分成28bits或者116位。可以实现字访问,也可以实现字节访问。以上定义是将一个无名的unionaddress联系起来,使得访问address对应的内存时,就像访问union一样。

 

那么对于下面的一些看起来貌似比较复杂的定义就相对比较好理解了:

 

#define RF1AIFCTL1_         (0x0F02u) /* Radio interface control register 1 */

 

DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_)

 

#define RF1AIFIFG         RF1AIFCTL1_L /* Radio interface interrupt flag register */

 

#define RF1AIFIE          RF1AIFCTL1_H /* Radio interface interrupt enable register */

 

可以发现,第一个宏定义,“RF1AIFCTL1_”在字符串的最后带一个下划线,其实代表这只是一个地址。而通过宏扩展DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_),将会被扩展为:

 

__no_init union \

 

{ \

 

 struct \

 

 { \

 

    volatile unsigned char RF1AIFCTL1_L; \

 

    volatile unsigned char RF1AIFCTL1_H; \

 

 }; \

 

 volatile unsigned short   RF1AIFCTL1; \

 

} @ (0x0F02u);

 

 

 

关于@的用法,今天查阅了《MSP430 IAR C/EC++ Compiler Reference Guide》,找到了结果:

 

A variable that has been explicitly placed at an address, for example by using the compiler @ syntax, will be placed in either the DATA16_AC or the DATA16_AN segment.

 

从中可以看出,@是一种语法。那么它的作用很明显就是将变量放置到对应的地址中。使用@,一个变量可以明确的制定一个存储地址。

 

因此之前的宏定义就变得好理解了。

 

#define DEFC(name, address) __no_init volatile unsigned char name @ address;

 

就是将name变量存放在address地址中,那么如此一来就可以为每个寄存器进行命名了,也就是说可以实现每个寄存器对应一个或者多个变量。

 

至此头文件中另外一个问题也迎刃而解:

 

#define RF1AIFCTL1_         (0x0F02u) /* Radio interface control register 1 */

 

DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_)

 

#define RF1AIFIFG         RF1AIFCTL1_L /* Radio interface interrupt flag register */

 

#define RF1AIFIE          RF1AIFCTL1_H /* Radio interface interrupt enable register */

 

我们将DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_)展开:

 

__no_init union \

 

{ \

 

 struct \

 

 { \

 

    volatile unsigned char RF1AIFCTL1_L; \

 

    volatile unsigned char RF1AIFCTL1_H; \

 

 }; \

 

 volatile unsigned short   RF1AIFCTL1; \

 

} @ (0x0F02u);

 

那么可以知道,RF1AIFCTL1RF1AIFCTL1_LRF1AIFCTL1_H已经声明成为一个变量,存放的地址分别是0x0F02u0x0F02u+10x0F02u。因此接下来后面两条宏定义就自然的解开了。

 

#define RF1AIFIFG         RF1AIFCTL1_L /* Radio interface interrupt flag register */

 

#define RF1AIFIE          RF1AIFCTL1_H /* Radio interface interrupt enable register */

 

功能只是为变量RF1AIFCTL1_LRF1AIFCTL1_H定义了另外的一种名字作为替换。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值