原创 PIC单片机C语言编程中的位操作

2014-2-18 21:49 3024 20 20 分类: MCU/ 嵌入式
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调试观察
 
#include<pic.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的共用体来表示
 
#include<pic.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){;}
}
 
五、用指针转换来表示
 
#include<pic.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){;}
}
 
六:五的方法还是烦琐,可以用粘贴符号的形式来简化它.
 
#include<pic.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%的达到汇编的程度的.另一个优势是可读性高,代码灵活.上面的几个位操作方法任由你选,你不必担心会产生多余的代码量出来.

文章评论0条评论)

登录后参与讨论
我要评论
0
20
关闭 站长推荐上一条 /2 下一条