热度 20
2014-2-18 21:49
3026 次阅读|
0 个评论
PIC的位操作是NO1,在汇编中是没问题的,但如何在C语言中可以随心所欲的位操作是今天我们要聊的话题. 一、用位操作来做一些标志位,也就是BOOL变量 可以简单如下定义: bit a,b,c; PICC会自动安排一个内存,并在此内存中自动安排一位来对应a,b,c.由于我们只是用它们来简单的表示一些0,1信息,所以我们不需要详细的知道它们的地址\位究竟是多少,只管拿来就用好了. 二、要是需要用一个地址固定的变量来位操作,可以参照PIC.H里面定义寄存器 如:用25H内存来定义8个位变量. static volatile unsigned char myvar @ 0x25; static volatile bit b7 @ (unsigned)myvar*8+7; static volatile bit b6 @ (unsigned)myvar*8+6; static volatile bit b5 @ (unsigned)myvar*8+5; static volatile bit b4 @ (unsigned)myvar*8+4; static volatile bit b3 @ (unsigned)myvar*8+3; static volatile bit b2 @ (unsigned)myvar*8+2; static volatile bit b1 @ (unsigned)myvar*8+1; static volatile bit b0 @ (unsigned)myvar*8+0; 这样即可以对MYVAR操作,也可以对B0--B7直接位操作. 但不好的是,此招在低档片子,如C5X系列上可能会出问题. 还有就是表达起来复杂,你不觉得输入代码受累么?呵呵 三、这也是一些常用手法 #define testbit(var, bit) ((var) (1 (bit))) //测试某一位,可以做BOOL运算 #define setbit(var, bit) ((var) |= (1 (bit))) //把某一位置1 #define clrbit(var, bit) ((var) = ~(1 (bit))) //把某一位清0 付上一段代码,可以用MPLAB调试观察 #includepic.h #define testbit(var, bit) ((var) (1 (bit))) #define setbit(var, bit) ((var) |= (1 (bit))) #define clrbit(var, bit) ((var) = ~(1 (bit))) char a,b; void main(){ char myvar; myvar=0B10101010; a=testbit(myvar,0); setbit(myvar,0); a=testbit(myvar,0); clrbit(myvar,5); b=testbit(myvar,5); if(!testbit(myvar,3)) a=255; else a=100; while(1){;} } 四、用标准C的共用体来表示 #includepic.h union var{ unsigned char byte; struct { unsigned b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } bits; }; char a,b; void main(){ static union var myvar; myvar.byte=0B10101010; a=myvar.bits.b0; b=myvar.bits.b1; if(myvar.bits.b7) a=255; else a=100; while(1){;} } 五、用指针转换来表示 #includepic.h typedef struct { unsigned b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } bits; //先定义一个变量的位 #define mybit0 (((bits *)myvar)-b0) //取myvar的地址(myvar)强制转换成bits类型的指针 #define mybit1 (((bits *)myvar)-b1) #define mybit2 (((bits *)myvar)-b2) #define mybit3 (((bits *)myvar)-b3) #define mybit4 (((bits *)myvar)-b4) #define mybit5 (((bits *)myvar)-b5) #define mybit6 (((bits *)myvar)-b6) #define mybit7 (((bits *)myvar)-b7) char myvar; char a,b; void main(){ myvar=0B10101010; a=mybit0; b=mybit1; if(mybit7) a=255; else a=100; while(1){;} } 六:五的方法还是烦琐,可以用粘贴符号的形式来简化它. #includepic.h typedef struct { unsigned b0:1, b1:1, b2:1, b3:1, b4:1, b5:1, b6:1, b7:1; } bits; #define _paste(a,b) a##b #define bitof(var,num) (((bits *)(var))-_paste(b,num)) char myvar; char a,b; void main(){ a=bitof(myvar,0); b=bitof(myvar,1); if(bitof(myvar,7)) a=255; else a=100; while(1){;} } 有必要说说#define _paste(a,b) a##b 的意思: 此语句是粘贴符号的意思,表示把b符号粘贴到a符号之后. 例子中是: a=bitof(myvar,0);--->(((bits *)(myvar))-_paste(b,0))--->(((bits *)(var))-b0) 可以看出来,_paste(b,0)的作用是把0粘贴到了b后面,成了b0符号. 总结:C语言的优势是能直接对低层硬件操作,代码可以非常非常接近汇编,上面几个例子的位操作代码是100%的达到汇编的程度的.另一个优势是可读性高,代码灵活.上面的几个位操作方法任由你选,你不必担心会产生多余的代码量出来.