日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【STM32】位操作、按位与、按位或、按位异或、取反、左移、右移等基础 C 语言知识补充

發布時間:2025/4/5 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【STM32】位操作、按位与、按位或、按位异或、取反、左移、右移等基础 C 语言知识补充 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章目錄

  • 1 位操作
    • 1.1 按位與
    • 1.2 按位或
    • 1.3 按位異或
    • 1.4 取反
    • 1.5 左移
    • 1.6 右移
  • 2 單片機中常用操作
    • 2.1 不改變其他位時,對某幾個位設定值
    • 2.2 移位操作提高代碼可讀性
    • 2.3 取反操作使用技巧

1 位操作

運算符含義
&按位與
按位或
^按位異或
~取反
<<左移
>>右移

c 語言中存在以上 6 個位操作運算符,且它們只能用于整形操作數。

總結:對于原二進制數來說,&0是屏蔽,&1是不變。

總結:對于原二進制數來說,|0是不變,|1是置1。

總結:對于原二進制數來說,^0是不變,^1是反轉。


1.1 按位與

按位與的定義是:同一二進制位上的數字都是1的話,& 的結果為1,否則為0。

運算結果
0 & 00
0 & 10
1 & 00
1 & 11

根據這個特性,& 操作常常用來屏蔽特定的二進制位。

例如:0000 1111 & 0000 0011 = 0000 0011

與運算0 0 0 0 1 1 1 1
&0 0 0 0 0 0 1 1
結果0 0 0 0 0 0 1 1

可以看見,1111的前兩位被屏蔽成為0了。

所以如果想清空數據,只需要將原二進制數與上 &0 就可以了。0的位數對應原二進制數的位數,對各位進行屏蔽,全部置0。

相對的,&可以利用0來屏蔽,也可以用1來讀取。

例如: 一個二進制數 1101 1001,我只想要它的后四位,怎么辦呢?

只需要進行如下操作:1101 1001 & 0000 1111即可。

與運算1 1 0 1 1 0 0 1
&0 0 0 0 1 1 1 1
結果0 0 0 0 1 0 0 1

其實該方法是屏蔽和讀取的結合,&0保證消除無用位,&1保證有用數據的完整性。

總結:對于原二進制數來說,&0是屏蔽,&1是不變。


1.2 按位或

定義:只要參與運算的雙方其中有一個是1,結果就是1.同0才為0。

運算結果
0 | 00
0 | 11
1 | 01
1 | 11

主要用作將某些特定位置1。

例如:1010 0000 | 0000 1111 = 1010 1111。

或運算1 0 1 0 0 0 0 0
0 0 0 0 1 1 1 1
結果1 0 1 0 1 1 1 1

總結:對于原二進制數來說,|0是不變,|1是置1。


1.3 按位異或

只要參與運算的雙方互異,結果就為1,否則為0。

運算結果
0 ^ 00
0 ^ 11
1 ^ 01
1 ^ 10

可以通過上面的定義看到,一個數^1 的話就會0變成1,1變成0,而^0則不對原數進行改變。所以根據此特性可以對特定位進行0 1 反轉。

例如: 1100 1100 ^ 0000 1100 = 1100 0000。

異或運算1 1 0 0 1 1 0 0
^0 0 0 0 1 1 0 0
結果1 1 0 0 0 0 0 0

同樣的,如果對一個數進行^0,代表保留原值。

總結:對于原二進制數來說,^0是不變,^1是反轉。


1.4 取反

對一個二進制數進行取反。1變0,0變1。

唯一需要注意的一點是,~的優先級是邏輯運算符中最高的,必須優先計算。


1.5 左移

左移與右移比較類似,是將目標二進制數字向左/右移動相應的位數。

左移補0:1111 1111 << 1 == 1111 1110,換算十進制的話是原來數值的2倍。

左移1 1 1 1 1 1 1 1
<<1
結果1 1 1 1 1 1 1 0

1.6 右移

右移看情況:負數補1,正數補0。需要看符號位。同樣,換算為十進制數值變為原來的1/2.

右移1 1 1 1 1 1 1 1
>>1
結果0 1 1 1 1 1 1 1

總結:左乘右除。


2 單片機中常用操作

2.1 不改變其他位時,對某幾個位設定值

比如要改變 GPIOA 的狀態,可以先對寄存器的值進行 & 清零操作

GPIOA -> CRL &= 0XFFFFFF0F; // 將第 4-7 位清 0

然后再與需要設置的值進行 | 或運算

GPIOA -> CRL |= 0X00000040; // 設置相應位的值,且不改變其他位的值

2.2 移位操作提高代碼可讀性

以固件庫的 GPIO 初始化的函數里一行代碼為例

GPIOx -> BSRR = (((uint32_t)0x01) << pinpos);

這個操作就是將 BSRR 寄存器的第 pinpos 位設置為 1。
為什么要通過左移而不是直接設定呢?其實,這是為了提高代碼的可讀性以及可重用性。這行代碼可以直觀明了的知道,是將第 pinpos 位設置為 1。

如果寫成

GPIOx -> BSRR = 0x0030;

這樣的代碼就不容易看出,也不好重用了。

類似的代碼還有:

GPIOA -> ORT |= 1<<5; // PA.5 輸出高,不改變其他位

這樣我們一目了然,5 告訴我們是第 5 位也就是第 6 個端口,1 告訴我們是設置成了 1。

2.3 取反操作使用技巧

SR 寄存器的每一位都代表一個狀態,某個時刻我們希望去設置某一位的值為 0,同時其他位都保留位 1,簡單的作法是直接給寄存器設置一個值:

TIMx -> SR = 0xFFF7;

這樣做法可讀性交較差。

看看庫函數中代碼是如何使用的:

TIMx -> SR = (uint16_t)~TIM_FLAG;

而 TIM_FLAG 是通過宏定義完成的值:

#define TIM_FLAG_Update ((uint16_t)0x0001) #define TIM_FLAG_CC1 ((uint16_t)0x0002)

看這個就容易明白,可以直接從宏定義重看出 TIM_FLAG_Update 就是設置的第 0 位了,可讀性較強。


Ref: C語言中的邏輯運算符:按位與,按位或,按位異或,取反,左右移位
Ref: STM32 不完全手冊 - 立創開源

總結

以上是生活随笔為你收集整理的【STM32】位操作、按位与、按位或、按位异或、取反、左移、右移等基础 C 语言知识补充的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。