msp430头文件中 DEFC DEFW 及周边的解释

发布者:AngelicHeart最新更新时间:2015-11-11 来源: eefocus关键字:msp430  头文件  DEFC  DEFW 手机看文章 扫描二维码
随时随地手机看文章
现象:

     从这看见DEFC DEFW


#define __MSP430_HAS_SD16_A1__       

#define SD16INCTL0_         (0x00B0u) 
DEFC(   SD16INCTL0        , SD16INCTL0_)
#define SD16AE_             (0x00B7u) 
DEFC(   SD16AE            , SD16AE_)
#define SD16CONF0_          (0x00F7u) 
DEFC(   SD16CONF0         , SD16CONF0_)
#define SD16CONF1_          (0x00BFu) 
DEFC(   SD16CONF1         , SD16CONF1_)
                                     

#define SD16CTL_            (0x0100u) 
DEFW(   SD16CTL           , SD16CTL_)
#define SD16CCTL0_          (0x0102u) 
DEFW(   SD16CCTL0         , SD16CCTL0_)
#define SD16IV_             (0x0110u) 
DEFW(   SD16IV            , SD16IV_)
#define SD16MEM0_           (0x0112u) 
DEFW(   SD16MEM0          , SD16MEM0_)

      接着找到下面的定义

#ifdef __IAR_SYSTEMS_ICC__
#include "in430.h"
#pragma language=extended

#define DEFC(name, address) __no_init volatile unsigned char name @ address;
#define DEFW(name, address) __no_init volatile unsigned short name @ address;
#define DEFXC  volatile unsigned char
#define DEFXW  volatile unsigned short

#endif 


#ifdef __IAR_SYSTEMS_ASM__
#define DEFC(name, address) sfrb name = address;
#define DEFW(name, address) sfrw name = address;

 

解释:

数值分配伪指令:主要用于对符合的数值定义,以下是常见的定义

EQU     在当前模块中赋予一个永久的值

      同上

DEFINE       在多个模块环境下,定义一个在整个文件中都有效的值

sfrb和sfrw   是老的版本对功能寄存器的定义

DEFC         是新的版本对功能寄存器的定义

READ_ONLY DEFC    是新的版本定义只读功能模块寄存器

 

3.3.1  扩展关键字
关键字的概念前面已经介绍过。下面是除了 C语言标准关键字之外的扩展部分,这里只
介绍常用的扩展关键字。
1.asm
也可以写成 __asm。功能是在 C 程序中直接嵌入汇编语言。
语法:
asm ("string");
其中 string 必须是有效的汇编语句。
2.__interrupt
放在函数前面,标志中断函数。下面这段程序是异步串行口 UART0 的接收中断函数。
UART0RX_VECTOR 为异步串行口 UART0 的接收中断向量。
举例:
#pragma vector=UART0RX_VECTOR
__interrupt void UART0_R(void)   //UART0接收中断
         
 TXBUF0=RXBUF0;
}
3.__monitor
放在函数前面, 功能是当这一函数执行的时候自动关闭中断。 应该尽量缩短这样的函数,
否则,中断事件无法得到及时的响应。
4.__no_init
放在全局变量前面,功能是使程序启动时不为变量赋初值。
5.__raw
编译中断函数时,编译器会自动生成一段代码,首先保存当时所用到 CPU 内寄存器的内
容,退出中断程序时再进行恢复。将__raw放在中断函数前可以禁止保存 CPU内寄存器的过
程,当然退出时也不会恢复。是否为中断函数使用此关键字要根据需要而定。
6.__regvar
放在变量前面,作用是声明变量为寄存器变量。可以用于整数、指针、32 位浮点数以及
只含有一个元素的结构和联合。寄存器变量的地址只能为 R4 或者R5,也不能用指针指向这
个寄存器变量,而且必须用__no_init 禁止初始化。如:
__regvar __no_init unsigned char q0 @ __R4; 
– 57 –
其他不常用的关键字还有:__data16、__intrinsic、__noreturn、 __root、__task、__word16。

 

IAR编程环境 _no_init

2008-10-20 14:58
提问者:侯宁05电61 | 悬赏分:10 | 浏览次数:1980次
extern volatile BYTE sppRxStatus;
extern volatile BYTE sppTxStatus;
__no_init SPP_RX_STRUCT rxData @ "PM0_XDATA";
__no_init SPP_TX_STRUCT txData @ "PM0_XDATA";
大侠告诉我,后两句是什么意思?_no_init在编程环境中是蓝色的字。
@ 符号什么意思。
 
最佳答案
@是指定地址,__no_init 是一个SEGMENT,是给LINKER用的,定义到不初始化的块中去。
@就是指定地址,这个应该没什么好说的了,大部分编译器都这么用。你应该理解这个吧。
你定义全局变量的时候比如int char;  即使你没有赋值给他,编译器还是会给他一个初始化值0,编译的时候编译器把他分配到初始化为零的那个SEGMENG中去了。编译器默认的有几个块,初始化为零的块,初始化不为零的块,和不初始化的块,你可以定义自己的块,如你的PM0_XDATA,这个就是你自己定义的一个块,那你的这个块是个什么属性呢,就是,__no_init 属性,有了这个属性,编译器只给你分配空间,不给你初始化。
赞同43
回答者: 0223050423 | 二级
 
 
昵称:sharkdo   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_init是IAR扩展语法里面的一个扩展关键字。作用是声明一个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 寄存器类型的字。

 [page]

使用语法如下: 

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位的地址存储空间分成2个8bits或者1个16位。可以实现字访问,也可以实现字节访问。以上定义是将一个无名的union与address联系起来,使得访问address对应的内存时,就像访问union一样。

 

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

#define RF1AIFCTL1_         (0x0F02u)  

DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_) 

#define RF1AIFIFG         RF1AIFCTL1_L  

#define RF1AIFIE          RF1AIFCTL1_H 

可以发现,第一个宏定义,“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)  

DEFCW(   RF1AIFCTL1        , RF1AIFCTL1_)

#define RF1AIFIFG         RF1AIFCTL1_L  

#define RF1AIFIE          RF1AIFCTL1_H  

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

 __no_init union

{

 struct

 {

    volatile unsigned char RF1AIFCTL1_L;

    volatile unsigned char RF1AIFCTL1_H;

 };  

 volatile unsigned short   RF1AIFCTL1;  

} @ (0x0F02u); 

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

 

#define RF1AIFIFG         RF1AIFCTL1_L  

#define RF1AIFIE          RF1AIFCTL1_H 

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


关键字:msp430  头文件  DEFC  DEFW 引用地址:msp430头文件中 DEFC DEFW 及周边的解释

上一篇:单片机C语言code与data的作用
下一篇:keil应用小贴士:Use MicroLIB是干什么的

推荐阅读最新更新时间:2024-03-16 14:38

如何快速设计红外体温检测仪?TI来支招!
  体温检测是我们居家,出入社区或工作场所以及出行中的必要监测。红外体温检测仪通过非接触式测温有助于减少接触传染。在这里我们来和大家谈谈这个系统和主要的设计方案。   MSP430系列单片机是德州仪器(TI)公司1996年开始推向市场的一种16位超低功耗RISC混合信号处理器,基于该系列产品开发出来的应用不计其数,数不胜数,尤其是面向传感与检测类终端应用,因其在片上集成有高性能ADC、LCD驱动、串口通讯、PWM输出等模块,成为了红外体温检测仪厂商的不二之选。配合TI提供的丰富的线上软硬件设计资源,使得开发人员可以大大简化设计流程,快速开发红外体温检测仪原型机,同时节省电路板空间从而降低成本。   下图提供了基于MSP43
[单片机]
如何快速设计红外体温检测仪?TI来支招!
关于MSP430单片机串口通信丢失数据
研究摸索了接近一个星期,把所遇到的问题写出来以供参考。 最开始看一个官方的串口收发数据的示例,然后自己操作后收发数据老是会丢失一个数据,然后看User’s Guide,取消了函数收发的方法直接用寄存器操作,问题解决。 接下来写一个组帧协议,收发完全正常。但是看上去非常的杂乱就想美化一下,就开始写函数,进行函数调用。好了,这下问题又来了,数据又会丢失。 接近一个星期的思前想后,发现不是自己写的代码有问题,是官方示例的波特率配置问题。大家都知道波特率表示每秒钟传送的码元符号的个数,是衡量数据传输速率的指标,它用单位时间内载波调制状态改变的次数来表示。晶振为1MHz波特率为15200,我自己改成了9600,问题解决。如何配置
[单片机]
FreeRTOS 8.2.1在MSP430 上的低功耗实现
应用FreeRTOS在MSP430上做项目已经很久了,如何配合MSP430这样的低功耗芯片让系统尽可能的工作在低功耗模式是本文的议题。 一、IDLE线程作为低功耗入口 对于现在流行的大部分RTOS来说启动系统调度环境以后,都会创建出一个IDLE线程,而这个线程又往往运行在最低的优先级,这个线程让系统的调度环境继续工作。 在FreeRTOS的网站上会建议大家引用这个线程让系统进入MSP430的低功耗模式,事实上从官方拿到的代码就有下面这一句(本文以MSP430F5438A的主芯片为例子,代码跑在EXP-MSP5438A演示板上): void vApplicationIdleHook( void ) { /* Ca
[单片机]
电容触摸MSP430电路与LED驱动电路设计详解
  MSP430系列单片机以低功耗和外设模块的丰富性而著称,而针对电容触摸应用,MSP430的PIN RO 电容触摸检测方式支持IO口直接连接检测电极,不需要任何外围器件,极大的简化了 电路设计 ,而本设计文档中使用的MSP430G2XX5 更支持多达2个IO口,可驱动24个以上的LED灯,达到理想的显示效果。   电容触摸实现原理   MSP430根据型号的不同支持多种电容触摸检测方式,有RC 震荡、比较器、PIN RO,本设计使用的是PIN Relaxation Oscillator 方式,原理如图1,芯片管脚内部检测电路由施密特触发器、反向器,以及一个电阻组成,震荡信号经过施密特触发器变成脉冲信号,再通过反向器反馈回RC 电
[单片机]
电容触摸<font color='red'>MSP430</font>电路与LED驱动电路设计详解
51单片机keilC中头文件absacc.h作用
当51单片机通过8255和锁存器74LS273来扩展IO时,经常用到头文件absacc.h。 在程序中,用 #include absacc.h 即可使用其中定义的宏来访问绝对地址,包括:CBYTE、XBYTE、PWORD、DBYTE、CWORD、XWORD、PBYTE、DWORD 例如: rval=CBYTE ;指向程序存贮器的0002h地址 rval=XWORD ;指向外RAM的0004h地址 KEIL 中ABSACC.H 定义如下: #ifndef __ABSACC_H__ #define __ABSACC_H__ #define CBYTE ((unsigned char volatile code *) 0) #de
[单片机]
基于MSP430F149的温度采集报警系统的设计和实现
  引言   随着电子计算机信息技术的不断发展和完善,采用单片机实现的温度监控系统的应用越来越多。且采用单片机实现的温度监控系统具有自动化和无人值守等特点,使得它们在许多应用场合得到了广泛的应用。本文介绍的温度采集报警系统具有一定的通用性,它采用传感器与单片机的A/D通道相连,简化了模拟采集的设计,从而减小设计的复杂性,增加系统的可靠性,也同时减小了PCB的面积。报警和显示模块主要是驱动蜂鸣器实现报警功能和便于实时观察。该系统充分体现了智能化、低功耗、高精度的发展趋势。重点在于传感器的设计及智能化、低功耗的硬件电路设计上。   2 系统硬件设计与实现(单元电路设计)   系统以单片机MSP430F149为核心。本系统的功能设计目标
[单片机]
怎样使用C语言来编写MSP430的高质量代码
简介:微处理器一般用于特定环境和特定用途,出于成本、功耗和体积的考虑,一般都要求尽量节省使用资源,并且,由于微处理器硬件一般都不支持有符号数、浮点数的运算,且运算位有限,因此,分配变量时必须仔细。另外要说明的是,速度和存储器的消耗经常是2个不可兼顾的目标,在多数情况下,编程者必须根据实际情况作出权衡和取舍。 需要注意的事项如下: 1) 通常在满足运算需求的前提下,尽量选择为变量定义字节少的数据类型。 比如最常用的int和char,int是16位的,char是8位的,如果没有必要,不要使用int,而且使用char也最好使用unsigned char。运行时,可以在变量窗口看到,使用类型为unsigned char的变量是
[单片机]
MSP430F149在电力测控保护产品中的应用
MSP430F149(以下简称“F149”)是德州仪器(TI)公司推出超低功耗Flash型16位RISC指令集单片机。F149有丰富的内部硬件资源,是一款性价比极高的工业级芯片。在应用中,F149不需做过多的扩展,适合要求快速处理的实时系统,故可在电力系统微机测量和保护方面得以应用。详细的F149资料可参阅有关文献,本文主要对电力系统中基本参数测量的实现方法和开发中一些应注意的问题进行论述。 1 F149外围模拟信号调理 在电力系统微机测量中,通常将一次额定电流和电压通过电流互感器(TA)、电压互感器(TV)分别转换为0~5A的电流信号和0~100V的电压信号,该信号再经一级互感器转换为数百mV~几V的电压信号,具体输出电压的
[测试测量]
<font color='red'>MSP430</font>F149在电力测控保护产品中的应用
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved