1024G 嵌入式資源大放送!包括但不限於C/C++、單片機、Linux等。關注微信公衆號【嵌入式大雜燴】,回覆1024,便可免費獲取!git
操做位有兩種方法,一種是位字段,另外一種是使用按位運算符。位字段的方法可查看往期筆記:【C語言筆記】位域。本文介紹使用按位運算符操做位的方法。下表爲幾種位操做符及其含義:github
在嵌入式編程中,經常須要對一些寄存器進行配置,有的狀況下須要改變一個字節中的某一位或者幾位,可是又不想改變其它位原有的值,這時就可使用按位運算符進行操做。下面進行舉例說明,假若有一個8位的TEST寄存器:編程
當咱們要設置第0位bit0的值爲1時,可能會這樣進行設置:微信
TEST = 0x01;
可是,這樣設置是不夠準確的,由於這時候已經同時操做到了高7位:bit1~bit7,若是這高7位沒有用到的話,這麼設置沒有什麼影響;可是,若是這7位正在被使用,結果就不是咱們想要的了。markdown
在這種狀況下,咱們就能夠借用「&」和「|」進行配置。ide
對於二進制位操做來講,無論該位原來的值是0仍是1,它跟0進行&運算,獲得的結果都是0,而跟1進行&運算,將保持原來的值不變;無論該位原來的值是0仍是1,它跟1進行|運算,獲得的結果都是1,而跟0進行|運算,將保持原來的值不變。函數
因此,此時能夠設置爲:ui
TEST = TEST | 0x01;
其意義爲:TEST寄存器的高7位均不變,最低位變成1了。在實際編程中,常改寫爲:.net
TEST |= 0x01;
這種寫法能夠必定程度上簡化代碼,是 C 語言經常使用的一種編程風格。code
一樣的,要給TEST的低4位清0,高4位保持不變,能夠進行以下配置:
TEST &= 0xF0;
這個場景單片機開發中常用,方法就是先對須要設置的位用&操做符進行清零操做,而後用|操做符設值。好比我要改變GPIOA的狀態,能夠先對寄存器的值進行&清零操做:
GPIOA->CRL &= 0XFFFFFF0F; //將第4-7位清0
而後再與須要設置的值進行|或運算:
GPIOA->CRL |= 0X00000040; //設置相應位的值,不改變其餘位的值移位操做提升代碼的可讀性。
移位操做在單片機開發中也很是重要,下面讓咱們看看固件庫的GPIO初始化的函數裏面的一行代碼:
GPIOx->BSRR = (((uint32_t)0x01) << pinpos);
這個操做就是將BSRR寄存器的第pinpos位設置爲1,爲何要經過左移而不是直接設置一個固定的值呢?其實,這是爲了提升代碼的可讀性以及可重用性。這行代碼能夠很直觀明瞭的知道,是將第pinpos位設置爲1。若是你寫成:
GPIOx->BSRR = 0x0030;
這樣的代碼就很差看也很差重用了。
相似這樣的代碼不少:
GPIOA->ODR |= 1 << 5; //PA.5輸出高,不改變其餘位
這樣咱們一目瞭然,5告訴咱們是第5位也就是第6個端口,1告訴咱們是設置爲1了。
~取反操做使用技巧SR寄存器的每一位都表明一個狀態,某個時刻咱們但願去設置某一位的值爲0,同時其餘位都保留爲1,簡單的做法是直接給寄存器設置一個值:
TIMx->SR = 0xFFF7;
這樣的做法設置第3位爲0,可是這樣的做法一樣很差看,而且可讀性不好。看看庫函數代碼中怎樣使用的:
TIMx->SR = (uint16_t)~TIM_FLAG;
而TIM_FLAG 是經過宏定義定義的值:
#define TIM_FLAG_Update ((uint16_t)0x0001) #define TIM_FLAG_CC1 ((uint16_t)0x0002) #define TIM_FLAG_CC2 ((uint16_t)0x0004) #define TIM_FLAG_CC3 ((uint16_t)0x0008) #define TIM_FLAG_CC4 ((int16_t)0x0010) #define TIM_FLAG_COM ((uint16_t)0x0020) #define TIM_FLAG_Trigger ((uint16_t)0x0040) #define TIM_FLAG_Break ((uint16_t)0x0080) #define TIM_FLAG_CC1OF ((uint16_t)0x0200) #define TIM_FLAG_CC2OF ((uint16_t)0x0400) #define TIM_FLAG_CC3OF ((uint16_t)0x0800) #define TIM_FLAG_CC4OF ((uint16_t)0x1000)
即設置SR第3位爲0時可設置爲:
TIMx->SR = (uint16_t)~TIM_FLAG_CC3;
以上就是關於位操做在嵌入式編程中的一些技巧,若有錯誤,歡迎指出!
參考資料:
《STM32F1開發指南-庫函數版本_V3.1 》
《手把手教你學51單片機》