位帶操作在stm32中的C語言實現

2021-07-05 05:08:21 字數 1307 閱讀 6744

位帶操作在stm32中的c語言實現

首先:#define bitband(addr,bitnum)  ((addr & 0xf0000000) + 0x2000000 + ((addr & 0xfffff) << 5) + (bitnum << 2))

對上句程式的解釋:

利用巨集定義的方式將位帶位址的對映表示出來,該函式有兩個引數addr和bitnum,分別是原本的位址和在資料中的第幾位。我們知道兩個公式如下:

0x2000_0000‐0x200f_ffff位址空間:aliasaddr = 0x22000000 + (a – 0x20000000)*32 + n*4

0x4000_0000‐0x400f_ffff位址空間:aliasaddr = 0x42000000 + (a – 0x40000000)*32 + n*4

仔細觀察我們可以發現,是有規律可尋的。兩個公式的基位址乙個是0x22000000,乙個是0x42000000,他們只是最高位不一樣,這個最高位和最原始的位址的最高位是一致的。所以我們通過 (addr & 0xf0000000) 來取最高位,再加上0x2000000就得到了公式中的基位址。我們知道兩個位址空間中位址的變換只是在低5位上,比如0x2000_0000 — 0x200f_ffff(有5個f),利用(a – 0x20000000)的目的是得到位址addr和0x2000_0000之間的偏移,也就是低5位的內容,所以我們通過 (addr & 0xfffff)得到了低5位的資料,也即是偏移量。公式中的乘以32,我們使用效率更高的左移5位,同理,之後的乘以4也是通過移位操作來實現的。

然後我們需要將上述位址轉換為乙個指標,也就是,我們要告訴編譯器這是乙個位址。

#define  mem_addr(addr)  *((volatile unsigned long *) (addr))

其中使用到的volatile這個關鍵字是為了防止編譯器進行優化。這是必須的。

完成上述兩步之後,我們就可以使用位帶操作了,比如我們要對gpioa中的1管腳進行輸出控制,我們需要控制gpioa的odr暫存器,通過手冊我們知道它的位址是(gpioa_base + 0x0c),所以我們定義:

#define  gpioa_odr_addr  (gpioa_base + 0x0c)

#define  gpioa(bitnum)   mem_addr( bitband(gpioa_odr_addr,bitnum))

將gpioa的1管腳置高,就可以這樣寫:

gpioa(1) = 1;

同理,我們可以得到其他管腳控制的方法,或者獲取其他管腳的輸入。

以上,就是我對stm32的位帶操作的實現的理解,有什麼理解不到位的地方,請大家指證,希望和大家多多交流。

stm32之位帶操作

stm32相對於8位微控制cpu來說實在強大的不得了,依稀記得51控制i o空的時候是 sbit led1 p0 0 然而我們在32卻沒有想 sbit 類似的關鍵字進行i o的某位進行操作。於是引入了 位帶操作的概念 什麼事位帶操作?標準的定義是 通過訪問位帶別名區來實現,即通過將每個位元位膨脹成乙...

STM32位帶操作詳細介紹

3.gpio位帶實現 在stm32中,如果我們要使pb0埠輸出低電平,可以用如下語句 gpiob odr 0 0 在51微控制器中我們是這樣的 p0 0xff 匯流排操作 還有一種方法 sbit led1 p0 0 led1 0 位操作 在stm32中能不能實現位操作呢,當然是可以的,這種方法我們叫...

STM32 Contex M的位帶操作

位帶操作的思想在30年前就已經有了,還是8051開創的先河。如今,contex m3將此能力進化,這裡的位帶操作位定址區威力大幅度增強。有兩個區中實現了位帶。其中乙個是 sram 區的最低 1mb 範圍,第二個則是片內外設區的最低 1mb 範圍。這兩個區中的位址除了可以像普通的 ram 一樣使用外,...