热度 19
2017-8-9 14:32
1568 次阅读|
0 个评论
今天跟着视频学习了位运算,感觉很有用,这里分享给大家。 位运算 位运算主要有:位与运算符()、按位或运算符(|)、异或运算符(^)、取反运算符(~)、左移运算符()、右移运算符()等,下面我们分别介绍这几个位运算的用法及其在程序中的运用。 (1)位与() 按位与运算符“”是双目运算符。其功能是参与运算的两数各对应的二进位相与。两个数相“与”时,如果两个位同时为1,则结果为1,否则为0,即:11=1,10=0,01=0,00=0。 比如:0xc30x11计算如下 在STM32编程中位与()运算可以作为条件判断之用,请看下面的程序: uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin),这是STM32库中的函数,用来读取输出的某个引脚的电平,运行一下”Go To Definition”,你会发现下面的语句: if ((GPIOx-ODR GPIO_Pin) != (uint32_t)Bit_RESET),当然对应的GPIOx-ODR是输出数据寄存器的值,是16位的数值;GPIO_Pin也是STM32库定义的16位类型的数据。 (2)位或(|) 按位或运算符“|”是双目运算符。其功能是参与运算的两数各对应的二进位相或。只要对应的两个二进位有一个为1时,结果位就为1,即:1|1=1,1|0=1,0|1=1,0|0=0。 比如:0xc3|0x10 在STM32编程中位或运算(|),可以作为置位之用,因为位或运算不会改变影响原来数值的其它位,上面的0xc3|0x10,原来的0xc3(b11000011),只有一个位发生了改变。请看下面的程序: GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1;这是常见的对两个引脚按位或,在STM32库中,GPIO_Pin_0和GPIO_Pin_1其实也是两个整数,请看它们的宏定义: #define GPIO_Pin_0 ((uint16_t)0x0001) #define GPIO_Pin_1 ((uint16_t)0x0002) (3)异或(^) 两个二进制数进行异或,若对应的位不相同,则结果为1,否则为0,即:0^0=0,0^1=1,1^0=1,1^1=0; 比如(0xc3 ^ 0x10) ^ 0x10 从上面的式子中大家发现了什么,对,0xc3与0x10第一次异或,发生一次改变,且只改变了与0x10相关的位,并且如果与同一个数两次异或,它就恢复到初始值,所以异或(^)具有翻转的功能,在程序中可以当做开关使用,比如,让一个LED灯点亮和熄灭就可以用这种方法: GPIOA-ORD ^= GPIO_Pin_1; //LED1灯熄灭 Delay_ms(100); GPIOA-ORD ^= GPIO_Pin_1; //LED1点亮 (4)取反(~) 这是个单目运算符,二进制位取反,如果1取反,结果为0,0取反,结果为1,即:~0=1,~1=0。 程序中取反(~)和按位与()相结合,会有复位的效果。 比如0xd3(~0x10) (~0x10)结果为b11101111,再和0xc3按位与: 是不是达到了复位的效果呢? (5)左移运算符() 左移运算符用来将一个数的各二进制位全部左移若干位,后面补0,移出的位被丢弃,相当于乘2运算,因为位运算比乘法用算快,所以可对一个代码进行优化。 比如0x018,结果为b100000000,就是1后面补8个0,移位运算符在通信时,接收数据时很有用。 (6)右移运算符() 右移运算是将一个二进制位的操作数按指定移动的位数向右移动,移出位被丢弃,对于左边移出的空位,如果是正数,则一律补0,如果是负数,则可能补0,也可能补0,这由不同的机器决定。 这个运算符可以用来获取一个16位数据的高8位,比如:要获取0x1111的高8位,0xcc118,便可得到高8位0xcc。 到这里,今天的内容就结束了。 如果 有写的不合适的地方,还请大家多多指教。如果你有兴趣,也可以一起互相学习,共同进步。 (微信号 :c18093458455)