原创 STM32系列之四旋翼(二)位运算

2017-8-9 14:32 1579 19 19 分类: MCU/ 嵌入式

今天跟着视频学习了位运算,感觉很有用,这里分享给大家。

位运算

位运算主要有:位与运算符(&)、按位或运算符(|)、异或运算符(^)、取反运算符(~)、左移运算符(<<)、右移运算符(>>)等,下面我们分别介绍这几个位运算的用法及其在程序中的运用。

(1)位与(&)

按位与运算符“&”是双目运算符。其功能是参与运算的两数各对应的二进位相与。两个数相“与”时,如果两个位同时为1,则结果为1,否则为0,即:1&1=1,1&0=0,0&1=0,0&0=0。

比如:0xc3&0x11计算如下

在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运算,因为位运算比乘法用算快,所以可对一个代码进行优化。

比如0x01<<8,结果为b100000000,就是1后面补8个0,移位运算符在通信时,接收数据时很有用。

(6)右移运算符(>>)

右移运算是将一个二进制位的操作数按指定移动的位数向右移动,移出位被丢弃,对于左边移出的空位,如果是正数,则一律补0,如果是负数,则可能补0,也可能补0,这由不同的机器决定。

这个运算符可以用来获取一个16位数据的高8位,比如:要获取0x1111的高8位,0xcc11>>8,便可得到高8位0xcc。

到这里,今天的内容就结束了。

如果有写的不合适的地方,还请大家多多指教。如果你有兴趣,也可以一起互相学习,共同进步。 (微信号 :c18093458455)

文章评论0条评论)

登录后参与讨论
我要评论
0
19
关闭 站长推荐上一条 /2 下一条