STM32——GPIO(2)
生活随笔
收集整理的這篇文章主要介紹了
STM32——GPIO(2)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
STM32——GPIO
宗旨:技術的學習是有限的,分享的精神是無限的。
/* GPIO_InitTypeDef結構體 */ typedef enum {GPIO_Speed_10MHz = 1, //枚舉常量,值為 1,代表輸出速率最高為 10MHzGPIO_Speed_2MHz, //對不賦值的枚舉變量,自動加 1,此常量值為 2GPIO_Speed_50MHz //常量值為 3 } GPIOSpeed_TypeDef;typedef enum {GPIO_Mode_AIN = 0x0, //模擬輸入模式GPIO_Mode_IN_FLOATING = 0x04, //浮空輸入模式GPIO_Mode_IPD = 0x28, //下拉輸入模式GPIO_Mode_IPU = 0x48, //上拉輸入模式GPIO_Mode_Out_OD = 0x14, //開漏輸出模式GPIO_Mode_Out_PP = 0x10, //通用推挽輸出模式GPIO_Mode_AF_OD = 0x1C, //復用功能開漏輸出GPIO_Mode_AF_PP = 0x18 //復用功能推挽輸出 } GPIOMode_TypeDef;typedef struct {uint16_t GPIO_Pin; /* 指定要配置的引腳 */GPIOSpeed_TypeDef GPIO_Speed; /* 指定GPIO引腳輸出的最高頻率 */GPIOMode_TypeDef GPIO_Mode; /* 指定GPIO引腳工作狀態 */ } GPIO_InitTypeDef; /* 初始化GPIO -- GPIO_Init() */ void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct) {uint32_t currentmode = 0x00, currentpin = 0x00, pinpos = 0x00, pos = 0x00;uint32_t tmpreg = 0x00, pinmask = 0x00;/* 斷言,用于檢查輸入的參數是否正確 */assert_param(IS_GPIO_ALL_PERIPH(GPIOx));assert_param(IS_GPIO_MODE(GPIO_InitStruct->GPIO_Mode));assert_param(IS_GPIO_PIN(GPIO_InitStruct->GPIO_Pin));/*---------------------------- GPIO 的模式配置 -----------------------*//*把輸入參數 GPIO_Mode 的低四位暫存在 currentmode*/currentmode = ((uint32_t)GPIO_InitStruct -> GPIO_Mode) & ((uint32_t)0x0F);/*判斷是否為輸出模式,輸出模式,可輸入參數中輸出模式的 bit4 位都是 1*/if ((((uint32_t)GPIO_InitStruct -> GPIO_Mode) & ((uint32_t)0x10)) != 0x00){/* 檢查輸入參數 */assert_param(IS_GPIO_SPEED(GPIO_InitStruct->GPIO_Speed));/* 輸出模式,所以要配置 GPIO 的速率:00(輸入模式) 01(10MHz) 10(2MHz) 11 */currentmode |= (uint32_t)GPIO_InitStruct->GPIO_Speed;}/*----------------------------配置 GPIO 的 CRL 寄存器 ------------------------*//* 判斷要配置的是否為 pin0 ~~ pin7 */if (((uint32_t)GPIO_InitStruct -> GPIO_Pin & ((uint32_t)0x00FF)) != 0x00){/*備份原 CRL 寄存器的值*/tmpreg = GPIOx->CRL;/*循環,一個循環設置一個寄存器位*/for (pinpos = 0x00; pinpos < 0x08; pinpos++){/*pos 的值為 1 左移 pinpos 位*/pos = ((uint32_t)0x01) << pinpos;/* 令 pos 與輸入參數 GPIO_PIN 作位與運算,為下面的判斷作準備 */currentpin = (GPIO_InitStruct->GPIO_Pin) & pos;/*判斷,若 currentpin=pos,說明 GPIO_PIN 參數中含的第 pos 個引腳需要配置*/if (currentpin == pos){/*pos 的值左移兩位(乘以 4),因為寄存器中 4 個寄存器位配置一個引腳*/pos = pinpos << 2;/*以下兩個句子,把控制這個引腳的 4 個寄存器位清零,其它寄存器位不變*/pinmask = ((uint32_t)0x0F) << pos;tmpreg &= ~pinmask;/* 向寄存器寫入將要配置的引腳的模式 */tmpreg |= (currentmode << pos);/* 復位 GPIO 引腳的輸入輸出默認值*//*判斷是否為下拉輸入模式*/if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD){/*下拉輸入模式,引腳默認置 0,對 BRR 寄存器寫 1 可對引腳置 0*/GPIOx->BRR = (((uint32_t)0x01) << pinpos);}else{/*判斷是否為上拉輸入模式*/if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU){/*上拉輸入模式,引腳默認值為 1,對 BSRR 寄存器寫 1 可對引腳置 1*/GPIOx->BSRR = (((uint32_t)0x01) << pinpos);}}}}/*把前面處理后的暫存值寫入到 CRL 寄存器之中*/GPIOx->CRL = tmpreg;}/*---------------------------- 以下部分是對 CRH 寄存器配置的 -------------------------當要配置的引腳為 pin8 ~~ pin15 的時候,配置 CRH 寄存器, ------------------ -----這過程和配置 CRL 寄存器類似-------------------------------------------讀者可自行分析,看看自己是否了解了上述過程--^_^-----------*//* Configure the eight high port pins */if (GPIO_InitStruct->GPIO_Pin > 0x00FF){tmpreg = GPIOx->CRH;for (pinpos = 0x00; pinpos < 0x08; pinpos++){pos = (((uint32_t)0x01) << (pinpos + 0x08));/* Get the port pins position */currentpin = ((GPIO_InitStruct->GPIO_Pin) & pos);if (currentpin == pos){pos = pinpos << 2;/* Clear the corresponding high control register bits */pinmask = ((uint32_t)0x0F) << pos;tmpreg &= ~pinmask;/* Write the mode configuration in the corresponding bits */tmpreg |= (currentmode << pos);/* Reset the corresponding ODR bit */if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPD){GPIOx->BRR = (((uint32_t)0x01) << (pinpos + 0x08));}/* Set the corresponding ODR bit */if (GPIO_InitStruct->GPIO_Mode == GPIO_Mode_IPU){GPIOx->BSRR = (((uint32_t)0x01) << (pinpos + 0x08));}}}GPIOx->CRH = tmpreg;} }
總結
以上是生活随笔為你收集整理的STM32——GPIO(2)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 基于孪生网络的单目标跟踪持续汇总
- 下一篇: PAgP协议与LACP协议