STM32 Contex M的位帶操作

2021-07-09 10:20:52 字數 3589 閱讀 4280

位帶操作的思想在30年前就已經有了,還是8051開創的先河。如今,contex-m3將此能力進化,這裡的位帶操作位定址區威力大幅度增強。

有兩個區中實現了位帶。其中乙個是 sram 區的最低 1mb 範圍,第二個則是片內外設區的最低 1mb 範圍。這兩個區中的位址除了可以像普通的 ram 一樣使用外,它們還都有自己的「位帶別名區」,位帶別名區把每個位元膨脹成乙個 32 位的字。當你通過位帶別名區訪問這些字時,就可以達到訪問原始位元的目的。

上圖為位帶區和位帶別名區的膨脹對應關係

在位帶區中,每個位元都對映到別名位址區的乙個字——這是只有 lsb 有效的字。當一

個別名位址被訪問時,會先把該位址變換成位帶位址。對於讀操作,讀取位帶位址中的乙個

字,再把需要的位右移到 lsb,並把 lsb 返回。對於寫操作,把需要寫的位左移至對應的位

序號處,然後執行乙個原子的「讀-改-寫」過程。

m3的位帶位址對映如下表所示

介紹完了位址對映之後,下面就是位帶操作的實現方式了。

一、寫資料到位帶別名區

二、從位帶別名區讀取位元

具體的**實現如下所示:

//位帶操作,實現51類似的gpio控制功能

//io口操作巨集定義

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

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

#define bit_addr(addr, bitnum) mem_addr(bitband(addr, bitnum))

//io口位址對映

#define gpioa_odr_addr (gpioa_base+20) //0x40020014

#define gpiob_odr_addr (gpiob_base+20) //0x40020414

#define gpioc_odr_addr (gpioc_base+20) //0x40020814

#define gpiod_odr_addr (gpiod_base+20) //0x40020c14

#define gpioe_odr_addr (gpioe_base+20) //0x40021014

#define gpiof_odr_addr (gpiof_base+20) //0x40021414

#define gpiog_odr_addr (gpiog_base+20) //0x40021814

#define gpioh_odr_addr (gpioh_base+20) //0x40021c14

#define gpioi_odr_addr (gpioi_base+20) //0x40022014

#define gpioa_idr_addr (gpioa_base+16) //0x40020010

#define gpiob_idr_addr (gpiob_base+16) //0x40020410

#define gpioc_idr_addr (gpioc_base+16) //0x40020810

#define gpiod_idr_addr (gpiod_base+16) //0x40020c10

#define gpioe_idr_addr (gpioe_base+16) //0x40021010

#define gpiof_idr_addr (gpiof_base+16) //0x40021410

#define gpiog_idr_addr (gpiog_base+16) //0x40021810

#define gpioh_idr_addr (gpioh_base+16) //0x40021c10

#define gpioi_idr_addr (gpioi_base+16) //0x40022010

//io口操作,只對單一的io口!

//確保n的值小於16!

#define paout(n) bit_addr(gpioa_odr_addr,n) //輸出

#define pain(n) bit_addr(gpioa_idr_addr,n) //輸入

#define pbout(n) bit_addr(gpiob_odr_addr,n) //輸出

#define pbin(n) bit_addr(gpiob_idr_addr,n) //輸入

#define pcout(n) bit_addr(gpioc_odr_addr,n) //輸出

#define pcin(n) bit_addr(gpioc_idr_addr,n) //輸入

#define pdout(n) bit_addr(gpiod_odr_addr,n) //輸出

#define pdin(n) bit_addr(gpiod_idr_addr,n) //輸入

#define peout(n) bit_addr(gpioe_odr_addr,n) //輸出

#define pein(n) bit_addr(gpioe_idr_addr,n) //輸入

#define pfout(n) bit_addr(gpiof_odr_addr,n) //輸出

#define pfin(n) bit_addr(gpiof_idr_addr,n) //輸入

#define pgout(n) bit_addr(gpiog_odr_addr,n) //輸出

#define pgin(n) bit_addr(gpiog_idr_addr,n) //輸入

#define phout(n) bit_addr(gpioh_odr_addr,n) //輸出

#define phin(n) bit_addr(gpioh_idr_addr,n) //輸入

#define piout(n) bit_addr(gpioi_odr_addr,n) //輸出

#define piin(n) bit_addr(gpioi_idr_addr,n) //輸入

STM32 位帶應用

from cortex m3 支援了位操作後,可以使用普通的載入 儲存指令來對單一的位元進行讀寫。在 cm3 支援的位帶中,有兩個區中實現了位帶。其中乙個是 sram區的最低 1mb 範圍,0x20000000 0x200fffff sram 區中的最低 1mb 第二個則是片內外設區的最低 1mb範...

STM32型號與Contex m對應關係

cortex m核心m0,m0 m3,m4,m7之間的區別 來自於www.stmcu.com.cn high performance 高效能 mainstream 主流 ultra low power 低功耗 知識補貼 之所以arm公司會把cortex m分為這麼多系列,主要是針對不同的應用領域 下...

STM32中的位帶 bit band 操作

支援了位帶操作後,可以使用普通的載入 儲存指令來對單一的位元進行讀寫。在 cm3 中,有兩個區中實現了位帶。其中乙個是 sram 區的最低 1mb 範圍,第二個則是片內外設區的最低 1mb範圍。這兩個區中的位址除了可以像普通的 ram 一樣使用外,它們還都有自己的 位帶別名區 位帶別名區把每個位元膨...