玩轉X-CTR100 | 位帶操作-GPIO
更多塔克創新資訊歡迎登陸【塔克社區www.xtark.cn 】【塔克博客www.cnblogs.com/xtark/ 】
STM32F4位帶概念,及位帶的GPIO操作實踐應用。
原理介紹
51單片機相信各位都用過,假設P1.1的IO口上掛了一個LED,那麽你單獨對LED的操作就是P1.1 = 0或P1.1 = 1,註意,是你可以單獨的對P1端的第一個IO口進行操作,然而STM32是不允許這樣做的,那麽為了像51單片機一樣能夠單獨的對某個端的某一個IO單獨操作,就引入了位帶操作這樣的概念,簡單說就是為了去單獨操作32裏面PA端的第1個IO口,所以才有了位帶這樣的操作機制。
位帶操作就是把每個比特膨脹為一個32位的字,當訪問這些字的時候就達到了訪問比特的目的,比如說GPIO的ODR寄存器有32個位,那麽可以映射到32個地址上,我們去問這32個地址就達到訪問32個比特的目的。這樣我們往某個地址寫1 就達到往對應比特位寫1 的目的,同樣往某個地址寫0 就達到往對應的比特位寫0 的目的。
具體實現方法略,本節重點介紹位帶應用方法。
軟件生態
擴展文件
X-SOFT軟件生態,X-API擴展文件如下。
ax_bitband_gpio.h——位帶操作頭文件
接口函數
位帶相關操作在ax_bitband_gpio.h文件中做了如下宏定義。
//******** 位帶操作,實現類51GPIO控制******** //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口操作 #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) //輸入 |
例程設計
通過位帶操作實現了GPIO的輸入輸出操作,利用SW撥碼開關控制LED燈的開關。
硬件說明
硬件資源:
- 串口UART1
- LED燈
- SW 撥碼開關
軟件說明
軟件通過主程序實現,,AX_Init()函數已完成IO口初始化,SW和LED燈接口位帶定義如下。
//LED端口定義 #define GPIO_LED_G PDout(11) // 綠色LED #define GPIO_LED_R PDout(10) // 紅色LED
//SW撥碼開關端口定義 #define GPIO_SW1 PEin(15) //撥碼開關1 #define GPIO_SW2 PEin(10) //撥碼開關2 |
主程序代碼如下。
int main(void) { //X-CTR100初始化 AX_Init(115200); printf("***X-CTR100 位帶操作-GPIO例程***\r\n\r\n");
//位帶控制LED輸出 GPIO_LED_G = 0; GPIO_LED_R = 0; AX_Delayms(500); GPIO_LED_G = 1; GPIO_LED_R = 1; AX_Delayms(500);
//循環檢測,通過撥碼開關控制LED while (1) { //獲取撥碼開關1狀態,控制LED綠燈 if(GPIO_SW1 == 1) GPIO_LED_G = 1; else GPIO_LED_G = 0;
//獲取撥碼開關2狀態,控制LED紅燈 if(GPIO_SW2 == 1) GPIO_LED_R = 1; else GPIO_LED_R = 0;
AX_Delayms(200);
} } |
實現效果
撥動SW1控制綠色LED燈亮滅,撥動SW2控制紅色LED燈。
玩轉X-CTR100 | 位帶操作-GPIO