1)PICC中的基本变量类型
PICC支持的基本变量类型见表1。PICC遵循Little-endian标准,多字节变量的低字节放在存储空间的低地址,高字节放在高地址。
表1:PICC支持的基本变量类型
2)PICC中的高级变量
基于表1的基本变量,除了bit型位变量外,PICC完全支持数组、结构和联合等复合型高级变量,这和标准的C语言所支持的高级变量类型没有什么区别。例如:
数组:unsignedintdata[10];
结构:structcommInData{
unsignedcharinBuff[8];
unsignedchargetPtr,putPtr;
};
联合:unionint_Byte{
unsignedcharc[2];
unsignedinti;
};
3)PICC中的局部变量
PICC把所有函数内部定义的auto型局部变量放在bank0。为节约宝贵的存储空间,它采用了一种被叫做“静态覆盖”的技术来实现局部变量的地址分配。其大致的原理是在编译器编译原代码时扫描整个程序中函数调用的嵌套关系和层次,算出每个函数中的局部变量字节数,然后为每个局部变量分配一个固定的地址,且按调用嵌套的层次关系各变量的地址可以相互重叠。利用这一技术后所有的动态局部变量都可以按已知的固定地址地进行直接寻址,用PIC汇编指令实现的效率最高,但这时不能出现函数递归调用。PICC在编译时会严格检查递归调用的问题并认为这是一个严重错误而立即终止编译过程。既然所有的局部变量将占用bank0的存储空间,因此用户自己定位在bank0内的变量字节数将受到一定的限制,在实际使用时需注意。
4)PICC中的位变量
bit型位变量只能是全局的或静态的。PICC将把定位在同一bank内的8个位变量合并成一个字节存放于一个固定地址。因此所有针对位变量的操作将直接使用PIC单片机的位操作汇编指令高效实现。基于此,位变量不能是局部自动型变量,也无法将其组合成复合型高级变量。
PICC对整个数据存储空间实行位编址,0x000单元的第0位是位地址0x0000,以此后推,每个字节有8个位地址。编制位地址的意义纯粹是为了编译器最后产生汇编级位操作指令而用,对编程人员来说基本可以不管。但若能了解位变量的位地址编址方式就可以在最后程序调试时方便地查找自己所定义的位变量,如果一个位变量flag1被编址为0x123,那么实际的存储空间位于:
字节地址=0x123/8 =0x24
位偏移=0x123%8=3
即flag1位变量位于地址为0x24字节的第3位。在程序调试时如果要观察flag1的变化,必须观察地址为0x24的字节而不是0x123。
PIC单片机的位操作指令是非常高效的。因此,PICC在编译原代码时只要有可能,对普通变量的操作也将以最简单的位操作指令来实现。假设一个字节变量tmp最后被定位在地址0x20,那么
tmp|=0x80 =>bsf 0x20,7
tmp&=0xf7 =>bcf 0x20,3
if(tmp&0xfe)=>btfsc0x20,0
即所有只对变量中某一位操作的C语句代码将被直接编译成汇编的位操作指令。虽然编程时可以不用太关心,但如果能了解编译器是如何工作的,那将有助于引导我们写出高效简介的C语言原程序。在有些应用中需要将一组位变量放在同一个字节中以便需要时一次性地进行读写,这一功能可以通过定义一个位域结构和一个字节变量的联合来实现,例如:
union{
struct{
unsignedb0:1;
unsignedb1:1;
unsignedb2:1;
unsignedb3:1;
unsignedb4:1;
unsignedb5:1;
unsigned:2;//最高两位保留
}oneBit;
unsignedcharallBits;
}myFlag;
需要存取其中某一位时可以
myFlag.oneBit.b3=1;//b3位置1
一次性将全部位清零时可以
myFlag.allBits=0;//全部位变量清0
当程序中把非位变量进行强制类型转换成位变量时,要注意编译器只对普通变量的最低位做判别:如果最低位是0,则转换成位变量0;如果最低位是1,则转换成位变量1。而标准的ANSI-C做法是判整个变量值是否为0。另外,函数可以返回一个位变量,实际上此返回的位变量将存放于单片机的进位位中带出返回。