嵌入式开发(单片机,dsp)中,所使用的c语言和我们平时在pc上所使用的C语言不通。
1、扩展关键字(MSP430中)
(一定要注意有时候下划线是两个)
asm
也可以写成 _asm。功能是在c程序中直接嵌入汇编语言。
Asm(“string”);
其中string必须是有效的汇编语句。
__interrupt
放在函数前面,标志中断函数。下面这段程序是异步串行口UART0的接受中断函数。UART0RX_VECTOR为异步串行口UART0的接受中断向量。
举例:
#pragma vector=UART0RX_VECTOR
__interrupt void UARTO_R(void)
{
TXBUF0=RXBUF0;
}
__monitor
放在函数前面,功能是当这一函数执行的时候自动关闭中断。应该尽量缩短这样的函数,否则,中断事件无法得到及时的响应。
__no_init
放在全局变量前面,功能是使程序启动时不为变量赋初值。
__raw
编译中断函数时,编译器会自动生成一段代码,首先保存当时所用到CPU内寄存器的内容,退出中断程序时再进行恢复。将__raw放在中断函数前可禁止保存CPU内寄存器的过程,当然退出时也不会恢复。是否为中断函数使用此关键字需要更具具体情况而定。
__regvar
放在变量前面,作用是声明变量为寄存器变量。可以用于整数、指针、32位浮点数以及只含有一个元素的结构和联合体。寄存器变量的地址只能为R4或者R5,也不能使用指针指向这个寄存器变量,而且必须用__no_init禁止初始化。
如:
__regvar __no_init unsigned char q0 @ __R4;
其他不常用的关键字还有:__data16、__intrinsic、__noreturn、__root、__task、__word16。
2、内部函数
这里所谓内部函数,就是事先定义好的,定义不包含在用户程序中(包括所引入的系统头文件)的。比如如下定义
#define _DINT() __disable_interrupt()
后者就是一个内部函数,常用的内部函数如下:
__bcd_add_short
Unsigned short __bcd_add_short(unsigned short,unsignedshort);
功能:两个16为BCD格式的数字相加,返回和。
__bcd_add_long
Unsigned long __bcd_add_long(unsigned long,unsigned long);
功能:两个32位BCD格式的数字相加,返回和。
__bcd_add_long_long
功能:两个64位BCD格式的数字相加,返回和。
__bic_SR_register
Void _bic_SR_register(unsigned short);
功能:将CPU中SR寄存器中的某些位清零。其参数为屏蔽码,需要清零的位为1。
__bic_SR_register_on_exit
Void __bic_SR_register_on_exit(unsigned short);
功能:用于一个中断函数或者不可中断函数(标志为__monitor)返回时,将CPU内SR寄存器中得某些位清0.其参数为屏蔽码,需要清零的位为1.
__bis_SR_register
Void __bis_SR_register(unsigned short);
功能:将CPU中SR寄存器中得某些位置1.其参数为屏蔽码,需要置1的位为1.
__bis_SR_register_on_exit
Void __bis_SR_register_on_exit(unsigned short);
功能:用于一个中断函数或者不可中断函数(标志为__monitor)返回时,将CPU内SR寄存器中得某些位置1.其参数为屏蔽码,需要置1的位为1.
__disable_interrupt
Void __disable_interrupt(void);
功能:关闭全局中断。先执行DINT指令,关闭全局中断,然后再执行NOP指令。空指令是为了确保关闭了全局中断之后再执行下面的程序。
__enable_interrupt
Void __enable_interrupt(void);
功能:使用NINT指令打开全局中断。
__even_in_range
Unsigned short __even_in_range(unsigned shortvalue,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;
}
结果:假设iq0的值为2,执行完毕时MoonRiver=2.否则,与普通的switch语句一样,跳过case部分,直接执行下面的程序。使用__even_in_range的好处是可以生成效率比较高的代码,在判断多中断源时可以使用此函数。
__get_interrupt_state
Istate_t __get_interrupt_state(void);
功能:返回当前的中断状态。返回值istate_t为一结构,通过此函数可以将获得当前的中断状态并保存,将来可以使用__set_interrupt_state恢复中断状态。
__get_R4_register
Unsigned short __get_R4_register(void);
功能:返回寄存器R4的值,只在R4被锁定时有效。
__get_R5_register
Unsigned short __get_R5_register(void);
功能:返回寄存器R5的值,只在R5被锁定时有效。
__get_SP_register
Unsigned short __get_SP_register(void);
功能:返回堆栈指针寄存器SP的值。
__get_SR_register
Unsigned short __get_SR_register(void);
功能:返回CPU中状态寄存器SR的值。
__get_SR_register_on_exit
Unsigned short __get_SR_register_on_exit(void);
功能:用于一个中断函数或者不可中断函数(标志为__monitor)返回时,返回状态寄存器SR的值。只在中断函数或者不可中断函数中有效。
__low_power_mode_n
Void __low_power_mode_n(void);
功能:进入低功耗模式0~4.
__low_power_mode_off_on_exit
Void __low_power_mode_off_on_exit(void);
功能:从一个中断函数或者不可中断函数(标志为__monitor)返回时退出低功耗模式。只在中断或者不可中断函数中有效。
__no_operation
Void __no_operation(void);
功能:执行NOP指令。
__op_code
__op_code(unsigned short);
功能:在指令流中插入一个常数。
__segment_begin
Void *__segment_begin(segment);
功能:segment 是段的名字,必须是字符串。返回指向segment段的地址。此处的段是程序中定义的数据段、代码段、堆栈段等,一般用户可以使用编译器的默认设置。
__segment_end
Void *__segment_end(segment);
功能:segment是段的名字,必须是字符串。返回指向segment段结束后的第一个字节的地址。
__set_interrupt_state
Void __set_interrupt_state(istate_t);
功能:恢复istate_t中保存的中断状态。
__set_R4_register
Void __set_R4_register(unsigned short);
功能:将unsigned short值赋给寄存器R4,只在R4被锁定时有效。
__set_R5_register
Void __set_R5_register(unsigned short);
功能:将unsigned short 值赋给寄存器R5,只在R5被锁定时有效。
__set_SP_register
Void __set_SP_register(unsigned short);
功能:给堆栈指针寄存器SP赋值。
__swap_bytes
Unsigned short __swap_bytes(unsigned short);
功能:一个16位的无符号整数,高8位与低8位进行交换。如0x1234交换后0x3412.
2、有一些语法,虽然标准C中存在,但是我们不经常使用
struct GPADAT_BITS { // bits description
Uint16 GPIO0:1; // 0 GPIO0
Uint16 GPIO1:1; // 1 GPIO1
Uint16 GPIO2:1; // 2 GPIO2
Uint16 GPIO3:1; // 3 GPIO3
Uint16 GPIO4:1; // 4 GPIO4
Uint16 GPIO5:1; // 5 GPIO5
Uint16 GPIO6:1; // 6 GPIO6
Uint16 GPIO7:1; // 7 GPIO7
Uint16 GPIO8:1; // 8 GPIO8
Uint16 GPIO9:1; // 9 GPIO9
Uint16 GPIO10:1; // 10 GPIO10
Uint16 GPIO11:1; // 11 GPIO11
Uint16 GPIO12:1; // 12 GPIO12
Uint16 GPIO13:1; // 13 GPIO13
Uint16 GPIO14:1; // 14 GPIO14
Uint16 GPIO15:1; // 15 GPIO15
Uint16 GPIO16:1; // 16 GPIO16
Uint16 GPIO17:1; // 17 GPIO17
Uint16 GPIO18:1; // 18 GPIO18
Uint16 GPIO19:1; // 19 GPIO19
Uint16 GPIO20:1; // 20 GPIO20
Uint16 GPIO21:1; // 21 GPIO21
Uint16 GPIO22:1; // 22 GPIO22
Uint16 GPIO23:1; // 23 GPIO23
Uint16 GPIO24:1; // 24 GPIO24
Uint16 GPIO25:1; // 25 GPIO25
Uint16 GPIO26:1; // 26 GPIO26
Uint16 GPIO27:1; // 27 GPIO27
Uint16 GPIO28:1; // 28 GPIO28
Uint16 GPIO29:1; // 29 GPIO29
Uint16 GPIO30:1; // 30 GPIO30
Uint16 GPIO31:1; // 31 GPIO31
};