开始之前呢先祝大家圣诞节快乐,同时参加明天的研究生考试的同学们一战成"硕",接下来我就直奔主题了。
今天我要通过库函数操作stm32f407上的按键实现控制LED小灯以及蜂鸣器,实现的功能如下:
- KEY0键控制LED0的亮灭
- KEY1键控制LED1的亮灭
- KEY2键同时控制控制LED0和LED1的亮灭转换
- WK_UP键控制蜂鸣器
这篇文章同时会涉及到LED和蜂鸣器,相当于是对前两次的学习进行一个复习,可能在前两篇文章中没有考虑到的细节今天都会尽量考虑进去,希望这篇文章可以更好的帮助到大家对GPIO的理解,废话不多说,下面正式开始。
LED的初始化配置
想要点亮LED,首先我们需要确定LED在stm32f407开发板上的硬件电路连接,如下图所示:
从图上可以看出,两个LED属于共阳极连接,也就是说,当GPIO口输出高电平时,LED熄灭,当GPIO口输出低电平时,LED点亮,那么只需要配置好GPIO的输出,即可实现LED的亮灭,所以,我们还得知道控制LED的GPIO口是哪一个,毕竟stm32f4有70个用于控制LED的GPIO口;
我们可以从从上图中看到,控制LED0的是GPIOF_9,控制LED1的是GPIOF_10,同时我们还可以看到GPIOF_8是用来控制蜂鸣器(BEEP)的。知道了LED的硬件连接后,接下来就可以开始通过库函数配置我们的GPIO了。
通过库函数来配置GPIO,我们需要用到的库函数是GPIO_Init,对于这个函数,有如下的说明:
void GPIO_Init(GPIO_TypeDef* GPIOx, GPIO_InitTypeDef* GPIO_InitStruct);
从GPIO_Init的函数原型可以看出,需要用到两个参数,这两个参数分别是:
- GPIO_TypeDef* GPIOx:用来指明配置的GPIO是7组GPIO中的哪一组,这里控制LED用到的是GPIOF,所以该参数只需填入宏定义GPIOF即可
- GPIO_InitTypeDef* GPIO_InitStruct:从参数名字就可以知道这个参数是一个结构体的地址,所以在这里为了更好的说明,我们自定义一个结构体:
GPIO_InitTypeDef led_gpio;
该结构体的成员呢有以下几个:
uint32_t GPIO_Pin; //该参数对应的是某组GPIO中的某一个,毕竟一组GPIO有16个GPIO引脚
//就如前面说到控制LED0的GPIO口是GPIOF_9;控制LED1的GPIO口是GPIOF_10;
/*下面这几个参数我就放到正文里细说吧*/
GPIOMode_TypeDef GPIO_Mode;
GPIOSpeed_TypeDef GPIO_Speed;
GPIOOType_TypeDef GPIO_OType;
GPIOPuPd_TypeDef GPIO_PuPd;
GPIO_InitStruct的后面4个参数就是用于配置GPIO模式寄存器的,我在第一篇文章里说到,配置GPIO的模式需要用到4个寄存器,如果你没有看过我的第一篇文章的话,没有关系,我再来详细的说明一下:这里说到的寄存器分别是:
- GPIOx_MODER:GPIO端口模式寄存器
- GPIOx_OSPEEDR:GPIO端口输出速度寄存器
- GPIOx_OTYPER:GPIO端口输出类型寄存器
- GPIOx_PUPDR:GPIO端口上拉/下拉寄存器
分别对应着GPIO_InitStruct的后四个成员
下面我就来具体说说要控制LED,这4个GPIOF分别需要怎么配置:
>GPIOF_MODER
GPIOF_MODER寄存器可选的配置分别有:输入模式(复位状态),通用输出模式,复用功能模式,模拟模式,这里很容易想到,我们要向控制LED0,需要通过GPIOF_9输出高电平或低电平,所以毫无疑问我们需要将GPIOF_MODER寄存器配置成通用输出模式,对于该寄存器的四种模式在库函数中有如下的说明:
GPIO_Mode_IN = 0x00, /*输入模式*/
GPIO_Mode_OUT = 0x01, /*通用输出模式*/
GPIO_Mode_AF = 0x02, /*复用功能模式*/
GPIO_Mode_AN = 0x03 /*模拟模式*/
在此我们只需选择GPIO_Mode_OUT即可,一句话代码如下:
led_gpio.GPIO_Mode = GPIO_Mode_OUT;
>GPIOF_OSPEEDR
GPIOF_OSPEEDR寄存器可选的配置分别有:2MHz,25MHz,50MHz,100MHz,在此我们选择100MHz的端口输出速度(对于速度的选择我也不太明白会有啥影响,或者说选择的标准是啥,希望明白的大佬可以在评论区里解答下,非常感谢),对于这4中选择在库函数中有如下定义:
#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
所以一句话代码如下:
led_gpio.GPIO_Speed = GPIO_Speed_100MHz;
>GPIOx_OTYPER
GPIOF_OSPEEDR寄存器可选的配置分别有:推挽输出,开漏输出,在此我们选择推挽输出模式(同样不明白这两种模式的区别以及选择标准,希望有大佬可以在评论区解答下,感谢),对于这两种输出模式在库函数中有如下的定义:
typedef enum
{
GPIO_OType_PP = 0x00, //推挽输出
GPIO_OType_OD =