快速理解STM32位帶操作原理和用途
說到位帶操作,可能很多人比較陌生,但說到控制IO,你肯定不會陌生。有的項目為了最大效率控制IO,使用位帶操作。下面就來簡單說說未帶操作的內(nèi)容。
一、初識位帶操作
這兩個1MB將分別映射到另外兩個地址區(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)。
提示:看圖中的有顏色的8Bit,它是映射到偏移0x0200 0000外的32Bit(4Byte)空間上。我們讀寫0x2200 0000這個地址,其實就是操作0x2000 0000中的Bit0位。
解釋上面多處出現(xiàn)的關(guān)鍵詞
位帶區(qū):支持位帶操作的地址區(qū);
位帶別名:對別名地址的訪問最終作用到位帶區(qū)的訪問上;
三、位帶區(qū)->別名區(qū)計算公式
1.SARM區(qū)計算公式
AliasAddr = 0x22000000 + ((A‐0x20000000)*8+n)*4 = 0x22000000+(A-0x20000000)*32 + n*4
2.片上外設(shè)區(qū)計算公式
AliasAddr = 0x42000000 + ((A-0x40000000)*8+n)*4 = 0x42000000+(A-0x40000000)*32 + n*4
*8:1個字4個字節(jié);
*4:1個字節(jié)8Bit;
四、代碼實現(xiàn)
1.RAM位帶操作宏定義
#define BITBAND_RAM(RAM, BIT) (*((uint32_t volatile*)(0x22000000u + (((uint32_t)&(RAM) - (uint32_t)0x20000000u)<<5) + (((uint32_t)(BIT))<<2))))
2.外設(shè)寄存器位帶宏定義
#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;
B.讀取RAM地址0x20001000的Bit1位
uint8_t Val;
Val=BITBAND_RAM(*(uint32_t *)0x20001000, 1);
C.對PA1數(shù)據(jù)輸出寄存器輸出1
BITBAND_REG(GPIOA->ODR, 1) = 1;
D.讀取PA1數(shù)據(jù)輸出寄存器
uint8_t Val;
Val=BITBAND_REG(GPIOA->ODR, 1);
這里就是操作某一個地址,類似于操作指針一樣;
五、位帶操作優(yōu)缺點
1.優(yōu)點
2.缺點
操作不當(dāng)(傳入地址參數(shù)不對),容易出現(xiàn)總線Fault。
六、說明
基于STM32的Keil、IAR仿真打印輸出
CMSIS RTOS API,內(nèi)核通用API接口
Linux 內(nèi)核的 100% 自由版本 GNU Linux-libre 5.8 發(fā)布
長按前往圖中包含的公眾號關(guān)注
免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!