STM8学习笔记---寄存器操作之位或和位与运算

刚开始学习STM8单片机时,看别人的代码,在设置寄存器的时候经常使用,位或、位与、左移、右移等运算,就很不理解,为什么不直接给寄存器赋值,非要搞的这么复杂。直到后来程序写的多了,才明白这样写的好处。比如我们现在要设置PB5口为输出口。首先我们需要设置PB口的方向寄存器PB_DDR。
在这里插入图片描述
我们要设置PB5口为输出,那么就要把DDR5位设置为1。那么要设置的寄存器PB_DDR寄存器二进制数据为 0010 0000,转换为16进制为 0x20。设置寄存器的语句为

PB_DDR = 0x20;

这样操作寄存器看起来没什么问题,也挺方便。唯一的问题就是每次要先将设置的二进制数确定好,然后再转换为16进制数,再赋值给寄存器。代码少的时候没什么感觉,但是一旦代码量比较大,要设置的寄存器比较多时,再这样操作就比较麻烦,特别是设置的寄存器值要进行改变时再去计算二进制数,在转换成16进制数,就非常麻烦。而且还要不停的查阅参考手册,来确认寄存器的每一位值。一不小心很容易设置错,排除原因的时候又很难发现。
为了方便程序的编写和维护,这时候就需要用到移位运算。还是上面的例子,要设置PB5口为输出,需要将PB_DDR寄存器的第5位设置为1,其他位不变。那么将1左移5位,第五位不就刚好是1了吗。我们来看看移位操作,首先1的二进制数为
0000 0001
将这个数左移五位,最高位移出去,最低位补0,那么,向左移动5位后,变为
0010 0000
转换为16进制数为 0x20。于是对PB_DDR寄存器的设置语句可以改为:

 PB_DDR = 1<<5;

将1左移5位,然后赋值给PB_DDR寄存器。这样从代码上一眼就能看出来这是设置PB_DDR寄存器的DDR5为1。比上面的那种操作方式看起来简洁明了。
如果要继续设置PB4为输出的时候,寄存器的设置就可以写为:

		PB_DDR = 1<<4;

这样就将PB4口设置为了输出口。这时我们发现了一个问题,当将PB4设置为输出口时寄存器的值变为 0001 0000,DDR4为0,但是又将上一步设置的DDR5的值由1 变为0了,将PB4设置为输出后,又将PB5设置为了输入,改变了设计初衷。
那么如何解决这种问题呢,就需要用到位运算。先看看位或运算和位与运算的区别:
位或运算 |: 位之间进行或运算,如果有一个位为1,结果就为1。
位与运算&:位之间进行与运算,如果有一个位为0,结果就为0。
在设置PB4的时候不希望影响到PB5位,那么就可以用位或运算,给第4位或1,不管第4位以前的值是1还是0,与1进行或运算后,第4位的值就会变成1。那么在给PB_DDR赋值时,先进行或运算.

		PB_DDR = PB_DDR | 0x10;

同样为了方便程序书写和阅读,将16进制数改为位移运算。

	 	PB_DDR = PB_DDR | (1<<4);

为了书写简便,可以将上面的语句简写为:

		PB_DDR |= 1<<4;

这样在操作寄存器其中一位的时候,不会影响到其他位。这时如果设置PB4、PB5为输出,可以这样写:

		PB_DDR |= 1<<4;
  		PB_DDR |= 1<<5;

这样通过位移运算和位或运算的组合,可以很方便的设置寄存器值。 从语句上就能很清楚的看到是设置 PB_DDR寄存器的第4位和第5位为1。
如果这时候又需要将PB4口设置为输入模式,那么就需要将DDR4位由1变为0。位或运算只能将0变为1,不能将1变为0。而位与运算可以将1变为0,那么可以用位与运算实现。给PB_DDR寄存器的第4位位与0,就能将DDR4位由1变为0。
第4位为0,其他位为1二进制数为 1110 1111 转换为16进制数为0xEF。

      PB_DDR = PB_DDR & 0xEF;

这样在不影响其他位的情况下,将第4位变为了0。但是这样换算16进制也很麻烦,能不能同样用位移运算实现。但是位移运算是高位溢出后,低位自动补0。我们需要的是自动补1,那么有没有其他办法实现。我们观察设置第4位为0和第4位为1时的二进制数据
0001 0000
1110 1111
这两组数据刚好互补,那么将第4位为1其他位为0的数进行取反操作,那么得到的数刚好就是我们位与运算需要的数。
那么上面的设置语句可以改为

       PB_DDR = PB_DDR &( ~(1<<4));

将1左移4位后,先取反,让第4位变为0,其他位变为1,在和寄存器原先的值进行位与运算,那么就可以在不影响其他位的情况下,将第4位由1变为0。
上面的设置语句可以简写为:

	    PB_DDR &=   ~(1<<4);

通过增加一个取反运算,就可以实现用位移运算对寄存器某一位清0。
通过上面的分析可以得出一个结论 位或 | 运算可以实现将寄存器的某一位置1,而 位与& 运算可以实现将寄存器的某一位清0。通过这几种运算符的组合,设置寄存器时就会很方便快捷。
如要将PB4设置为输出,PB5设置为输入,那么运用上面的方法,可以很轻松的写出

 		PB_DDR |= 1<<4;
  		PB_DDR &= ~(1<<5);

这时候在看用以前对寄存器的操作方法,先设置对应的二进制数为 DDR4 为1 DDR5为0 0001 0000 转换为16进制数位 0x10 设置语句为

	    PB_DDR = 0x10;

明显可以发现直接设置寄存器操作起来麻烦,程序可读性很差。要修改寄存器的值时很费劲。
所以在以后代码编写中,推荐大家多用位或、位与、左移、右移、取反这些运算的组合方式进行寄存器设置。

发布了76 篇原创文章 · 获赞 30 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/qq_20222919/article/details/99426115