IAR C编译器相关(C语言补充学习)

        转自

        编译MSP430工程文件时,看到:

#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   是新的版本定义只读功能模块寄存器


        扩展关键字(常用):

        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。

        其他不常用的关键字还有:__data16、__intrinsic、__noreturn、 __root、__task、__word16

       

        实例解析:

        1、 __no_init SPP_RX_STRUCT rxData @ "PM0_XDATA";

               __no_init SPP_TX_STRUCT txData @ "PM0_XDATA";

        解析:

        @是指定地址,__no_init 是一个SEGMENT,是给LINKER用的,定义到不初始化的块中去。
        定义全局变量的时候比如int char; 即使你没有赋值给他,编译器还是会给他一个初始化值0,编译的时候编译器把他分配到初始化为零的那个SEGMENT中去了。编译器默认的有几个块,初始化为零的块,初始化不为零的块,和不初始化的块,你可以定义自己的块,如你的PM0_XDATA,这个就是你自己定义的一个块,那你的这个块是个什么属性呢,就是,__no_init 属性,有了这个属性,编译器只给你分配空间,不给你初始化。

       

        补充:

        volatile:作用: 作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。

        #pragma:指令对每个编译器给出了一个方法,在保持与C和C++语言完全兼容的情况下,给出主机或操作系统专有的特征。依据定义,编译指示是机器或操作系统专有的,且对于每个编译器都是不同的。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值