嵌入式程式設計 c位操作

2021-10-08 23:51:53 字數 3380 閱讀 8401

**在學習c語言位操作前需要具備十六進製制和二進位制的知識以及從二進位制與十六進製制的相互轉換,相應的教程請移步新增鏈結描述

現在掌握了十六進製制和二進位制之間的相互轉換知識,我們可以從c中的按位(或位級別)運算開始。基本上有6種型別的按位運算子。 這些是 :

1.以「 |」表示 或 運算子

2.以「&」表示 與 運算子

3.以「〜」表示 補碼或取反運算子

4.右移和左移分別用「 >>」和「 <

5.以「 ^」表示 異或 運算子

ps:按位操作只能用於整數型別的資料,不能用於浮點型和double型

ps:在c/c++中需要加上「0x」字首,否則會被編譯器認為是十進位制數。

考慮有乙個16位暫存器連線到16個引腳。 將任何位更改為1將產生乙個高電平(邏輯1),將其設定為0將產生乙個低電平(邏輯0)。 如果我們將位號8(從右起)分配為「 1」,則引腳8將產生高電平。

reg =(1

<<8)

;/*或者*/

reg =

0x80

;

如您所見,直接使用二進位制數是一件令人頭疼的事。 相反,使用十六進製制使其更容易一些,而使用左移運算子則使其非常簡單。 這裡的「 <>」,即右移運算子。

「(1 << 8)」僅表示「將1向左移位19位」。 其他位預設為零。

這與數字邏輯完全相同,即1與x進行或運算始終為1,0與x進行或運算始終為1,其中x不為0。 現在有兩個二進位制數字n1 = 0100和n2 = 1001。 在這裡,n1的第一位將與n2的第一位進行「或」運算,n1的第二位將與n2的第二位進行「或」運算,依次運算。

得到 4|9=13;

如果我們想將第8位和第7位設為』1』,我們可以使用「|」表示的二進位制或運算子。

reg = (1

<<

8)|(

1<<7)

;

如果我們想將前8位都設為『1』,可以使用十六進製制表示法而不是使用移位運算子來完成。想到乙個前八位(從右至左)都為1的二進位制數字然後將此數字轉換為十六進製制並使用它。

reg=

0xff

;

由以上兩種情況可得,當單個或少量引腳位操作時使用移位運算子,當大量引腳位操作時用十六進製制當我們需要將所有的0換位1,或者1換位0,則需要取反運算『~』。

unsigned

int x =

0xff

;reg =

~(x)

;/*或者*/

reg=

~0xff

;

c中的二進位制的與運算子用』&'表示。 當兩個數字進行「與」運算時,兩個數字中的每對「對應」位均進行「與」運算。 例如:1010和1101,這裡兩個數的第n位進行與運算以得到結果。

unsigned

char n1,n2,n3;

n1 =

0xf4

;// 二進位制 n1 = 11110100;

n2 =

0x3a

;// 二進位制 n2 = 00111010;

n3 = n1 & n2;

// 二進位制 n3 = 00110000;

異或運算用『^』表示,如果兩個輸入位不同,則結果將為』1』,如果兩個輸入位相同,則結果將為』0』。

unsigned

int n1,n2,n3;

n1 =

0x13

;//binay n1 = 10011

n2 =

0x1a

;//binay n2 = 11010;

n3 = n1^n2;

// n2 = 01001;

若乙個8位的暫存器,例如regt_8b用於啟動/停止8個不同的定時器。 位0(從左開始)控制定時器0,位1控制定時器1,依此類推…向位寫入』1』將啟動定時器,而』0』將停止定時器。

現在,假設計時器7、6、5已啟動,其他計時器已停止。 因此regt_8b的當前值為』11100000』。

若我們要啟動計時器3。我們可以採用不影響其他位的方式執行此操作,如下所示:

regt_8b |=(

1<<3)

;//或者 regt_8b = regt_8b | (1<<3);

若我們想關閉定時器6

regt_8b = regt_8b &(~

(1<<6)

);/*或者 regt_b & = (~(1<<6));

很多時候,我們需要讀取表示硬體狀態變化的暫存器中的某些標誌。比如開關的狀態。

若乙個32位的暫存器regx,其中的第12位表示資料從uart接收引腳到達緩衝器。 此資料可能是mcu啟動或停止或執行某項操作的命令。 因此,我們需要閱讀命令,然後解釋它並呼叫適當的函式。 在最簡單的方法中,我們可以連續掃瞄regx的第12位,如下所示:

while

( regx &(1

<<12)

)//wait indefinitely until 12th bit changes from 0 to 1

只有當regx的第12位為1,否則(regx&(1 << 12))的結果將始終為零。 當第12位為1時,為true條件,並且執行while迴圈內的**。

要從暫存器中提取一位,我們可以使用乙個變數,其中除我們所插入的位之外的所有其他位位置都被強制為0。這可以使用掩碼來完成。

假設我們要提取第13位,為此,我們首先定義乙個掩碼,其中第13位為1,其餘均為零。 然後,我們將此掩碼與暫存器進行「與」運算並將結果儲存在變數中。

unsigned

int mask ,extract_n;

mask =(1

<<13)

;extract_n = regx & mask;

如果regx的第13位為1,則extract_n的第13位也將為1。

若要測試regx的第13位是0還是1,我們可以按以下步驟完成:

if

(regx &(1

<<13)

)

ps:參考資料新增鏈結描述

嵌入式 位 bit 操作

嵌入式系統總是要使用者對變數或暫存器進行位操作。給定乙個整型變數 a,寫兩段 第乙個設定a的 bit 3 第二個清除a 的 bit 3 在以上兩個操作中,要保持其它位不變。對這個問題有三種基本的反應 1 不知道如何下手。該被面者從沒做過任何嵌入式系統的工作。2 用 bit fields bit fi...

嵌入式中C語言的位操作

位運算構建特定的二進位制數 技術公升級 使用巨集定義完成位運算 總結在操作中使用 將暫存器某些 特定位變成0,但是不影響其他位,可以進行如下操作,假設原來的暫存器reg1中的值為0xaaaaaaaa,希望將bit8 bit15清零並且其他位不進行改變,將這個數和0xffff00ff進行位與即可。re...

嵌入式程式設計

1 interrupt double compute area double radis 1 isr不能返回乙個值。2 isr不能傳遞引數。3 在許多處理器中浮點是不可重入的。4 printf 經常有重入和效能上的問題,所以一般不使用printf 2.volatile 1 volatile的語法和c...