上次學STM32F103是在大二的暑假,學了一段時間之後也沒有項目做,漸漸地就轉向其他的方向,最近實習要用到STM32F407,就打算從頭學,但是一些基礎還在,並決定將學習的過程記錄一下,以備使用。
一.STM32F407ZGT6的GPIO資源介紹
STM32F407ZGT6
- 一共有7組IO口
- 每組IO口有16個IO
- 一共16X7=112個IO
外加2個PH0和PH1
一共114個IO口
二.GPIO的相關寄存器
一組IO口相關的寄存器有10個,也就是說,10個寄存器控制一組IO口;
一個端口模式寄存器(GPIOx_MODER)
一個端口輸出類型寄存器(GPIOx_OTYPER)
一個端口輸出速度寄存器(GPIOx_OSPEEDR)
一個端口上拉下拉寄存器(GPIOx_PUPDR)
一個端口輸入數據寄存器(GPIOx_IDR)
一個端口輸出數據寄存器(GPIOx_ODR)
一個端口置位/復位寄存器(GPIOx_BSRR)
一個端口配置鎖存寄存器(GPIOx_LCKR)
兩個復位功能寄存器(低位GPIOx_AFRL & GPIOx_AFRH)
三.GPIO的配置流程
//聲明一個GPIO結構體變量
GPIO_InitTypeDef GPIO_InitStructure;
delay_init(84);
//使能GPIO所在的總線的時鐘
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
//定義該結構體
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9 |GPIO_Pin_10;//使用的IO口 (總共有16個IO口)
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //設置IO的模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; //100MHz
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //推輓
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
//初始化該結構體
GPIO_Init(GPIOF,&GPIO_InitStructure);
分析:
(1) GPIO的重要結構體,對其進行賦值
typedef struct
{
uint32_t GPIO_Pin; /*!< Specifies the GPIO pins to be configured.
This parameter can be any value of @ref GPIO_pins_define */
GPIOMode_TypeDef GPIO_Mode; /*!< Specifies the operating mode for the selected pins.
This parameter can be a value of @ref GPIOMode_TypeDef */
GPIOSpeed_TypeDef GPIO_Speed; /*!< Specifies the speed for the selected pins.
This parameter can be a value of @ref GPIOSpeed_TypeDef */
GPIOOType_TypeDef GPIO_OType; /*!< Specifies the operating output type for the selected pins.
This parameter can be a value of @ref GPIOOType_TypeDef */
GPIOPuPd_TypeDef GPIO_PuPd; /*!< Specifies the operating Pull-up/Pull down for the selected pins.
This parameter can be a value of @ref GPIOPuPd_TypeDef */
}GPIO_InitTypeDef;
( 1) GPIO_Mode_AIN 模擬輸入
( 2) GPIO_Mode_IN_FLOATING 浮空輸入
( 3) GPIO_Mode_IPD 下拉輸入
( 4) GPIO_Mode_IPU 上拉輸入
( 5) GPIO_Mode_Out_OD 開漏輸出
( 6) GPIO_Mode_Out_PP 推輓輸出
( 7) GPIO_Mode_AF_OD 複用開漏輸出
( 8) GPIO_Mode_AF_PP 複用推輓輸出
8種配置模式的使用場景
二.GPIO的時鐘使能
時鐘使能的函數在stm32f4xx_rcc.h中,根據上圖,外設在哪一條時鐘總線上進行函數選擇,所以GPIOF在AHB1總線上,此時選擇的函數爲:
RCC_AHB1PeriphClockCmd();
四.GPIO相關重要函數
重要函數:
1個初始化函數:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
2個讀取輸入電平函數:
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
2個讀取輸出電平函數:
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
4個設置輸出電平函數:
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_WriteBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, BitAction BitVal);
void GPIO_Write(GPIO_TypeDef* GPIOx, uint16_t PortVal);
因此此時就可以用,以下函數進行點亮,熄滅LED了
void GPIO_SetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
void GPIO_ResetBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
具體代碼如下:
int main(void)
{
//聲明一個GPIO結構體變量
GPIO_InitTypeDef GPIO_InitStructure;
delay_init(84);
//GPIO時鐘使能
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF, ENABLE);
GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9 |GPIO_Pin_10;//PIN9 PIN10 分別連接LED0 LED1
GPIO_InitStructure.GPIO_Mode=GPIO_Mode_OUT; //設置GPIO爲輸出模式
GPIO_InitStructure.GPIO_Speed=GPIO_Speed_100MHz; //100MHz的時鐘
GPIO_InitStructure.GPIO_OType=GPIO_OType_PP; //Í推輓輸出
GPIO_InitStructure.GPIO_PuPd=GPIO_PuPd_UP; //上拉
GPIO_Init(GPIOF,&GPIO_InitStructure);
while(1)
{
GPIO_SetBits(GPIOF,GPIO_Pin_9 |GPIO_Pin_10);//同時點亮LED
delay_ms(1000);
GPIO_ResetBits(GPIOF,GPIO_Pin_9 |GPIO_Pin_10);//同時熄滅LED
delay_ms(1000);
}
}