单片机的C语言中位操作用法
单片机的C语言中位操作用法在对单处机进行编程的过程中,对位的操作是经常遇到的。
C51对位的操控能力是非常强大的。
从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点。
这也是在各个领域中都可以看到C的重要原因。
在这一节中将详细讲解C51中的位操作及其应用。
1、位运算符C51提供了几种位操作符,如下表所示:运算符含义运算符含义&按位与~取反|按位或<<左移^按位异或>>右移1)“按位与”运算符(&)参加运算的两个数据,按二进位进行“与”运算。
原则是全1为1,有0为0,即:0&0=0;0&1=0;1&0=0;1&1=1;如下例:a=5&3;//a=(0b0101)&(0b0011)=0b0001=1那么如果参加运算的两个数为负数,又该如何算呢?会以其补码形式表示的二进制数来进行与运算。
a=-5&-3;//a=(0b1011)&(0b1101)=0b1001=-7在实际的应用中与操作经常被用于实现特定的功能:1.清零“按位与”通常被用来使变量中的某一位清零。
如下例:a=0xfe;//a=0b11111110a=a&0x55;//使变量a的第1位、第3位、第5位、第7位清零a=0b010101002.检测位要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
a=0xf5;//a=0b11110101result=a&0x08;//检测a的第三位,result=03.保留变量的某一位要屏蔽某一个变量的其它位,而保留某些位,也可以使用与操作来实现。
a=0x55;//a=0b01010101a=a&0x0f;//将高四位清零,而保留低四位a=0x052)“按位或”运算符(|)参与或操作的两个位,只要有一个为‘1’,则结果为‘1’。
即有‘1’为‘1’,全‘0’为‘0’。
0|0=0;0|1=1;1|0=1;1|1=1;例如:a=0x30|0x0f;//a=(0b00110000)|(0b00001111)=(0b00111111)=0x3f“按位或”运算最普遍的应用就是对一个变量的某些位置‘1’。
如下例:a=0x00;//a=0b00000000a=a|0x7f;//将a的低7位置为1,a=0x7f3)“异或”运算符(^)异或运算符^又被称为XOR运算符。
当参与运算的两个位相同(‘1’与‘1’或‘0’与‘0’)时结果为‘0’。
不同时为‘1’。
即相同为0,不同为1。
0^0=0;0^1=1;1^0=1;1^1=0;例如:a=0x55^0x3f;//a=(0b01010101)^(0b00111111)=(0b01101010)=0x6a异或运算主要有以下几种应用:1.翻转某一位当一个位与‘1’作异或运算时结果就为此位翻转后的值。
如下例:a=0x35;//a=0b00110101a=a^0x0f;//a=0b00111010a的低四位翻转关于异或的这一作用,有一个典型的应用,即取浮点的相反数,具体的实现如下:f=1.23;//f为浮点型变量值为1.23f=f*-1;//f乘以-1,实现取其相反数,要进行一次乘运算f=1.23;((unsigned char*)&f)[0]^=0x80;//将浮点数f的符号位进行翻转实现取相反数2.保留原值当一个位与‘0’作异或运算时,结果就为此位的值。
如下例:a=0xff;//a=0b11111111a=a^0x0f;//a=0b11110000与0x0f作异或,高四位不变,低四位翻转3.交换两个变量的值,而不用临时变量要交换两个变量的值,传统的方法都需要一个临时变量。
实现如下:void swap(unsigned char*pa,unsigned char*pb){unsigned char temp=*pa;//定义临时变量,将pa指向的变量值赋给它*pa=*pb;*pb=temp;//变量值对调}而使用异或的方法来实现,就可以不用临时变量,如下:void swap_xor(unsigned char*pa,unsigned char*pb){*pa=*pa^*pb;*pb=*pa^*pb;*pa=*pa^*pb;//采用异或实现变量对调}从上例中可以看到异或运算在开发中是非常实用和神奇的。
4)“取反”运算符(~)与其它运算符不同,“取反”运算符为单目运算符,即它的操作数只有一个。
它的功能就是对操作数按位取反。
也就是是‘1’得‘0’,是‘0’得‘1’。
~1=0;~0=1;如下例:a=0xff;//a=0b11111111a=~a;//a=0b000000001.对小于0的有符号整型变量取相反数d=-1;//d为有符号整型变量,赋值为-1,内存表示为0b 1111111111111111d=~d+1;//取d的相反数,d=1,内存表示0b0000000000000001此例运用了负整型数在内存以补码方式来存储的这一原理来实现的。
负数的补码方式是这样的:负数的绝对值的内存表示取反加1,就为此负数的内存表示。
如-23如果为八位有符号整型数,则其绝对值23的内存表示为0b00010111,对其取反则为0b11101000,再加1为0b11101001,即为0XE9,与Keil仿真结果是相吻合的:2.增强可移植性关于“增强可移植性”用以下实例来讲解:假如在一种单片机中unsigned char类型是八个位(1个字节),那么一个此类型的变量a=0x67,对其最低位清零。
则可以用以下方法:a=0x67;//a=0b01100111a=a&0xfe;//a=0b01100110上面的程序似乎没有什么问题,使用0xfe这一因子就可以实现一个unsigned char 型的变量最低位清零。
但如果在另一种单片机中的unsignedchar类型被定义为16个位(两个字节),那么这种方法就会出错,如下:b=0x6767;//假设b为另一种单片机中的unsigned char类型变量,值为0b0110011101100111b=b&0xfe;//如果此时因子仍为0xfe的话,则结果就为0b0000000001100110即0x0066,而与0x6766不相吻合上例中的问题就是因为不同环境中的数据类型差异所造成的,即程序的可移植性不好。
对于这种情况可以采用如下方法来解决:a=0x67;//a=0b01100111a=a&~1;//在不同的环境中~1将自动匹配运算因子,实现最后一位清零a=0x66其中~1为0b11111110b=0x6767;//a=0b0110011101100111b=a&~1;//~1=0b1111111111111110,b=0b0110011101100110,即0x67665)左移运算符(<<)左移运算符用来将一个数的各位全部向左移若干位。
如:a=a<<2表示将a的各位左移2位,右边补0。
如果a=34(0x22或0b00100010),左移2位得0b10001000,即十进制的136。
高位在左移后溢出,不起作用。
从上例可以看到,a被左移2位后,由34变为了136,是原来的4倍。
而如果左移1位,就为0b01000100,即十进制的68,是原来的2倍,很显然,左移N位,就等于乘以了2N。
但一结论只适用于左移时被溢出的高位中不包含‘1’的情况。
比如:a=64;//a=0b01000000a=a<<2;//a=0b00000000其实可以这样来想,a为unsigned char型变量,值为64,左移2位后等于乘以了4,即64X4=256,而此种类型的变量在表达256时,就成为了0x00,产生了一个进位,即溢出了一个‘1’。
在作乘以2N这种操作时,如果使用左移,将比用乘法快得多。
因此在程序中适应的使用左移,可以提高程序的运行效率。
6)右移运算符右移与左移相类似,只是位移的方向不同。
如:a=a>>1表示将a的各位向右移动1位。
与左移相对应的,左移一位就相当于除以2,右移N位,就相当于除以2N。
在右移的过程中,要注意的一个地方就是符号位问题。
对于无符号数右移时左边高位移和‘0’。
对于有符号数来说,如果原来符号位为‘0’,则左边高位为移入‘0’,而如果符号位为‘1’,则左边移入‘0’还是‘1’就要看实际的编译器了,移入‘0’的称为“逻辑右移”,移入‘1’的称为“算术右移”。
Keil中采用“算术右移”的方式来进行编译。
如下:d=-32;//d为有符号整型变量,值为-32,内存表示为0b11100000d=d>>1;//右移一位d为0b11110000即-16,Keil采用"算术逻辑"进行编译7)位运算赋值运算符在对一个变量进行了位操作中,要将其结果再赋给该变量,就可以使用位运算赋值运算符。
位运算赋值运算符如下:&=,|=,^=,~=,<<=,>>=例如:a&=b相当于a=a&b,a>>=2相当于a>>=2。
8)不同长度的数据进行位运算如果参与运算的两个数据的长度不同时,如a为char型,b为int型,则编译器会将二者按右端补齐。
如果a为正数,则会在左边补满‘0’。
若a为负数,左边补满‘1’。
如果a为无符号整型,则左边会添满‘0’。
a=0x00;//a=0b00000000d=0xffff;//d=0b1111111111111111d&=a;//a为无符号型,左边添0,补齐为0b0000000000000000,d=0b0000000000000000。
c语言的位操作
c语⾔的位操作c语⾔的位操作最常⽤的地⽅就是⽤在对寄存器的写值上。
⼀.基本的⼀些概念 1.位与:&操作:1 & 1 = 1; 1 & 0 = 0; 0 & 0 = 0;特点:只有全是1的时候才是1,其他情况都是0.总结:任何数和0位与就是0,和1位与没有变化,所以位与常⽤在清零上(清零⽤位与)。
2.位或:|操作:1 | 1 = 1; 1 | 0 = 1; 0 | 0 = 0;特点:只有全0的时候才是0,其他情况都是1.总结:任何数和1位或就是1,和0位或没有变化,所以位或常⽤在置1上(置1⽤位或)。
3.位取反:~操作:~1 = 0; ~0 = 1;特点:1取反为0,0取反为1. 4.位异或:^操作:1 ^ 1 = 0; 1 ^ 0 = 1; 0 ^ 1 = 1; 0 ^ 0 = 0;特点:相同为0,不同为1.总结:任何数和1位异或会取反,和0异或没有变化(特定位要取反就⽤位异或)。
5.左移(<<)和右移(>>)操作的时候要考虑有符号数(signed number)和⽆符号数(unsigned number)。
对于有符号数:左移的时候右侧补0;右移的时候左侧补符号位(正数符号位为0,则补0;负数符号位为1,则补1).对于⽆符号数:左移的时候右侧补0;右移的时候左侧也是补0.注意:我们对寄存器进⾏赋值的时候⽤的都是⽆符号的数⼆.与逻辑运算的区别 1.逻辑运算的基本符号:逻辑与(&&) 逻辑或(||) 逻辑取反(!) 2.我们需要注意的地⽅就是:位操作中只有1和0;逻辑操作的中⾮0代表是真(1),0就代表是假(0) 3.运算的时候,位运算是把数字拆为⼀位⼀位的进⾏运算的;逻辑运算是把数字作为⼀个整体进⾏运算的,但是他们运算的基本操作和位运算⼀致(譬如:1 && 1 = 1, 0 && 1 = 0 等等)。
单片机 C语言开发 sbit使用方法
单片机C语音开发sbit使用方法··1.bit和sbit都是C51扩展的变量类型。
bit和int char之类的差不多,只不过char=8位, bit=1位而已。
都是变量,编译器在编译过程中分配地址。
除非你指定,否则这个地址是随机的。
这个地址是整个可寻址空间,RAM+FLASH+扩展空间。
bit只有0和1两种值,意义有点像Windows下VC中的BOOL。
sbit是对应可位寻址空间的一个位,可位寻址区:20H~2FH。
一旦用了sbi xxx = REGE^6这样的定义,这个sbit量就确定地址了。
sbit大部分是用在寄存器中的,方便对寄存器的某位进行操作的。
2.bit位标量bit位标量是C51编译器的一种扩充数据类型,利用它可定义一个位标量,但不能定义位指针,也不能定义位数组。
它的值是一个二进制位,不是0就是1,类似一些高级语言中的Boolean类型中的True和False。
3.sfr特殊功能寄存器sfr也是一种扩充数据类型,点用一个内存单元,值域为0~255。
利用它可以访问51单片机内部的所有特殊功能寄存器。
如用sfr P1 = 0x90这一句定P1为P1端口在片内的寄存器,在后面的语句中我们用以用P1 = 255(对P1端口的所有引脚置高电平)之类的语句来操作特殊功能寄存器。
sfr P1 = 0x90; //定义P1 I/O 口,其地址90Hsfr 关键定后面是一个要定义的名字,可任意选取,但要符合标识符的命名规则,名字最好有一定的含义如P1 口可以用P1 为名,这样程序会变的好读好多.等号后面必须是常数,不允许有带运算符的表达式,而且该常数必须在特殊功能寄存器的地址范围之内(80H-FFH),具体可查看附录中的相关表.sfr 是定义8 位的特殊功能寄存器而sfr16 则是用来定义16 位特殊功能寄存器,如8052 的T2 定时器,可以定义为:sfr16 T2 = 0xCC; //这里定义8052 定时器2,地址为T2L=CCH,T2H=CDH用sfr16 定义16 位特殊功能寄存器时,等号后面是它的低位地址,高位地址一定要位于物理低位地址之上.注意的是不能用于定时器0 和1 的定义.sbit 可定义可位寻址对象.如访问特殊功能寄存器中的某位.其实这样应用是经常要用的如要访问P1 口中的第2 个引脚P1.1.我们可以照以下的方法去定义:(1) sbit 位变量名=位地址sbit P1_1 = Ox91;这样是把位的绝对地址赋给位变量.同sfr 一样sbit 的位地址必须位于80H-FFH 之间. (2) sbit 位变量名=特殊功能寄存器名^位位置sft P1 = 0x90;sbit P1_1 = P1 ^ 1; //先定义一个特殊功能寄存器名再指定位变量名所在的位置,当可寻址位位于特殊功能寄存器中时可采用这种方法(3) sbit 位变量名=字节地址^位位置sbit P1_1 = 0x90 ^ 1;这种方法其实和2 是一样的,只是把特殊功能寄存器的位址直接用常数表示. 在C51存储器类型中提供有一个bdata 的存储器类型,这个是指可位寻址的数据存储器,位于单片机的可位寻址区中,可以将要求可位录址的数据定义为bdata,如:unsigned char bdata ib; //在可位录址区定义ucsigned char 类型的变量ibint bdata ab[2]; //在可位寻址区定义数组ab[2],这些也称为可寻址位对象sbit ib7=ib^7 //用关键字sbit 定义位变量来独立访问可寻址位对象的其中一位sbit ab12=ab[1]^12;操作符"^"后面的位位置的最大值取决于指定的基址类型,char0-7,int0-15,long0-31.sfr 并标准C 语言的关键字,而是Keil 为能直接访问80C51 中的SFR 而提供了一个新的关键词,其用法是:sfrt 变量名=地址值。
51单片机位操作
C51单片机位操作方法[日期:2010-10-21 ] [来源:本站原创作者:佚名] [字体:大中小] (投递新闻)C51对位的操控能力是非常强大的。
从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点。
这也是在各个领域中都可以看到C的重要原因。
在这一节中将详细讲解C51中的位操作及其应用。
1、位运算符C51提供了几种位操作符,如下表所示:运算符含义运算符含义&按位与~取反|按位或<<左移^按位异或>>右移1)“按位与”运算符(&)参加运算的两个数据,按二进位进行“与”运算。
原则是全1为1,有0为0,即:0&0=0; 0&1=0; 1&0=0; 1&1=1;如下例:a=5&3; //a=(0b 0101) & (0b 0011) =0b 0001 =1那么如果参加运算的两个数为负数,又该如何算呢?会以其补码形式表示的二进制数来进行与运算。
a=-5&-3; //a=(0b 1011) & (0b1101) =0b 1001 =-7在实际的应用中与操作经常被用于实现特定的功能:1.清零“按位与”通常被用来使变量中的某一位清零。
如下例:a=0xfe; //a=0b 11111110a=a&0x55;//使变量a的第1位、第3位、第5位、第7位清零a= 0b 01010100 2.检测位要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
a=0xf5; //a=0b 11110101result=a&0x08; //检测a的第三位,result=03.保留变量的某一位要屏蔽某一个变量的其它位,而保留某些位,也可以使用与操作来实现。
a=0x55; //a=0b 01010101a=a&0x0f; //将高四位清零,而保留低四位a=0x052)“按位或”运算符(|)参与或操作的两个位,只要有一个为‘1’,则结果为‘1’。
C51中的位操作
b=b&0xfe; //如果此时因子仍为 0xfe 的话,则结果就为 0b 0000 0000 0110 0110 即 0x0066,而与 0x6766 不相吻合
上例中的问题就是因为不同环境中的数据类型差异所造成的,即程序
的可移植性不好。对于这种情况可以采用如下方法来解决: a=0x67; //a=0b 0110 0111 a=a&~1; //在不同的环境中~1 将自动匹配运算因子,实现最后一位清零 a=0x66 其中~1 为 0b 11111110 b=0x6767; //a=0b 0110 0111 0110 0111 b=a&~1; //~1=0b 1111 1111 1111 1110,b=0b 0110 0111 0110 0110 ,即 0x6766
1.清零 “按位与”通常被用来使变量中的某一位清零。如下例:
a=0xfe; //a=0b 11111110
a=a&0x55; //使变量 a 的第 1 位、第 3 位、第 5 位、第 7 位清零 a= 0b 01010100 2.检测位 要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
51单片机位操作
C51单片机位操作方法C51对位的操控能力是非常强大的。
从这一点上,就可以看出C不光具有高级语言的灵活性,又有低级语言贴近硬件的特点。
这也是在各个领域中都可以看到C的重要原因。
在这一节中将详细讲解C51中的位操作及其应用。
1、位运算符C51提供了几种位操作符,如下表所示:1)“按位与”运算符(&)参加运算的两个数据,按二进位进行“与”运算。
原则是全1为1,有0为0,即:0&0=0; 0&1=0; 1&0=0; 1&1=1;如下例:a=5&3; //a=(0b 0101) & (0b 0011) =0b 0001 =1那么如果参加运算的两个数为负数,又该如何算呢?会以其补码形式表示的二进制数来进行与运算。
a=-5&-3; //a=(0b 1011) & (0b1101) =0b 1001 =-7在实际的应用中与操作经常被用于实现特定的功能:1.清零“按位与”通常被用来使变量中的某一位清零。
如下例:a=0xfe; //a=0ba=a&0x55;//使变量a的第1位、第3位、第5位、第7位清零a= 0b2.检测位要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。
a=0xf5; //a=0bresult=a&0x08; //检测a的第三位,result=03.保留变量的某一位要屏蔽某一个变量的其它位,而保留某些位,也可以使用与操作来实现。
a=0x55; //a=0ba=a&0x0f; //将高四位清零,而保留低四位a=0x052)“按位或”运算符(|)参与或操作的两个位,只要有一个为‘1’,则结果为‘1’。
即有‘1’为‘1’,全‘0’为‘0’。
0|0=0; 0|1=1; 1|0=1; 1|1=1;例如:a=0x30|0x0f; //a=(0b)|(0b)=(0b)=0x3f“按位或”运算最普遍的应用就是对一个变量的某些位置‘1’。
单片机c语言的结构体实现字节、位操作
单片机c语言的结构体实现字节、位操作结构体是C语言中一种数据类型,它可以包含不同类型的数据成员。
结构体可以通过位操作和字节操作来进行操作。
1. 字节操作:字节操作主要是针对结构体中的整型数据成员。
可以使用位与(&)和位或()操作来读取或设置结构体中某个字节的值。
示例代码:c#include <stdio.h>定义一个结构体typedef struct {unsigned char byte1;unsigned char byte2;unsigned char byte3;unsigned char byte4;} MyStruct;int main() {MyStruct myStruct;读取第二个字节的值unsigned char secondByte = myStruct.byte2;printf("Second byte: %d\n", secondByte);设置第三个字节的值为10myStruct.byte3 = 10;return 0;}2. 位操作:位操作主要是针对结构体中的位字段数据成员。
可以使用位操作符(<<,>>,&,)来对位字段进行读取和设置。
示例代码:c#include <stdio.h>定义一个结构体typedef struct {unsigned char flag1 : 1;unsigned char flag2 : 1;unsigned char flag3 : 1;unsigned char flag4 : 1;} MyStruct;int main() {MyStruct myStruct;设置第一个位字段为1myStruct.flag1 = 1;读取第二个位字段的值unsigned char secondFlag = myStruct.flag2;printf("Second flag: %d\n", secondFlag);return 0;}通过结构体的字节操作和位操作,可以对结构体中的字节和位字段进行精确的操作。
C语言对寄存器的位操作
C语言对寄存器的位操作在C语言中,寄存器通常定义为一个特定地址的指针变量,例如:```c```其中,`volatile`关键字的作用是告诉编译器,该寄存器的值可能会发生变化,避免编译器对寄存器的优化,确保每次访问都从设备读取最新的值。
读取寄存器位的值:C语言提供了位操作运算符来读取寄存器位的值,如下所示:```cunsigned int reg_value = *reg_address; // 读取整个寄存器的值unsigned int bit_value = (*reg_address >> bit_number) & 0x1; // 读取特定位的值```其中,`>>`运算符用于将寄存器的值向右移动`bit_number`位,取出目标位的值,然后使用`&`运算符与`0x1`相与,将除目标位外的其它位清零,以获取目标位的值。
修改寄存器位的值:C语言提供了位操作运算符来修改寄存器位的值,如下所示:```c*reg_address ,= (0x1 << bit_number); // 将特定位设置为1*reg_address &= ~(0x1 << bit_number); // 将特定位设置为0```其中,`,=`运算符用于将特定位设置为1,先将`0x1`左移`bit_number`位,然后与寄存器值进行或运算,实现特定位的设置。
`&=`运算符用于将特定位设置为0,先将`0x1`左移`bit_number`位,然后取反得到`~(0x1 << bit_number)`,与寄存器值进行与运算,实现特定位的清零。
设置寄存器位的值:C语言提供了位操作运算符来设置寄存器位的值,如下所示:```c*reg_address = (*reg_address & ~(0x1 << bit_number)) ,(value << bit_number); // 设置特定位的值```其中,`&`运算符和`,`运算符类似于前面的用法,用于将目标位清零和设置为特定值。
单片机c语音自定义标志位用法bit
单片机C语言编程中“位”(bit)的保存方案引言在现有的教课书及相关文章中,都难得提到在单片机C语言编程中对于自定义“位”的状态进行保存的理念。
当单片机C语言编程中提及“位”的概念时,人们自然会想到状态字PSW 中PSW.5的F0与PSW.1的F1两个用户通用标志位。
这两个标志位均可参与布尔运算、“位”控操作,也可随状态字PSW一起保存。
但是,往往会忽视这一点:在一些特定的情况下,如在C语言编程的中断服务程序中,对状态字PSW中PSW.5的F0与PSW.1的F1这两个用户标志位的操作可能是无效的。
如:void EX1_ISR() interrupt 2 {//外部中断1static unsigned int tempaddr;//定义接收地址缓存static unsigned int tempkey;//定义接收数据缓存unsigned int timecnt;timecnt=TH1*256+TL1;TH1=0;TL1=0;TR1=1;//定时器1启动F0=~F0;//取反F0if(F0) {tempaddr=tempaddr<<1;}else {tempkey=tempkey<<1;}}以上是一段单片机外部中断1的中断服务程序,乍看似乎没什么问题,仿真调试时也能通过“编辑”。
但实际上这是一段错误的程序——其中对“F0”用户标志位的“取反”操作是达不到其预期效果的。
因为对“F0”用户标志位的“取反”操作是在中断服务程序中进行的。
在进入中断时,C语言自动会保护“中断现场”——将程序指针PC、累加器ACC、状态字PSW等压入堆栈保护起来……直到中断返回时弹出堆栈并覆盖了中断服务时的变值,恢复到压入堆栈之前的原样。
因此,状态字PSW中的F0也不例外,如果压入堆栈之前F0是处于逻辑“0”状态,中断返回后还是复原成逻辑“0”状态——不管中断服务程序中怎么取反改变——也就是说,在中断服务程序中试图改变F0之值的操作是有失偏颇的。
mcs51单片机位操作指令及编程举例
mcs51单片机位操作指令及编程举例MCS-51 单片机的硬件结构中,有一个位处理器(又称布尔处理器),它有一套位变量处理的指令集。
在进行位处理时,CY(就是我们前面讲的进位位)称位累加器。
有自已的位RAM,也就是我们刚讲的内部RAM 的20H-2FH 这16 个字节单元即128 个位单元,还有自已的位I/O 空间(即P0.0..P0.7,P1.0.P1.7,P2.0..P2.7,P3.0..P3.7)。
当然在物理实体上它们与原来的以字节寻址用的RAM,及端口是完全相同的,或者说这些RAM 及端口都能有两种使用办法。
(1)位传送指令MOV C,BITMOV BIT,C 这组指令的功能是实现位累加器(CY)和其它位地址之间的数据传递。
例:MOV P1.0,CY ;将CY中的状态送到P1.0 管脚上去(如果是做算术运算,我们就能通过观察知道现在CY 是多少啦)。
MOV P1.0,CY ;将P1.0 的状态送给CY。
(2)位修正指令位清0 指令CLR C ;使CY=0CLR bit ;使指令的位地址等于0。
例:CLR P1.0 ;即使P1.0 变为0 位置1 指令SETB C ;使CY=1SETB bit ;使指定的位地址等于1。
例:SETB P1.0 ;使P.0 变为1 位取反指令CPL C ;使CY 等于原来的相反的值,由1 变为0,由0 变为1。
CPL bit ;使指定的位的值等于原来相反的值,由0 变为1,由1 变为0。
例:CPL P1.0 以我们做过的实验为例,如果原来灯是亮的,则执行本指令后灯灭,反之原来灯是灭的,执行本指令后灯亮。
(3)位逻辑运算指令位与指令ANL C,bit ;CY 与指定的位地址的值相与,结果送回CYANL C,/bit ;先将指定的位地址中的值取出后取反,再和CY 相与,结果送回CY,但注意,指定的位地址中的值本身并不发生变化。
例:ANL C,/P1.0 设执行本指令前,CY=1,P1.0 等于1(灯灭),则执行完本指令后CY=0,而P1.0 也是等于1。
单片机指令的位操作与位运算技巧
单片机指令的位操作与位运算技巧在单片机编程中,位操作和位运算是一项重要的技术,它能够实现对某个特定位的操作和对位数的运算。
本文将介绍一些常用的位操作和位运算技巧,帮助读者更好地掌握这一技术。
一、位操作技巧1. 位设置(置1)要将某个特定位设置为1,可以使用按位或(|)运算符将该位设置为1,其余位不变。
例如,要将PORTA的第0位设置为1,可以使用以下方式:PORTA |= (1<<0);2. 位清除(置0)要将某个特定位设置为0,可以使用按位与(&)运算符将该位设置为0,其余位不变。
例如,要将PORTB的第3位设置为0,可以使用以下方式:PORTB &= ~(1<<3);3. 位取反要将某个特定位取反,可以使用按位异或(^)运算符,将该位取反。
例如,要将PORTC的第5位取反,可以使用以下方式: PORTC ^= (1<<5);4. 位读取要读取某个特定位的值,可以使用按位与(&)运算符将其他位屏蔽,只保留需要的位。
例如,要读取PIND的第2位的值,可以使用以下方式:uint8_t value = PIND & (1<<2);二、位运算技巧1. 位与运算位与运算可以用来屏蔽某些位,只保留需要的位。
例如,要屏蔽一个字节的高4位,可以使用以下方式:uint8_t value = 0xAB;value &= 0x0F;2. 位或运算位或运算可以将某些位设置为1,其余位不变。
例如,要将一个字节的低4位设置为1,可以使用以下方式:uint8_t value = 0x12;value |= 0x0F;3. 位异或运算位异或运算可以实现位的翻转。
例如,要将一个字节的高4位和低4位互换,可以使用以下方式:uint8_t value = 0x34;value ^= 0xF0;4. 位移运算位移运算可以实现对位的平移操作。
左移运算(<<)将位向左移动,右移运算(>>)将位向右移动,并可以通过设置补齐位来控制移动后的数值。
