嵌入式---GPIO配置
1.配置流程
(1)時鐘使能
(2)結構體賦值
(3)寫入暫存器
2.配置說明
2.1需要先明確使能的時鐘屬於哪一組GPIO,然後呼叫HAL函式庫中的使能函式進行使能。
__GPIOA_CLK_ENABLE(); //使能GPIOA時鐘
2.2結構體賦值
在HAL庫中stm32f7xx_hal.gpio.h檔案中,可以看到GPIO_InitTypeDef結構體定義,如下:
typedef struct { uint32_t Pin; //指定 IO 口 uint32_t Mode; //模式設定 uint32_t Pull; //上下拉設定 uint32_t Speed; //速度設定 uint32_t Alternate;//複用對映配置 }GPIO_InitTypeDef;
賦值說明
(1)Pin:指定IO口
(2)Mode:模式設定,輸入輸出模式一共有以下8種
GPIO_Mode_AIN /*模擬輸入,特點:應用ADC模擬輸入,或者低功耗下省電*/ GPIO_Mode_IN_FLOATING /*浮空輸入,特點:浮空輸入一般多用於外部按鍵輸入,IO的電平狀態是不確定 的,完全由外部輸入決定,如果在該引腳懸空的情況下,讀取該埠的電平是不確定的*/ GPIO_Mode_IPD /*下拉輸入,特點:預設低電平*/ GPIO_Mode_IPU /*上拉輸入,特點:預設高電平*/ GPIO_Mode_Out_OD /*開漏輸出,特點:IO輸出0接GND,IO輸出1,懸空;接上拉電阻才可以輸出高 電平,上升沿速度慢。適合於做電流型的驅動,其吸收電流的能力相對強(一般20ma以內);可以將多個開漏輸出的 Pin,連線到一條線上。通過一隻上拉電阻,在不增加任何器件的情況下,形成“與邏輯”關係。*/ GPIO_Mode_Out_PP /*推輓輸出,特點:可以輸出高,低電平,導通損耗小,效率高,讀輸入值是未 知的*/ GPIO_Mode_AF_OD /*複用開漏輸出,特點:可以理解為GPIO口被用作第二功能時的配置情況(即並 非作為通用IO口使用),如:片內外設功能(TX1,MOSI,MISO.SCK.SS)*/ GPIO_Mode_AF_PP /*複用推輓輸出,特點:可以理解為GPIO口被用作第二功能時的配置情況(即並 非作為通用IO口使用),如:片內外設功能(I2C的SCL,SDA)*/
(3)Pull:作為輸入引腳時指定
(4)Speed:引腳速度,GPIO的引腳速度跟應用相匹配,速度配置越高,噪聲越大,功耗越大。
高頻的驅動電路,噪聲也高,當不需要高的輸出頻率時,請選用低頻驅動電路,這樣非常有利於提高系統的EMI效能。當然如果要輸出較高頻率的訊號,但卻選用了較低頻率的驅動模組,很可能會得到失真的輸出訊號。
① USART串列埠,若最大波特率只需115.2k,那用2M的速度就夠了,既省電也噪聲小。
② I2C介面,若使用400k波特率,若想把餘量留大些,可以選用10M的GPIO引腳速度。
③ SPI介面,若使用18M或9M波特率,需要選用50M的GPIO的引腳速度。 (5)Alternate:引腳複用對映
①複用功能:內建外設是與I/O口共用引出管腳(不同的功能對應同一管腳)
STM32 所有內建外設的外部引腳都是與標準GPIO引腳複用的,如果有多個複用功能模組對應同一個引腳,只能使能其中之一,其它模組保持非使能狀態。
②重對映功能:複用功能的引出腳可以通過重對映,從不同的I/O管腳引出,即複用功 能的引出腳位是可通過程式改變到其他的引腳上!
直接好處:PCB電路板的設計人員可以在需要的情況下,不必把某些訊號在板上繞一大圈完成聯接,方便了PCB的設計同時潛在地減少了訊號的交叉干擾。
如:USART1: 0: 沒有重映像(TX/PA9,RX/PA10); 1: 重映像(TX/PB6,RX/PB7)。
通過參照datasheet上的引腳對映說明,來配置相應複用功能。
2.3寫入暫存器
在結構體賦值完成後,呼叫HAL庫中函式將結構體中的值寫入到暫存器。
HAL_GPIO_Init(GPIOG,&GPIO_Initure); //寫入暫存器
2.4舉例
//普通輸出引腳
void GPIO_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__GPIOA_CLK_ENABLE();//開啟GPIOA時鐘
GPIO_Initure.Pin = GPIO_PIN_10; //PA10
GPIO_Initure.Mode = GPIO_MODE_OUTPUT_PP; //推輓輸出
GPIO_Initure.Pull = GPIO_PULLUP; //上拉
GPIO_Initure.Speed = GPIO_SPEED_HIGH; //高速
HAL_GPIO_Init(GPIOA, &GPIO_Initure); //初始化
}
//SPI複用
void SPI1_Gpio_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__GPIOG_CLK_ENABLE();//開啟GPIOG時鐘
GPIO_Initure.Pin=SPI1_MISO_PIN;
GPIO_Initure.Mode=GPIO_MODE_AF_PP; //複用推輓輸出
GPIO_Initure.Pull=GPIO_NOPULL; //無上下拉
GPIO_Initure.Speed=GPIO_SPEED_FAST; //快速
GPIO_Initure.Alternate=GPIO_AF5_SPI1; //複用為SPI1
HAL_GPIO_Init(GPIOG,&GPIO_Initure); //初始化
}
//外部中斷
void EXIT_init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOD_CLK_ENABLE(); //開啟GPIOD時鐘
GPIO_Initure.Pin = SPI1_INTR_PIN; //PD8
GPIO_Initure.Speed = GPIO_SPEED_HIGH; //高速
GPIO_Initure.Mode = GPIO_MODE_IT_RISING; //上升沿沿觸發
GPIO_Initure.Pull = GPIO_PULLDOWN; //下拉
HAL_GPIO_Init(SPI1_INTR_PORT,&GPIO_Initure);
//中斷線0
//HAL_NVIC_SetPriority(EXTI9_5_IRQn,2,0); //搶佔優先順序為2,子優先順序為0
HAL_NVIC_EnableIRQ(EXTI9_5_IRQn); //使能中斷線0
}