位操作的宏函数实现

不像51,对位操作的实现是相当的简单的。P1.0 = 0;即可实现对该为的赋值操作了。但是现在的许多的MCU并不直接支持位操作,有时候具体实现起来有点麻烦甚至会变得很糊涂。特别对于刚从51系列出来的学生而言,16位或者32位的MCU的一些位操作就会显得很是糊涂,鄙人当初用凌阳的61单片机就是的。

 近日在一本书看到了比较好的解释,书名不给出了,特别给出自己的理解,也是为了做备忘。

 首先要理解几种基本的操作符的使用,eg : <<, >>,  | , & , ~ ;即左移,右移,或,与,取反

以8位的MCU为例,寄存器一般为8位的,要保证在置位和清零的时候不会影响到其他的位。比如要操作的寄存器或者变量为Reg;

  1. 置位 : 要将Reg的第n位(n<8)置一,其他位保持不变,可以写成Reg |= (1<<n);

    eg :  n = 5时, 1 << n 的结果为  0b00100000; 此时Reg = Reg | 0b00100000 就可以将Reg的第五位置一

  2. 清零 : 要将Reg的第n位(n<8)清零,其他位保持不变,可以写成Reg &= ~(1<<n);

    eg :  n = 5时, 1 << n 的结果为0b00100000; 此时Reg = Reg & 0b11011111 就可以将Reg的第五位清零

  3 取值  :   要取得Reg的第n位(n<8)的值,可以写成 Reg_tmp = (Reg >> n) & 1 ;

   右移n位后即可将Reg的第n位移动到LSB上,再和1相与,即可保留LSB位上的数值

为了方便使用,可以封装成宏函数的形式进行定义,方便调用使用:

   #define BitSet(Bit,Register)  ((Register) |= (1 << (Bit)))  // set register

   #define BitClr(Bit,Register)   ((Register) &= ~(1 << (Bit))) //clear

   #define BitGet(Bit,Register)  (((Register) >>(Bit)) & 1)      // get the bit of register

此时就可以使用BitSet , BitClr, BitGet进行位操作

 当要对GPIO进行配置的时候,可以进行相应的操作即可 :

   BitSet(3,GPIO_PDDR); // set the direction of the GPIO // output

   BitSet(3,GPIO_PDOR); // set the value of the GPIO

这个世界不会怜悯那些被屠宰者,而会尊敬那些一直在战斗着的人们
原文地址:https://www.cnblogs.com/zxqwolf/p/3040111.html