1. 程式人生 > >嵌入式---GPIO配置

嵌入式---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
}