1、GPIO功能概述
(1)概述
STM32F407ZG有8个16引脚的GPIO端口。还有一个12引脚的PI端口。
GPIO端口都连接在AHB1总线上,自高时钟频率168MHz。
GPIO引脚能承受5V电压.
每个GPIO端口有4个32位寄存器,用于配置GPIO引脚的工作模式;1个32位输入数据寄存器和1个32位输出数据寄存器,还有复用功能选择寄存器等。
(2)GPIO引脚可以配置多种工作模式:
输入浮空(input floating):作为GPIO输入引脚,不使用上拉或下拉电阻。
输入上拉(input pull-up),作为GPIO输入引脚,使用内部上拉电阻。当没有外部输入时,引脚输入电平为高电平。
输入下拉(input pull-down):作为GPIO输入引脚,使用内部下拉电阻。当没有外部输入时,引脚输入电平为低电平。
模拟(analog):作为GPIO模拟引脚,用于ADC输入引脚或DAC输出引脚。
具有上拉或下拉的开漏输出(output open-drain):如果不使用上拉或下拉电阻,开漏输出1时引脚为高阻态,输出0时引脚是低电平。这种模式可用于共用总线的信号。
具有上拉或下拉的推挽输出(output push-pull):如果不使用上拉或下拉电阻,推挽输出1时引脚是高电平,输出0时引脚为低电平。若需要增强引脚输出驱动能力,就可以使用上拉。例如需要GPIO引脚输出高电平点亮LED时。
具有上拉或下拉的复用功能推挽(afternate function push-pull)。
具有上拉或下拉的复用功能开漏(afternate function open-drain)。
2、初始化代码
(1)GPIO工作模式
typedef enum
{
GPIO_Mode_IN = 0x00, /*!< GPIO Input Mode */
GPIO_Mode_OUT = 0x01, /*!< GPIO Output Mode */
GPIO_Mode_AF = 0x02, /*!< GPIO Alternate function Mode */
GPIO_Mode_AN = 0x03 /*!< GPIO Analog Mode */
}GPIOMode_TypeDef;
(2)GPIO输出频率
typedef enum
{
GPIO_Low_Speed = 0x00, /*!< Low speed */
GPIO_Medium_Speed = 0x01, /*!< Medium speed */
GPIO_Fast_Speed = 0x02, /*!< Fast speed */
GPIO_High_Speed = 0x03 /*!< High speed */
}GPIOSpeed_TypeDef;
#define GPIO_Speed_2MHz GPIO_Low_Speed
#define GPIO_Speed_25MHz GPIO_Medium_Speed
#define GPIO_Speed_50MHz GPIO_Fast_Speed
#define GPIO_Speed_100MHz GPIO_High_Speed
(3)GPIO输出模式
typedef enum
{
GPIO_OType_PP = 0x00,
GPIO_OType_OD = 0x01
}GPIOOType_TypeDef;
(4)GPIO上拉下拉设置
typedef enum
{
GPIO_PuPd_NOPULL = 0x00,
GPIO_PuPd_UP = 0x01,
GPIO_PuPd_DOWN = 0x02
}GPIOPuPd_TypeDef;
(5)GPIO位设置
typedef enum
{
Bit_RESET = 0,
Bit_SET
}BitAction;
(6)GPIO初始化结构体
typedef struct
{
uint32_t GPIO_Pin;
GPIOMode_TypeDef GPIO_Mode;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOOType_TypeDef GPIO_OType;
GPIOPuPd_TypeDef GPIO_PuPd;
}GPIO_InitTypeDef;
3、库函数
(1)去初始化函数/默认模式
void GPIO_DeInit(GPIO_TypeDef* GPIOx);
(2)初始化函数
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_StructInit(GPIO_InitTypeDef* GPIO_InitStruct);
void GPIO_PinLockConfig(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
(3)GPIO读写函数
uint8_t GPIO_ReadInputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadInputData(GPIO_TypeDef* GPIOx);
uint8_t GPIO_ReadOutputDataBit(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
uint16_t GPIO_ReadOutputData(GPIO_TypeDef* GPIOx);
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);
void GPIO_ToggleBits(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);
(4)时钟使能函数
void RCC_AHB1PeriphClockCmd(uint32_t RCC_AHB1Periph, FunctionalState NewState);
STM32F407ZGT6的GPIO资源都是挂载在AHB1上的,所以时钟使能函数使用RCC_AHB1PeriphClockCmd()。
4、例程
(1)电路资源
(2)端口资源
用户标签 | 引脚名称 | 引脚功能 | GPIO模式 | 上拉或下拉 |
---|---|---|---|---|
LED1 | PF9 | GPIO_Output | 推挽输出 | 无 |
LED2 | PF10 | GPIO_Output | 推挽输出 | 无 |
KeyRight | PE2 | GPIO_Input | 输入 | 上拉 |
KeyDown | PE3 | GPIO_Input | 输入 | 上拉 |
KeyLeft4 | PE4 | GPIO_Input | 输入 | 上拉 |
KeyUp | PA0 | GPIO_Input | 输入 | 下拉 |
(3)例程
#include "gpio_keyled.h"
void led_key_init()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOF,ENABLE);
GPIO_InitStructure.GPIO_Pin = Led1_Pin | Led2_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOF,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KeyDown_Pin | KeyLeft_Pin | KeyRight_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOE,&GPIO_InitStructure);
GPIO_InitStructure.GPIO_Pin = KeyUp_Pin;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_DOWN;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;
GPIO_Init(GPIOA,&GPIO_InitStructure);
}
void led1_on()
{
GPIO_WriteBit(GPIOF,Led1_Pin,Bit_RESET);
}
void led2_on()
{
GPIO_WriteBit(GPIOF,Led2_Pin,Bit_RESET);
}
void led1_off()
{
GPIO_WriteBit(GPIOF,Led1_Pin,Bit_SET);
}
void led2_off()
{
GPIO_WriteBit(GPIOF,Led2_Pin,Bit_SET);
}
KEYS ScanKey()
{
KEYS key = KeyNone;
if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyRight_Pin))
{
Delay2();
if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyRight_Pin))
key = KeyRight;
}
if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyLeft_Pin))
{
Delay2();
if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyLeft_Pin))
key = KeyLeft;
}
if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyDown_Pin))
{
Delay2();
if(Bit_RESET == GPIO_ReadInputDataBit(GPIOE,KeyDown_Pin))
key = KeyDown;
}
if(Bit_SET == GPIO_ReadInputDataBit(GPIOA,KeyUp_Pin))
{
Delay2();
if(Bit_SET == GPIO_ReadInputDataBit(GPIOA,KeyUp_Pin))
key = KeyUp;
}
return key;
}
5、库使用流程
6、注意事项
-
AHB1的时钟使能需要写在GPIO口初始化之前。
-
标准库中的 SystemInit 函数把 STM32 芯片的系统时钟设置成了 168MHz,即此时 AHB1 时钟频率为 168MHz,APB2 为 84MHz,APB1 为 42MHz。