打印
[其他ST产品]

STM32Cube HAL库——GPIO介绍及应用(按键控制灯的闪烁)

[复制链接]
836|25
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
GPIO, IO, gp, pi, ST
【STM32】STM32Cube HAL库——GPIO介绍及应用(按键控制灯的闪烁)
GPIO输入输出
GPIO(General Purpose Input-Output)引脚用作一般的数字输入输出引脚。其内部有双向保护二极管,有可配置是否使用的上拉和下拉电阻。
一个GPIO口的16个引脚的功能可以单独设置,每个引脚的输入输出数据可以单独读取或输出。
一共有四种模式,如下(只需要懂输入浮空、上拉、下拉,推挽输出就够用了,想要进一步了解可以查看GPIO输入输出模式原理)。




使用特权

评论回复
沙发
自动化陈稳|  楼主 | 2023-12-27 16:13 | 只看该作者
作为GPIO输入
(1)输入浮空(Input floating),并且不使用上拉或下拉。
(2)输入上拉(Input pull-up),使用内部上拉电阻,引脚外部无输入时读取的引脚输入电平为高电平。
(3)输入下拉(Input pull-down),使用内部下拉电阻,引脚外部无输入时读取的引脚输入电平为低电平。
举例: 以下是一个按键输入电路图。

使用特权

评论回复
板凳
自动化陈稳|  楼主 | 2023-12-27 16:14 | 只看该作者
通过电路图可以知道,想要使得按键有用(即当按键按下时相应的引脚电平高低发生变化),PA0脚必须保持低电平(0V),PE4、PE3、PE2必须保持高电平(3.3V)。四个按键都没有按下时,四个引脚的电平发生变化。由此确定GPIO输入的上拉和下拉。
即:PA0:下拉输入,未按下时,PA0输入为0,按下后PA0输入为1
PE2、PE3、PE4:上拉输入,未按下时,输入为1,按下后输入为0

使用特权

评论回复
地板
自动化陈稳|  楼主 | 2023-12-27 16:14 | 只看该作者
作为GPIO输出
(1)具有上拉或下拉的开漏输出(Output open-drain)。如果没有上拉或下拉,开漏输出1时引脚是高阻态,输出0时引脚是低电平,这种模式可用于共用总线的信号。

使用特权

评论回复
5
自动化陈稳|  楼主 | 2023-12-27 16:14 | 只看该作者
(2)具有上拉或下拉的推挽输出(Output push-pull)。如果没有上拉或下拉,推挽输出1时引脚为高电平,输出0时引脚为低电平。若需要增强引脚输出驱动能力,就可以使用上拉。

使用特权

评论回复
6
自动化陈稳|  楼主 | 2023-12-27 16:14 | 只看该作者
举例: 以下是一个LED输出电路图。
通过电路可知,想要让LED亮起,PF9和PF10必须保持低电平,反之,保持高电平,由此确定确定PF9和PF10为推挽输出。

使用特权

评论回复
7
自动化陈稳|  楼主 | 2023-12-27 16:14 | 只看该作者
与推挽输出相对的就是开漏输出,对于开漏输出和推挽输出的区别最普遍的说法就是开漏输出无法真正输出高电平,即高电平时没有驱动能力,需要借助外部上拉电阻完成对外驱动。**很少用到,知道基本的概念就行了

使用特权

评论回复
8
自动化陈稳|  楼主 | 2023-12-27 16:14 | 只看该作者
作为ADC或DAC引脚
模拟(Analog 功能),作为GPIO模拟引脚,用于ADC输入或DAC输出引脚。

作为复用功能引脚
(1)具有上拉或下拉的复用功能推挽(Alternate function push-pull)
(2)具有上拉或下拉的复用功能开漏(Alternate function open-drain)

使用特权

评论回复
9
自动化陈稳|  楼主 | 2023-12-27 16:15 | 只看该作者
GPIO应用编程实战(按键控灯)
接下来的编程在接口调试的基础上进行的,如果没有接口调试这一步程序将无法烧录,链接:接口调试。
设计目标:LED灯以一定频率闪烁,按一次按键后灯的闪烁频率发生变化。

使用特权

评论回复
10
自动化陈稳|  楼主 | 2023-12-27 16:15 | 只看该作者
第一步:查看控制板原理图,确定引脚和GPIO输入输出状态。
该例以一款自带外设的stm32F405系列的单片机为例,如果使用无外设的单片机(如STM32F103C8T6小系统板),请按照需求自行连接外设。

使用特权

评论回复
11
自动化陈稳|  楼主 | 2023-12-27 16:15 | 只看该作者
已知电路图如下:

使用特权

评论回复
12
自动化陈稳|  楼主 | 2023-12-27 16:15 | 只看该作者

使用特权

评论回复
13
自动化陈稳|  楼主 | 2023-12-27 16:16 | 只看该作者
由此可知LED灯的引脚为PB13,按键的引脚为PB14。
这里的输入为按键,且当按键未按下时,PB14为高电平,按键按下后,PB14为低电平,即为上拉输入。
LED灯PB13引脚为推挽输出。

使用特权

评论回复
14
自动化陈稳|  楼主 | 2023-12-27 16:16 | 只看该作者
第二步:STM32CubeMX配置,生成代码。
接下来的操作将在上的基础上进行操作。
将PB13和PB14引脚的模式分别选为GPIO_Output和GPIO_Input,点击右键分别命名为“LED1”和“KeyUser”

使用特权

评论回复
15
自动化陈稳|  楼主 | 2023-12-27 16:16 | 只看该作者
接下来,点击左面System Core选项卡中的GPIO,分别配置PB13和PB14引脚。具体如下图:

使用特权

评论回复
16
自动化陈稳|  楼主 | 2023-12-27 16:17 | 只看该作者

使用特权

评论回复
17
自动化陈稳|  楼主 | 2023-12-27 16:17 | 只看该作者
完成以上配置后,点击生成代码(GENERATE CODE),并打开IDE工程文件。`

使用特权

评论回复
18
自动化陈稳|  楼主 | 2023-12-27 16:17 | 只看该作者
第三步:编写代码。
接下来,在打开的IDE文件中进行编程。
在主函数(main.c)中的while循环中加入以下代码:`                    if(HAL_GPIO_ReadPin(KeyUser_GPIO_Port, KeyUser_Pin)== GPIO_PIN_RESET)   //如果读取到的KeyUser引脚的电平状态为低电平(即按键按下)
                    {
                        HAL_Delay(50);                                                                                                      //防止按键抖动,延时50ms
                              if(HAL_GPIO_ReadPin(KeyUser_GPIO_Port, KeyUser_Pin)==GPIO_PIN_RESET)//再次判断按键是否按下,如果按下
                              {
                                HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin, GPIO_PIN_SET);                  //LED灯的引脚输出高电平(即灯灭)
                                HAL_Delay(300);
                                HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);          //LED灯的引脚输出低电平(既灯亮)
                                HAL_Delay(300);                                                                                                          //交替进行进而闪烁
                              }
                    }
                    else                                                                                                                                          //按键没有按下时
                    {
                            HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin, GPIO_PIN_SET);                          //同理
                            HAL_Delay(1000);
                            HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
                            HAL_Delay(1000);
                    }

使用特权

评论回复
19
自动化陈稳|  楼主 | 2023-12-27 16:17 | 只看该作者
(代码都有注释,不做过多说明)
运行烧录后,现象为:灯以1秒的频率进行闪烁,按下按键后灯以0.3秒的频率进行闪烁,松手后又以1秒的频率闪烁。

使用特权

评论回复
20
自动化陈稳|  楼主 | 2023-12-27 16:17 | 只看该作者
第四步:代码优化,验证。
为了确保按键按下后松开,灯依旧保持不同频率的闪烁,加入按键检测和一个变量对代码进行优化。
在gpio.c文件中加入按键扫描的代码:uint8_t Key_Scan(GPIO_TypeDef *GPIOx,uint16_t GPIO_Pin)
{
        if(HAL_GPIO_ReadPin(KeyUser_GPIO_Port, KeyUser_Pin) == KEY_OFF)
        {
                while        (HAL_GPIO_ReadPin(KeyUser_GPIO_Port, KeyUser_Pin) == KEY_OFF)//消除按键抖动
                        return KEY_OFF;
        }
        else
                return KEY_ON;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

82

主题

1200

帖子

1

粉丝