1. 程式人生 > >玩轉X-CTR100 | 位帶操作-GPIO

玩轉X-CTR100 | 位帶操作-GPIO

宋體 www AC str #define *** io口初始化 art 訪問

技術分享圖片

更多塔克創新資訊歡迎登陸【塔克社區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