上次学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);
}
}