<meta name="keywords" content="必胜时时彩开户,keywords" /> 单片机位操作的逻辑运算详解 联系我们

单片机位操作的逻辑运算详解

从51单片机转到其他的芯片时,总会遇到一个异常疑惑的效果,就是其他芯片有的或许没有位操作。以是最年夜的效果就是经由历程逻辑操作来改变一个字节的某个位。因此在这里总结一下关于位操作的一些表达式。
首先,对一个字节,8位也好,16位也好,32位也好,只需两种操作,一种叫置位,一种叫清零。先从置位提及。
置位可以对一切位阻拦操作,也能够或许对某个位阻拦操作。

一切操作很俭梗直接赋值就ok了。我们假定一个无符号字符型uchar为8位。且最低位为0,也就是说0-7位,而不是1-8位,那么改变值的状态只须要直接即是就ok了

uchar a=0;
a=0xfe;

这样的话,就让a的低1-7职位1,a的0位稳固
但这样做有一个效果,我每次改变数值时,还要先掀开盘算器,然后设置到2进制功效,然后要把我要选择的位输入出来,好比100,然后按16进制功效。然后盘算器显示4。我以为这样很费事。咋办呢,效果先进们就想出了一个措施。经由历程位移的措施改变一个为,就酿成了这样

uchar a=0;
a = (1<<5);

这样做的话,就把a的第6位(重视是第6为不是第5位,由于数据最低位是0,而不是1,由于我总是弄混,以是也申饬年夜家,当心着方面的弱点,假定弄混,你的数据有能够掉落足)置1。那么a的值用2进制体现的话那就是00100000b,那么能够又会有人问,假定我想把第2和第3职位1怎样办呢?那么你可以这样

uchar a=0;
a = (3<<1);

这样做的意思是将二进制(11)位移到第二位的地方。那么第二位,是第一个1,第三位是第二个1。同理假定让第3位和低5位为1,第4位为0,怎样办。

uchar a=0;
a =  (5<<2);

这样便可以完成101位移到第3位了,以上,基本是置位的年夜概操作了,虽然这只是一次性的。也就是说,假定我欲望1次只操作一个位,好比当a=00000001b时,我欲望a的第二位也置1,且第一名依然保持1,怎样办呢?那也有措施,可以接纳与操作。例如:a为1,我欲望a的第2职位1,且第1位保持稳固,那么

uchar a=1;
a |= (1<<1);

这样便可以到达想要的效果了。然我们来看看,这是为甚么?
首先,a=1,酿成二进制时,a=00000001b
然后再看下面的谁人表达式
a |= (1<<1);
剖析一下,看过c语言相关书籍的人年夜概都知道这个一个含有复合的赋值运算符的表达式。这个式子可以拆成:
a=a|(1<<1);
这样就不难明得了,(1<<1)的意思是把1左移1位,那么效果就是10b,把这个效果在和a阻拦或操作,我们知道或操作是同为0效果才是0。

a          00000001
或操作  00000010
效果     00000011

以是这个公式便可使在不改变a=1的情形下,再使a的第2位酿成1,这样的效果就是a=3。这就是这个公式的年夜概原理。
不只这个,我还可以划分对两个不合的位阻拦操作。以是我可以这样:

uchar a=1;
a |= (1<<2)|(1<<3)|(1<<4)|(1<<5);

这样的话,便可以把第3、4、5、6位一切置1,而且保持a的第1位稳固,这个公式的事实效果是00111101b。 异常,这招,在一切置位也有用。但是a原来的值就消掉落了

uchar a=1;
a = (1<<2)|(1<<3)|(1<<4)|(1<<5);

那么效果只需4个1,00111100b,第1位的一就没有了
异常好比(3<<1)也能够或许涌现在单一置位当中

uchar a=1
a |= (3<<1);

这个表达式效果为00000111b。到这,置位操作,基本上就都在这了,年夜多数法式模范模范,这几个措施也够了,这也是破晓普遍的措施,或许尚有其他的措施,假定你知道,欲望能够告诉我。下面说说清0,清0可以用(&=~),举个例子:

uchar a=0xfe;
a &=~ (1<<4);

让我们来剖析一下这个式子,首先这和下面一样,是一个含有复合的赋值运算符的表达式。拆开来以后

a=a&(~(1<<4))

这个式子比适才要严重年夜一些,让我们先来看看括号最外面的(1<<4)
效果为10000b,然后我们把这个式子取反,由于a是8位的,以是效果被转换成11101111b,然后我们在把a和这个效果阻拦与运算。由于与运算的纪律是全1为1。

a            11111110b
与操作   11101111b
效果       11101110b

现在,我们清晰了这个效果时怎样来的了。
异常同时使两位酿成0也能够或许经由历程(3<<5)来完成,好比

uchar a=0xfe;
a &=~ (3<<4);

这样也是可以取得欲望的效果的,但是须要重视一下,(1<<2)|(1<<3)|(1<<4)|(1<<5),像这类一名一名的变则须要重视一下了。由于清零中先须要取反,以是假定欲望一名一名的变,则须要用括号,把效果扩起来,组成一个值,然后再取反,才干取得想要的效果了。好比

uchar a=0xfe;

/*
重视,这样做是纰谬的,效果只会把第二位清0,
a &=~ (1<<2)|(1<<3)|(1<<4)|(1<<5);
*/
a &=~ ((1<<2)|(1<<3)|(1<<4)|(1<<5));

这样做才干到达欲望的效果。
能够年夜家会想,用(&=)会取得啥样的效果呢?这我试了一下

uchar a=0xfe
a &= (1<<4);

首先(1<<4),效果是10000,然后再阻拦与操作

a      11111110b
与操作 00010000b
效果   00010000b

这个效果不是我们想要的,不外这个效果可以到达樊篱我们不要的位,好比在断定中,断定最高位能否为1,可以接纳这样的语句

if(a&0x80)

这句话,假定a的最高位为1,则为真,假定最高位不为1,则为假,假定位最高位为1的话,效果为10000000,在c语言中不为0,则为真,以是剖断某位能否为1时,可以接纳&操作。

以上就是质朴的总结了一下置位,清零的逻辑操作的措施。