STM32 IO口位帶操作

2021-09-07 06:25:14 字數 4555 閱讀 6781

m4中有4gb的訪問空間,訪問空間有兩個比較重要的位址,暫存器對映位址,又叫別名位址(範圍32mb),暫存器位址(範圍1mb,固定的)

使用庫函式對io引腳操作比較費時間,需要進行現場保護和現場恢復操作,不能一步到位。使用位帶操作能夠一步到位,方便快捷。

每個埠都有對應的暫存器位址,檢視庫函式可以看到對暫存器的的操作。

如:

void gpio_togglebits(gpio_typedef* gpiox, uint16_t gpio_pin)

gpiox->odr ^= gpio_pin; 就是對odr暫存器的操作,通過右鍵 go to definition of 'odr』可以追尋到暫存器所在的結構體,注釋中有說明該暫存器在結構體中的偏移量,odr的位址是結構體首位址偏移0x14.

巨集定義 gpiof 實際上是乙個位址,通過右鍵 go to definition of …可以逐步追尋到埠的暫存器位址

#define gpiof               ((gpio_typedef *) gpiof_base)

#define gpiof_base (ahb1periph_base + 0x1400)

#define ahb1periph_base (periph_base + 0x00020000)

#define periph_base ((uint32_t)0x40000000) /*!< peripheral base address in the alias region

所以gpiof的位址為

gpiof = 0x40000000 + 0x00020000 + 0x1400 = 0x40021400

gpiof的odr暫存器位址還需要偏移0x14個位元組,所以

gpiof->odr = gpiof + 0x14 = 0x40021414

gpiof位址是暫存器位址,將該位址轉換為暫存器對映位址,可以實現埠的位操作,即直接對引腳操作。

轉換公式

aliasaddr = 0x42000000 + (a - 0x40000000) * 8 * 4 + n * 4
說明:0x42000000是外設位帶別名區的起始位址,0x40000000是外設位帶區的起始位址,a - 0x40000000指該位元前面有多少個位元組,乙個位元組有8位,所以8,乙個位膨脹後是4位元組,所以4,a表示埠位址,n表示埠的引腳號。引腳號膨脹後4個位元組,所以也*4。

以gpiof9為例,根據公式可以得出gpiof9的對映位址為

gpiof9_aliasaddr = 0x42000000 + (gpiof - 0x40000000) * 8 * 4 + 9 * 4

= 0x42000000 + (0x40021414 - 0x40000000) * 8 * 4 + 9 * 4

示例,用位帶操作實現4個led的控制

說明:4個led燈對應的引腳為gpiof9,gpiof10,gpioe13,gpioe14

/*該**需要對應的庫函式支撐,需要提前新增庫函式*/

#include "stm32f4xx.h"

static gpio_inittypedef gpio_initstructure; //gpio初始化結構體

/*下列為延時函式** 參考文章 [stm32系統定時器systick,delay的精確編寫](

void delay_ms(uint32_t n)

}/*延時函式結束*/

int main(void)

}//結束

在開發過程中,可以將比較常用到的io口的位帶操作封裝成乙個標頭檔案,在正確配置對應的io口後,能夠簡便的對引腳進行操作。

/***來自粵嵌--溫老師*/

#ifndef __sys_h__

#define __sys_h__

//位帶操作,實現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) //輸入

#endif

STM32 IO口工作模式

一 推挽輸出 可以輸出高 低電平,連線數字器件 推挽結構一般是指兩個三極體分別受兩個互補訊號的控制,總是在乙個三極體導通的時候另乙個截止。高低電平由ic的電源決定。推挽電路是兩個引數相同的三極體或mosfet,以推挽方式存在於電路中,各負責正負半周的波形放大任務,電路工作時,兩隻對稱的功率開關管每次...

STM32 IO口模式介紹

gpio mode ain 模擬輸入模式 gpio mode in floating 浮空輸入模式 gpio mode ipd 下拉輸入模式 gpio mode ipu 上拉輸入模式 gpio mode out od 通用開漏輸出模式 gpio mode out pp 通用推挽輸出模式 gpio m...

stm32 io 口配置和使用

對於stm32 gpio的配置種類有8種之多 1 gpio mode ain 模擬輸入 2 gpio mode in floating 浮空輸入 3 gpio mode ipd 下拉輸入 4 gpio mode ipu 上拉輸入 5 gpio mode out od 開漏輸出 6 gpio mode...