位帶操作可能現(xiàn)在用的比較少了,但在以前MCU性能不是很好的時(shí)候,位帶操作卻是眾多軟件工程師常用操作。
本文主要結(jié)合Cortex-M3內(nèi)核(STM32F1)來(lái)講述,相信許多朋友在初學(xué)的時(shí)候都被繞暈過。
1、關(guān)于位帶操作
Bit-banding簡(jiǎn)稱位帶,有人也叫位段。支持位帶操作后,可以使用普通的加載/存儲(chǔ)指令來(lái)對(duì)單一的比特進(jìn)行讀寫。
很多朋友是從學(xué)習(xí)51單片機(jī)過來(lái)的,都知道P1.1這個(gè)引腳可以單獨(dú)控制,我們操作的這個(gè)引腳就是一個(gè)Bit位。
我們都知道在STM32中不能直接操作寄存器的某一個(gè)Bit位,比如單獨(dú)控制PA端口輸出數(shù)據(jù)寄存器中的ODR1,如下圖:
STM32F1內(nèi)核Cortex-M3早就考慮到了這個(gè)問題,為了能達(dá)到直接操作ODR1這類Bit位,就在內(nèi)核中開辟了一塊地址區(qū)域(位帶別名):可以將ODR1這類Bit位(位帶區(qū))映射到位帶別名區(qū)域?qū)?yīng)的地址,只需要操作映射后的地址,就可以實(shí)現(xiàn)操作這個(gè)ODR1位了。
簡(jiǎn)單來(lái)說(shuō)就是映射操作,只是這個(gè)映射操作有許多約定要遵循。
2、位帶操作中的映射關(guān)系
在Cortex-M3中有兩個(gè)區(qū)實(shí)現(xiàn)了位帶操作,其中一個(gè)是SRAM區(qū)的最低 1MB 范圍,第二個(gè)則是片內(nèi)外設(shè)區(qū)的最低 1MB 范圍。
這兩個(gè)區(qū)域如下圖紅色標(biāo)注的區(qū)域:
這兩個(gè)1MB將分別映射到另外兩個(gè)地址區(qū)域:1.SRAM區(qū)的最低1MB(0x2000 0000 --- 0x200F FFFF) 映射到(0x2200 0000 --- 0x23FF FFFF)。
2.片內(nèi)外設(shè)區(qū)的最低1MB(0x4000 0000 --- 0x400F FFFF)映射到(0x4200 0000 --- 0x43FF FFFF)。
其實(shí)就是映射到偏移(距離自身)0x0200 0000外的32MB空間(位帶別名區(qū)),如下圖SRAM區(qū)映射關(guān)系:
提示:看圖中的有顏色的8Bit,它是映射到偏移0x0200 0000外的32Bit(4Byte)空間上。我們讀寫0x2200 0000這個(gè)地址,其實(shí)就是操作0x2000 0000中的Bit0位。
這就是所謂的“比特的膨脹對(duì)應(yīng)關(guān)系”,1Bit膨脹到32Bit(4字節(jié))。4字節(jié)對(duì)應(yīng)的就是那1Bit位的地址,而這個(gè)地址中的數(shù)據(jù)只有最低一位才有效(LSB)。
解釋上面多處出現(xiàn)的關(guān)鍵詞:位帶區(qū):支持位帶操作的地址區(qū);位帶別名:對(duì)別名地址的訪問最終作用到位帶區(qū)的訪問上;
3、位帶區(qū)->別名區(qū)計(jì)算公式
位帶操作的主要目的:通過Bit位地址(A)計(jì)算得到別名區(qū)地址(AliasAddr)。
1.SARM區(qū)計(jì)算公式
AliasAddr= 0x22000000 + ((A‐0x20000000)*8+n)*4 =0x22000000+(A-0x20000000)*32 + n*4
2.片上外設(shè)區(qū)計(jì)算公式
AliasAddr= 0x42000000 + ((A-0x40000000)*8+n)*4 =0x42000000+(A-0x40000000)*32 + n*4
由于映射關(guān)系一樣,所以公式原理也一樣,只是地址不一樣。計(jì)算公式需要結(jié)合上圖比特的膨脹對(duì)應(yīng)關(guān)系來(lái)理解。
*8:1個(gè)字4個(gè)字節(jié);
*4:1個(gè)字節(jié)8Bit;
4、代碼實(shí)現(xiàn)
利用上面計(jì)算公式,代碼實(shí)現(xiàn)的過程就很簡(jiǎn)單,我們的目的就是對(duì)“AliasAddr”這個(gè)地址進(jìn)行讀寫操作。
1.RAM位帶操作宏定義
#defineBITBAND_RAM(RAM,BIT)(*((uint32_tvolatile*)(0x22000000u+(((uint32_t) (RAM)-(uint32_t)0x20000000u)<<5)?+?(((uint32_t)(BIT))<<2))))
2.外設(shè)寄存器位帶宏定義
#defineBITBAND_REG(REG,BIT)(*((uint32_tvolatile*)(0x42000000u+(((uint32_t) (REG)-(uint32_t)0x40000000u)<<5)?+?(((uint32_t)(BIT))<<2))))
方便大家對(duì)比,給一個(gè)截圖:
A.RAM地址0x20001000的Bit1位寫0
BITBAND_RAM(*(uint32_t*)0x20001000,1)=0;
B.讀取RAM地址0x20001000的Bit1位
uint8_tVal;Val=BITBAND_RAM(*(uint32_t*)0x20001000,1);
C.對(duì)PA1數(shù)據(jù)輸出寄存器輸出1
BITBAND_REG(GPIOA->ODR,1)=1;
D.讀取PA1數(shù)據(jù)輸出寄存器
uint8_tVal;Val=BITBAND_REG(GPIOA->ODR,1);
這里就是操作某一個(gè)地址,類似于操作指針一樣;
5、位帶操作優(yōu)缺點(diǎn)
1.優(yōu)點(diǎn)
相比直接操作寄存器代碼更簡(jiǎn)潔,運(yùn)行效率更高。避免在多任務(wù),或中斷時(shí)出現(xiàn)紊亂等。
2.缺點(diǎn)
操作不當(dāng)(傳入地址參數(shù)不對(duì)),容易出現(xiàn)總線Fault。
6、最后
關(guān)于Cortex-M3的位帶操作,更多詳情可以參看Cortex-M3技術(shù)參考手冊(cè)(權(quán)威指南)。
這后面的Cortex-M處理器已經(jīng)不再支持位帶操作了,從兼容未來(lái)軟件的角度來(lái)說(shuō),不是很建議大家再繼續(xù)使用了。
只是位帶操作是一種經(jīng)典,這里分享給大家了解一下,希望對(duì)你們有幫助。
來(lái)源:嵌入式專欄
免責(zé)聲明:本文為轉(zhuǎn)載文章,轉(zhuǎn)載此文目的在于傳遞更多信息,版權(quán)歸原作者所有。本文所用視頻、圖片、文字如涉及作品版權(quán)問題,請(qǐng)聯(lián)系小編進(jìn)行處理
審核編輯 黃宇
-
mcu
+關(guān)注
關(guān)注
146文章
16988瀏覽量
350302 -
Cortex-M
+關(guān)注
關(guān)注
2文章
227瀏覽量
29727
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論