1.1.1 扩展关键字
1. asm 也可以写成 _asm。功能是在c程序中直接嵌入汇编语言。 asm(“string”); 其中string必须是有效的汇编语句。
2. __interrupt 放在函数前面,标志中断函数。下面这段程序是异步串行口UART0的接受中断函数。UART0RX_VECTOR为异步串行口UART0的接受中断向量。 举例: #pragma vector=UART0RX_VECTOR __interrupt void UARTO_R(void) { 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.1.2 内部函数
1. __bcd_add_short Unsigned short __bcd_add_short(unsigned short,unsigned short); 功能:两个16为BCD格式的数字相加,返回和。
2. __bcd_add_long Unsigned long __bcd_add_long(unsigned long,unsigned long); 功能:两个32位BCD格式的数字相加,返回和。
3. __bcd_add_long_long 功能:两个64位BCD格式的数字相加,返回和。
4. __bic_SR_register Void _bic_SR_register(unsigned short); 功能:将CPU中SR寄存器中的某些位清零。其参数为屏蔽码,需要清零的位为1。
5. __bic_SR_register_on_exit Void __bic_SR_register_on_exit(unsigned short); 功能:用于一个中断函数或者不可中断函数(标志为__monitor)返回时,将CPU内SR寄存器中得某些位清0.其参数为屏蔽码,需要清零的位为1.
6. __bis_SR_register Void __bis_SR_register(unsigned short); 功能:将CPU中SR寄存器中得某些位置1.其参数为屏蔽码,需要置1的位为1.
7. __bis_SR_register_on_exit Void __bis_SR_register_on_exit(unsigned short); 功能:用于一个中断函数或者不可中断函数(标志为__monitor)返回时,将CPU内SR寄存器中得某些位置1.其参数为屏蔽码,需要置1的位为1.
8. __disable_interrupt Void __disable_interrupt(void); 功能:关闭全局中断。先执行DINT指令,关闭全局中断,然后再执行NOP指令。空指令是为了确保关闭了全局中断之后再执行下面的程序。
9. __enable_interrupt Void __enable_interrupt(void); 功能:使用_EINT()指令打开全局中断。
10. __even_in_range Unsigned short __even_in_range(unsigned short value,unsigned short upper_limit);
功能:只能与switch语句结合使用,判断value是否为偶数且小于等于upper_limit.
举例:
Unsigned int MoonRiver,iq0; Iq0=2;
Switch(__even_in_range(iq0,4))
{
Case 0:
MoonRiver=0;
Break;
Case 2:
MoonRiver=2;
break;
} 结果:假设iq0的值为2,执行完毕时MoonRiver=2.否则,与普通的switch语句一样,跳过case部分,直接执行下面的程序。使用__even_in_range的好处是可以生成效率比较高的代码,在判断多中断源时可以使用此函数。
11. __get_interrupt_state Istate_t __get_interrupt_state(void); 功能:返回当前的中断状态。返回值istate_t为一结构,通过此函数可以将获得当前的中断状态并保存,将来可以使用__set_interrupt_state恢复中断状态。
12. __get_R4_register Unsigned short __get_R4_register(void); 功能:返回寄存器R4的值,只在R4被锁定时有效。
13. __get_R5_register Unsigned short __get_R5_register(void); 功能:返回寄存器R5的值,只在R5被锁定时有效。
14. __get_SP_register Unsigned short __get_SP_register(void); 功能:返回堆栈指针寄存器SP的值。
15. __get_SR_register Unsigned short __get_SR_register(void); 功能:返回CPU中状态寄存器SR的值。
16. __get_SR_register_on_exit Unsigned short __get_SR_register_on_exit(void); 功能:用于一个中断函数或者不可中断函数(标志为__monitor)返回时,返回状态寄存器SR的值。只在中断函数或者不可中断函数中有效。
17. __low_power_mode_n Void __low_power_mode_n(void); 功能:进入低功耗模式0~4.
18. __low_power_mode_off_on_exit Void __low_power_mode_off_on_exit(void); 功能:从一个中断函数或者不可中断函数(标志为__monitor)返回时退出低功耗模式。只在 中断或者不可中断函数中有效。
19. __no_operation Void __no_operation(void); 功能:执行NOP指令。
20. __op_code __op_code(unsigned short); 功能:在指令流中插入一个常数。
21. __segment_begin Void *__segment_begin(segment); 功能:segment 是段的名字,必须是字符串。返回指向segment段的地址。此处的段是程序中定义的数据段、代码段、堆栈段等,一般用户可以使用编译器的默认设置。
22. __segment_end Void *__segment_end(segment); 功能:segment是段的名字,必须是字符串。返回指向segment 段结束后的第一个字节的地址。
23. __set_interrupt_state Void __set_interrupt_state(istate_t); 功能:恢复istate_t中保存的中断状态。
24. __set_R4_register Void __set_R4_register(unsigned short); 功能:将unsigned short值赋给寄存器R4,只在R4被锁定时有效。
25. __set_R5_register Void __set_R5_register(unsigned short); 功能:将unsigned short 值赋给寄存器R5,只在R5被锁定时有效。
26. __set_SP_register Void __set_SP_register(unsigned short); 功能:给堆栈指针寄存器SP赋值。
27. __swap_bytes Unsigned short __swap_bytes(unsigned short); 功能:一个16位的无符号整数,高8位与低8位进行交换。如0x1234交换后0x3412.
1.1.3 扩展定义
1. PxIN、PxOUT、PxDIR、PxSEL X为端口号。IN为端口输入寄存器,OUT为端口输出寄存器,DIR为端口方向控制寄存器,SEL为端口第二功能选择寄存器。 举例: Moon=P1IN;//读端口P1的值 P3OUT=5;//P3端口输出5 P2DIR=0XF0;//P2端口的高四位为输出,低4位为输入 P6SEL=0XF;//P6端口的高四位用作I/O端口,低4位用于第二功能
2. BITx X的取值范围为0~F。代表寄存器的某一位。
其定义为:
#define BIT0 (0X0001)
#define BIT1 (0X0002)
… …
#define BITE (0X4000)
#define BITF (0X8000)
BIT0为最低位,BITF为最高位。MSP430是不支持位操作的,如果想对位操作,最好的方法就是通过位屏蔽来实现。
举例: P1OUT|=BIT0;//将P1口的最低位输出置1
P1OUT&=~BIT7;//将P1口的最高位输出清0,P1口只有8位
3. LMPx X:0~4.进入0~4低功耗模式。其定义为: #define LPM0 _BIS_SR(LPM0_bits)//进入低功耗模式0 …
#define LPM0 _BIS_SR(LPM4_BITS)//进入低功耗模式4
从以上代码可以看出扩展定义是对内部函数的二次包装
举例: LPM0;//进入低功耗模式0
LPM4;//进入低功耗模式4
4. LPMx_EXIT X:0~4。退出0~4低功耗模式。
其定义为: #define LPM0_EXIT _BIC_SR_IRQ(LPM0_bits)//退出低功耗模式0 …
#define LPM4_EXIT _BIC_SR_IRQ(LPM4_bits)//退出低功耗模式4 举例: LPM0_EXIT; LPM4_EXIT;
5. _EINT() 打开全局中断控制,使GIE=1。
6. _DINT() 关闭全局中断控制,使GIE=0.执行__disable_interrupt指令。
7. _NOP() 空操作。执行__no_operation指令。
8. _OPC(x) 在指令流中插入一个常数。X为unsigned char 类型。执行__op_code指令。
9. _SWAP_BYTES(x) X是一个16位的无符号整数,高8位与低8位进行交换。执行__swap_bytes指令。
10. __no_init [数据类型] 变量名 @ 地址 在某一固定地址处定义一个不进行初始化的变量,地址可以在RAM或FLASH内。如果使用此方式定义在RAM内的变量需要赋值,那么必须先定义,然后才能赋值。
举例: /*分配变量MoonRiver在RAM地址0x210*/
__no_init unsigned int MoonRiver @ 0x210;//没有初始化
MoonRiver=100; //初始化MoonRiver 为100
/*分配变量MoonRiver在FLASH地址0XFFC0*/
__no_init float MoonRiver @0Xffc0; /*分配数组MoonRiver[3] 在RAM地址0X200*/
__no_init char MoonRiver[3] @0x200; /*分配结构sMoonRiver在RAM地址0X200*/
typedef struct
{
Unsigned char q0;
Unsigned char iq0;
}sMoonRiver; //定义一个结构型的数据类型,名为sMoonRiver
__no_init sMoonRiver MoonRiver @0x200;//声明变量MoonRiver,其数据类型为sMoonRiver MoonRiver.q0=100; MoonRiver.iq0=1000; //为MoonRiver赋初值
11. Const [数据类型] 变量名 @ 地址 在某一固定地址处定义一个只读变量,并且只能在定义的时候赋初值。这种定义变量的方式在FLASH的固定地址处分配变量时非常有用。
举例: /*分配变量MoonRiver在RAM地址0x210*/
Const unsigned int MoonRiver @0x210 =100;//初始化MoonRiver为100
/*分配变量MoonRiver在FLASH地址0XFFC0*/
Const float MoonRiver @0XFFC0=32.5;//初始化MoonRiver为32.5
/*分配数组MoonRiver[3]在FLASH地址0XFF00*/
Const char MoonRiver[3] @0Xff00{0,1,2};
/*分配结构sMoonRiver在RAM地址0XFFD0*/
Typedef struct
{
Unsigned char q0;
Unsigned char iq0;
}sMoonRiver;//定义一个结构型的数据类型,取名为sMoonRiver Const sMoonRiver MoonRiver @ 0xffd0={2,500};
//声明变量MoonRiver,其数据类型为sMoonRiver 如果不需要确定地址,指向在FLASH中分配一个变量,形式为: Const [数据类型] 变量名; 举例: Const unsigned int MoonRiver=100;