【STM32】Gpio通用输入输出学习笔记(跑马灯、蜂鸣器和按键输入实验)


一、前言

1.1 开发环境

①Keil MDK V5.38a
②STM32CubemxV6.10.0
③正点原子战舰板(STM32F103ZET6)
④高速DAP仿真器
⑤MCU Package V1.8.5

1.2 GPIO电路原理

GPIO(General-purpose input/output,通用输入输出),通过与外围电路的直接连接,达到获取外围电路电平状态(输入),或者控制外围电路电平状态(输出)。GPIO的电路原理框图如下所示:
在这里插入图片描述
由上图可知,GPIO存在3种输入状态:模拟/复用/普通 + 上/下/浮空输入,将输入上/下拉的目的,在于指定未连接外围电路时的输入电平状态。上拉表示在未连接外围电路时读取到IO输入电平应为高;下拉表示在未连接外围电路时读取到IO输入电平应为低,浮空则表示不关心此电平状态。
GPIO存在2种输出状态:普通/复用 + 推挽/开漏输出,将输出推挽/开漏的目的,在于指定输出高电平的强度。推挽输出时的高电平强度大,相当于把I/O直接连到了电源,此时若将I/O连接到GND将会发生短路,大概率会烧毁I/O,通常在控制外围电路时使用此功能(例:点亮/熄灭LED);开漏输出时需要通过外围电路的上拉才能输出高电平,此时若将I/O连接到GND不会发生短路现象,通常在仅需接收外围电路传输信息时使用此功能。

1.3 板卡电路原理

1.3.1 按键电路原理

由下图可知,Key0、Key1和Key2会在按键按下时,将对应的Gpio管脚连接到Gnd,即将Gpio管脚拉低,当按键没有按下时Gpio管脚应该默认为高电平,用来区分按键按下和未按下两种状态;所以需要使能Gpio管脚的输入模式,并配置Gpio管脚上拉。同理Wkup连接的Gpio管脚应该配置为输入模式,并配置Gpio管脚下拉。
在这里插入图片描述

1.3.2 Led电路原理

由下图可知,当Gpio管脚输出低电平时,会在Led的两端产生电压差,从而驱动Led点亮,当Gpio管脚输出高电平时,会在Led的两端没有电压差,Led熄灭;所以需要使能Gpio管脚为输出模式,并配置Gpio管脚上拉。
在这里插入图片描述

1.3.3 Beep电路原理

由下图可知,当Gpio管脚输出高电平时,会在导通三极管,同时Beep的两端会产生电压差,从而驱动Beep鸣叫,当Gpio管脚输出低电平时,会在关断三极管,同时Beep的两端没有电压差,Beep停止鸣叫;所以需要使能Gpio管脚为输出模式,并配置Gpio管脚下拉。
在这里插入图片描述


二、功能实现

2.1 配置STM32Cubemx工程

1、配置MCU调试功能(PS:若不配置该参数可能出现程序下载一次后,再次下载失败的情况)
在这里插入图片描述
根据实际调试器与MCU引脚的连接数量选择调试参数,通常调试器除了VCC和GND外,只有2个管脚,需要选择Serial Wire。

2、配置连接LED1的GPIO管脚(鼠标左键选择GPIO_Output即可,鼠标右键选择Enter User Label即可设置GPIO管脚名称)
在这里插入图片描述

3、配置连接BEEP的GPIO管脚
在这里插入图片描述

4、配置连接KEY2的GPIO管脚
在这里插入图片描述

5、配置连接KEY1的GPIO管脚

在这里插入图片描述

6、配置连接KEY0的GPIO管脚
在这里插入图片描述

7、配置MCU时钟树,默认使用外部时钟源,并配置系统时钟为72MHz
在这里插入图片描述
在这里插入图片描述

8、生成Keil MDK工程
在这里插入图片描述
若不勾选"Generate ......",则生成的所有的驱动代码都会在main.c中;勾选后生成的驱动代码将存在于各自的驱动文件。
在这里插入图片描述
在这里插入图片描述

2.2 Keil MDK工程编码

2.2.1 按键驱动代码

Key.c:

#include "Key.h"

static GPIO_TypeDef *Key_Gpio_Port[4] = {
    GPIOE, GPIOE, GPIOE, GPIOA };
static uint32_t Key_Gpio_Pinx[4] = {
    KEY0_Pin, KEY1_Pin, KEY2_Pin, WKUP_Pin };

/*
 * @brief 初始化独立按键
 * @param Key_Index:独立按键索引号
*/
void Key_Init(KEY_INDEX_E Key_Index)
{
   
    GPIO_InitTypeDef GPIO_InitStruct = {
   0};

    /* 使能Key管脚端口时钟 */
    if((KEY_INDEX_0 == Key_Index) || \
       (KEY_INDEX_1 == Key_Index) || \
       (KEY_INDEX_2 == Key_Index))
    {
   
        __HAL_RCC_GPIOE_CLK_ENABLE();
        GPIO_InitStruct.Pull = GPIO_PULLUP;
    }
    else
    {
   
        __HAL_RCC_GPIOA_CLK_ENABLE();
        GPIO_InitStruct.Pull = GPIO_PULLDOWN;
    }

    /* 设置Key管脚初始化参数并完成初始化 */
    GPIO_InitStruct.Pin = Key_Gpio_Pinx[Key_Index];
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(Key_Gpio_Port[Key_Index], &GPIO_InitStruct);
}

/*
 * @brief 初始化独立按键
 * @param Key_Index:独立按键索引号
 * @retval 独立按键当前状态
*/
KEY_STATUS_E Key_Get_Status(KEY_INDEX_E Key_Index)
{
   
    GPIO_PinState pin_status = GPIO_PIN_RESET
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值