Bit-banding簡稱位帶,有人也叫位段。支持位帶操作后,可以使用普通的加載/存儲指令來對單一的比特進行讀寫。
很多朋友是從學習51單片機過來的,都知道P1.1這個引腳可以單獨控制,我們操作的這個引腳就是一個Bit位。
我們都知道在STM32中不能直接操作寄存器的某一個Bit位,比如單獨控制PA端口輸出數據寄存器中的ODR1,如下圖所示:

STM32F1內核Cortex-M3早就考慮到了這個問題,為了能達到直接操作ODR1這類Bit位,就在內核中開辟了一塊地址區域(位帶別名):可以將ODR1這類Bit位(位帶區)映射到位帶別名區域對應的地址,只需要操作映射后的地址,就可以實現操作這個ODR1位了。
簡單來說就是映射操作,只是這個映射操作有許多約定要遵循。
在Cortex-M3中有兩個區實現了位帶操作,其中一個是SRAM區的最低1MB范圍,第二個則是片內外設區的最低1MB范圍。
這兩個區域如下圖紅色標注的區域:

這兩個1MB將分別映射到另外兩個地址區域:

位帶操作的主要目的:通過Bit位地址(A)計算得到別名區地址(AliasAddr)。
1、SARM區計算公式
AliasAddr=0x22000000+((A‐0x20000000)*8+n)*4=0x22000000+(A-0x20000000)*32+n*4
2、片上外設區計算公式
AliasAddr=0x42000000+((A-0x40000000)*8+n)*4=0x42000000+(A-0x40000000)*32+n*4
由于映射關系一樣,所以公式原理也一樣,只是地址不一樣。計算公式需要結合上圖比特的膨脹對應關系來理解。
*8:1個字4個字節
*4:1個字節8Bit
#define BITBAND_RAM(RAM, BIT) (*((uint32_t volatile*)(0x22000000u + (((uint32_t)&(RAM) - (uint32_t)0x20000000u)<<5) + (((uint32_t)(BIT))<<2))))2、外設寄存器位帶宏定義
#define BITBAND_REG(REG, BIT) (*((uint32_t volatile*)(0x42000000u + (((uint32_t)&(REG) - (uint32_t)0x40000000u)<<5) + (((uint32_t)(BIT))<<2))))
A.?RAM地址0x20001000的Bit1位寫0
BITBAND_RAM(*(uint32_t *)0x20001000, 1) = 0;uint8_t Val;Val=BITBAND_RAM(*(uint32_t *)0x20001000, 1);
C.?對PA1數據輸出寄存器輸出1
BITBAND_REG(GPIOA->ODR, 1) = 1;uint8_t Val;Val=BITBAND_REG(GPIOA->ODR, 1);
這里就是操作某一個地址,類似于操作指針一樣。
關于Cortex-M3的位帶操作,更多詳情可以參看Cortex-M3技術參考手冊(權威指南)。
這后面的Cortex-M處理器已經不再支持位帶操作了,從兼容未來軟件的角度來說,不是很建議大家再繼續使用了。
只是位帶操作是一種經典,這里分享給大家了解一下,希望對你們有幫助。

END
來源:嵌入式專欄
→點關注,不迷路←