【STM32 HAL库】GPIO:按键和LED

发布者:幸福的时光最新更新时间:2025-10-24 来源: bilibili关键字:STM32  HAL库  GPIO  按键  LED 手机看文章 扫描二维码
随时随地手机看文章

文章内容偏向HAL库的移植和使用,以个人观点及了解为主,若与事实不符,则以www.st.com、www.stmcu.org.cn等平台为准。


使用的软件:   

VSCode(1.36版,带C/C++ IntelliSense插件)                                              

Keil MDK(5.26版)


芯片:STM32H743ZIT6(Nucleo-H743平台,B-01版)


所使用的库:STM32Cube_FW_H7_V1.3.0,下载地址:https://www.st.com/content/st_com/en/products/embedded-software/mcu-mpu-embedded-software/stm32-embedded-software/stm32cube-mcu-mpu-packages/stm32cubeh7.html

参考资料:STM32H743xI参考手册、数据手册、部分HAL库文件、NUCLEO-H743原理图(B-01)

程序下载:https://pan.baidu.com/s/124IrMzjdF15hEtk_hhi4iA

cut-off

        计算机的组成部分通常分为5类:运算器、控制器、储存器、输入设备、输出设备。对于STM32H743ZIT6来说,最基本的输入/输出设备就是IO口(GPIO,General-Purpose Input/Output,通用输入/输出口)。所以就以GPIO的操作作为第一个实验。

        关于GPIO的内容,在参考手册的第10章。

        STM32H743ZIT6共有11组GPIO,即GPIOA-GPIOK,除GPIOK只有PK0-PK7这8个引脚外,其他各组GPIO都有16个引脚Pn0-Pn15(n=A,B......J)。每一个IO口都可以独立地配置、操作。

cut-off

        GPIO的工作模式

GPIO的工作模式

        如上图所示,GPIO有3种输入通用模式、1种模拟模式、2种通用输出模式和2种复用输出模式,从上到下依次为:

            1、浮动输入模式

            2、上拉输入模式

            3、下拉输入模式

            4、模拟输入模式

            5、带上拉/下拉功能的开漏输出模式

            6、带上拉/下拉功能的推挽输出模式

            7、带上拉/下拉功能的开漏复用模式

            8、带上拉/下拉功能的推挽复用模式

        在这8种功能中,功能1-3类似,差别就是启用或禁用上拉/下拉电阻;功能4使用模拟信号,而且既可以作为输出口,又可以作输入口;功能5-8都是输出功能,但功能5、6可以直接用软件修改IO口的电平状态,而功能7、8的电平状态由硬件改变。

        其实7、8的复用输出功能也可以归为输出功能,但是与通用输出功能不同的是,在复用模式下,有专门的驱动电路来驱动IO口,IO的电平状态不再受到GPIO相关寄存器的控制,其控制权将交给驱动IO口的外设,如UART、I2C等。不过GPIO的工作模式却没有复用输入模式,这是因为输入信号不需要专用的电路,只需要把信号直接送给对应的外设就可以了。但如果某一个IO口启用了复用功能(不论输入还是输出),虽然HAL库提供的GPIO读函数依然有效,但禁止使用HAL库提供的写函数修改IO口电平状态,同时也不建议读取IO口电平状态。

cut-off

        GPIO的结构:

GPIO的结构

        GPIO的结构大同小异。就输入电压而言,可以分为两类,一类是支持5V容忍度的IO,一类是不支持5V容忍度的IO。所谓的5V容忍度,指的是某个IO口既可以使用3.3V高电平,又可以使用5V高电平且不会损坏,但要串接保护电阻。不过还是参考后者,即不支持5V容忍度的IO。

        不管何种模式,图片右边的两个保护二极管都不会被禁用,也不会影响输入的电平,所以不做讨论。

        对于3种输入模式,右边的上拉/下拉电阻可以根据选择使用,蓝色框为输入驱动器,实际上这部分主要是一个施密特触发器。在输入模式下,从IO输入的信号会先向模拟部分(橙色)提供一路信号(不管用不用,都会提供,由相应的模拟外设选择输入的信号,下同),之后经过施密特触发器,向复用输入功能部分(红色)提供一路信号,同时也向GPIO的输入数据寄存器(紫色)提供一路信号,作为从外部读取的电平。

        在模拟功能下,除了橙色部分的模拟信号输入/输出外,其他部分都无效或者禁止使用。

        如果启用了输出功能,那么就有两路可用的输出驱动信号,一路是来自GPIO输出数据寄存器的驱动信号(来自紫色的框中),另一路是复用功能驱动信号(来自左下黄色框中),具体选用哪一路信号,由输出驱动电路(绿色框)种的选择器确定,并将这一路信号送给输出控制部分,用来产生MOS管的驱动信号,通过MOS管的关断和导通,实现电平的变换。

        如果和功能5-8关联起来的话,功能5、6使用的驱动信号由GPIO输出数据寄存器提供,功能7、8使用的驱动信号由复用功能驱动信号提供。在开漏模式下,P-MOS始终关闭,通过启用上拉电阻或者外接上拉电阻的形式来产生高电平,如果没有有效的上拉电阻,那么IO口的电平状态是不确定的。如果是推挽模式,那么P-MOS和N-MOS会交替导通和关断,保证高电平足够高、低电平足够低。

cut-off

        GPIO的复用:

        STM32H743的外设非常多,其中某一些外设需要使用GPIO来输入、输出信号,此时就要把某些GPIO的控制权交给外设,由外设管理IO的电平状态。此时GPIO不能再作为通用IO使用,而是工作于由用户选定的功能,这种工作状态就叫做GPIO的复用。GPIO有16种复用模式,从AF0-AF15,详细的复用功能表再STM32H743xI的数据手册中,位于第五章靠后的部分。

GPIOA的复用功能

        虽然一个引脚支持数种复用功能,但同一时刻,只能选择一种复用功能。

        另外,所有GPIO都可以挂接在EXTI上,实现外部的上升沿、下降沿和跳变沿中断。关于EXTI的内容,目前不会使用太多,所以就先不细讲。

cut-off

        现在,来编写一个程序,使用1个按键和3个LED,当按键按下时,LED的状态随之改变。也就是这个视频实现的效果。

00:10

【STM32H743】第一个实验当然是玩灯了

2951观看 0弹幕

cut-off

        首先,来分析需求。

        NUCLEO-H743 B-01(B-01是版本号)开发板带有3个LED和1个用户按键。为了使用更多的硬件,也就是使用EXTI,所以把与按键连接的GPIO配置为中断模式,进入中断后按照一定的顺序修改LED状态,如果多次按下按键则循环给定的状态。LED的状态分4种:红、蓝、绿、全亮。如果LED已经是全亮的状态,那么下一个状态时红色,并开始循环。而按键是以按下触发中断的。

cut-off

        因为ST官网提供的NUCLEO-H743原理图只有C-01版,所以原理图就参考NUCLEO-F767开发板。

        红色LED阴极接地,阳极通过保护电阻连接PB14,蓝色LED也类似,连接在PB7,按键连接在PC13,按下按键产生高电平,释放按键产生低电平。

LED_G原理图

        而绿色LED配备了由运放组成的专用驱动电路,这种连接方式,会将同相端输入的直接反应到输出端。输入的信号可以又两路:PB0和PA5,这么做也许是考虑到了PA5带有DAC功能(DAC1_OUT2),但输出的电流不足以驱动LED,而设计的驱动电路。对于PB0来说,因为信号是同相的,所以也是高电平点亮LED。

        所以硬件信息就是:

            LED_R    PB14    高电平点亮

            LED_B    PB7      高电平点亮

            LED_G    PB0      高电平点亮

            KEY         PC13   上升沿中断

cut-off

        拷贝一份工程模板,将文件夹命名为"STM32H743_LED按键",在Driver/src下新建LED.c、KEY.c,在Driver/inc下新建LED.h、KEY.h。

        因为是已经写好的程序,所以就不重新编写了。        

        先同时打开KEY.h和LED.h。

动图

打开两个文件

        现在来看一看代码

KEY.h与LED.h

        每个文件的#ifndef-#define-#endif结构已经是惯例了,用于防止头文件重复编译。使用了HAL库的工程,用户头文件只需要添加stm32h7xx_hal.h即可,它通过包含stm32h7xx_hal_conf.h间接包含了所有已启用外设的头文件和stm32h7xx.h,不必再次包含每个外设的头文件。

        在KEY.h文件中先是用两个宏定义,定义了按键的GPIO引脚(6-7行),PC13,又声明了一个按键初始化函数(9行)。

        LED.h中也是类似,定义了每个LED的GPIO引脚,声明了三个函数,分别用于初始化LED(LED_Init())、点亮LED(LED_On())、熄灭LED(LED_Off())。另外6-12行定义了一个枚举类型LEDSelection_TypeDef,这个类型用于选择一个LED。

KEY.c中的程序

        现在来看看KEY.c文件。

        这个文件中的KEY_Init()函数大致分为3部分:开启GPIO时钟(7)、初始化GPIO引脚(9-12)、配置相应的中断(15-16).

        在HAL库中,与RCC外设有关的内容全部都在stm32h7xx_hal_rcc.c/.h、stm32h7xx_hal_rcc_ex.c/.h中,__HAL_RCC_GPIOC_CLK_ENABLE()是一条位于stm32h7xx_hal_rcc.h中第938行的宏。stm32h7xx_hal_rcc.h中还有其他类似的宏,用于外设的时钟管理,可以在启用正则表达式搜索功能后用__HAL_RCC_.*_CLK_ENABLE()搜索到,对应的DISABLE宏可以用__HAL_RCC_.*_CLK_DISABLE()搜索,也可以使用__HAL_RCC.*ABLE()匹配所有项.

动图

HAL库提供的外设时钟使能宏

        GPIO_InitStructure的数据类型是GPIO_InitTypeDef,它的定义在stm32h7xx_hal_gpio.h中

GPIO_InitTypeDef的定义

        这个结构中有5个成员。

            Pin:指定要配置的引脚,可单选或多选

            Mode:指定要配置的IO模式

            Pull:指定上拉/下拉电阻配置

            Speed:指定输出速度(仅输出模式、复用模式有效)

            Alternate:指定引脚的复用功能

        其中,前4个成员的参数定义在stm32h7xx_hal_gpio.h中,复用功能参数定义在stm32h7xx_hal_gpio_ex.h中,因为还没有用到复用模式,所以就暂不讨论。上一张图使用了正则表达式搜索,搜索结果的大致位置在右侧预览窗口中有显示。如果不知道该怎么选,可以直接查看对应的代码,比如IO模式:

GPIO_InitTypeDef::Mode的各个参数

        与上升沿中断对应的参数是143行的GPIO_MODE_IT_RISING。

        KEY.c第9行的参数来自KEY.h中第7行的定义,这个定义是stm32h7xx_hal_gpio.h中参数的二次定义,主要目的是为了让程序更加灵活,KEY.c第12行的GPIOPort_KEY的用法和目的也是类似的。KEY.c第11行,启用下拉电阻,保证按键IO空闲时为低电平,按键按下有产生上升沿。

        KEY.c的15、16行用于配置NVIC(嵌套向量中断控制器),15行用于配置NVIC的对应优先级,16行用于开启中断。NVIC是Cortex-M7内核的部分,所以暂不深入了解。经过HAL库的配置后,NVIC拥有4位抢占优先级和0位响应优先级(优先级分组4),但因为目前要编写的程序只有一个中断,所以这一部分可以随意配置。

        在这个程序中,按键中断时通过EXTI来实现的,PC13占用了EXTI13,所以在配置中断优先级时,中断号参数为EXTI15_10_IRQn。关于中断号(IRQn)的全部定义,可以在stm32h743xx.h中找到。

stm32h743xx.h中定义的中断号

        在LED.c中的LED_Init()函数的作用和代码与KEY_Init()类似,只不过没有中断优先级配置而已。

LED.c中的程序

        两个LED操作的函数结构相同,都是利用switch-case结构选择对应的LED灯,唯一的区别就是点亮灯需要输出高电平,IO状态为SET;熄灭灯需要低电平,IO状态为RESET。

            LED_On()和LED_Off()的参数s的类型就是在LED.h中定义的LEDSelection_TypeDef,用来选择LED灯,除单独选择红、绿、蓝之外,还有一个全部选择。

cut-off

        Driver文件夹下的4个文件编写好之后,要在stm32h7xx_it.c、main.c/.h中编写一些代码。首先是stm32h7xx_it.c,要在其中编写EXTI的中断响应程序,这个程序比较简单,只有4行(177-180)

        其中只是调用了HAL_GPIO_EXTI_IRQHandler()函数,传递的参数为产生外部中断的引脚号,也就是GPIO_InitTypeDef::Pin的值。这个函数是由stm32h7xx_hal_gpio.c/.h提供的,在右侧窗口中可以看到函数的源码,先检测并复位中断标志,再调用HAL_GPIO_EXTI_Callback()函数,即产生回调。关于回调的内容,将在下一篇文件讲到,现在只需要知道,只要产生有效的中断,HAL_GPIO_EXTI_Callback会被HAL库调用即可。

        之后,要在main.h中包含KEY.h和LED.h(同时要把对应的.c文件在MDK中添加到Driver组中,不然会报错)。

main.h中的代码

        在main.c中,要通过调用LED.c和KEY.c中的函数达到预期效果,所以编写的程序比较多。

main.c中的部分代码

        在main.c中,14、15、17行是添加的部分,注意要添加在10-12行的三个函数之后。前两行用于初始化按键及LED,最后一行是让程序进入一个初始状态,也就是上电后,红灯会立刻亮。之后编写这样一段程序:

还是main.c中的代码

        这一部分负责响应回调(或者说响应中断),函数头部分就是stm32h7xx_hal_gpio.c中521行的函数头,不过要去掉__weak修饰符(下一篇文章讲)。这样相当于重写stm32h7xx_hal_gpio.c中的HAL_GPIO_EXTI_Callback()函数,当HAL_GPIO_EXTI_IRQHandler()调用HAL_GPIO_EXTI_Callback()时,会调用main.c中的函数,而不是stm32h7xx_hal_gpio.c中的。


        第26行定义了一个静态变量LEDSelection,初值选择蓝色LED,之后用一个switch-case来选择按键按下这种情况(其实不用也可以,但如果允许多个引脚产生中断的话,就需要了)。第32-36行是实现LED状态改变的部分,先关闭全部LED(32行),在开启选中的LED(33行),最后选择下一个LED状态(35-36行)。其中35-36行选择不同LED状态的原理就是利用LEDSelection是枚举型变量,对其加一就会变成下一个成员的值,在用一个if作溢出判断即可。

[1] [2]
关键字:STM32  HAL库  GPIO  按键  LED 引用地址:【STM32 HAL库】GPIO:按键和LED

上一篇:STM32 HAL库 模拟SPI驱动 DAC8564
下一篇:STM32CubeIDE嵌入式开发入门到入坟-软件篇-2、新建工程与GPIO(IO)口配置

推荐阅读最新更新时间:2026-03-20 10:27

STM32HAL库GPIO相关函数解析
背景: 最近一直在学习HAL库,总结下STM32中HAL库的GPIO相关函数知识点。 内容: 在stm32l152xb.h头文件中定义了GPIO的相关寄存器,下面讲述的GPIO函数将会调用到这些寄存器。寄存器的结构体定义如下图: 下面解析stm32l1xx_hal_gpio.c文件中一些常用的GPIO函数: (1)GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)函数 GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin) { GPIO_Pi
[单片机]
按键操作(CubeMX加HAL库STM32系列)
这一篇是补充第一篇的按键操作, 因为第一篇很多地方很详细了, 写了很大的篇幅, 所以单独写一篇用CubeMX配置STM32使用自带按键的操作 提示 : 仍然按照先Cube配置再IAR或者Keil编程, CubeMX里面关于时钟的配置跟我上一篇写的一样, RCC和SYS设置以及时钟树(Clock Configuration)都按照第一篇配置即可, 没有什么特别的需求, 是从始至终不需改变这个地方的配置的。 1-2. 使用核心板自带按键 操作简介 :    通过板子上的两个按钮控制LED灯的亮灭 WK_UP按键按下则LED0闪烁, 松开停止闪烁并熄灭, 即WK_UP按键长按LED0才会持续闪烁    KEY0按下再松手, LE
[单片机]
<font color='red'>按键</font>操作(CubeMX加<font color='red'>HAL库</font>学<font color='red'>STM32</font>系列)
STM32 基础系列教程 2 - GPIO 按键输入
前言 学习stm32 GPIO 的使用,实现简单的按键输入功能,用按键的高低来控制LED的亮灭! 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的型号是 STM32F103c8t6, 使用stm32cubemx 工具自动产生的配置工程,使用KEIL5编译代码。将PA0引脚设置成输入引脚,程序得到PA0引脚的(按键操作)输入状态,并根据其输入电平的高低来控制PC13输出,来控制LED,实现按一次LED亮,再按一下,LED灭的功能。 本示例所用的最小系统板原理图: 新建STM32 CUBEMX 工程, 双击桌面STM32CubeMX工具 在CubeMX中菜单中点 File à New
[单片机]
<font color='red'>STM32</font> 基础系列教程 2 - <font color='red'>GPIO</font> <font color='red'>按键</font>输入
stm32实现GPIO输入按键检测
1、硬件设计 按键机械触点断开、闭合时,由于按键触点的弹性作用,按键开关不会马上稳定接通或一下就断开,使用按键时就会产生下图中的带纹波信号,需要软件消抖处理滤波 由于用软件消抖处理滤波不方便输入检测,所以提出了如下带有硬件消抖的电路。 从按键的原理图可知,当按键没有被按下时,GPIO引脚通过一个下拉电阻R64使引脚处于低电平状态,当按键被按下时,按键所在的电路导通,VCC通过一个限流电阻R33连接到GPIO引脚,使GPIO引脚的输入状态为高电平,只要我们检测引脚的输入电平为高电平,即可判断按键是否被按下。 同LED工程,为了使工程的移植性更高,是工程更有条理,我们把按键相关的代码独立分开存储,在工程模板
[单片机]
<font color='red'>stm32</font>实现<font color='red'>GPIO</font>输入<font color='red'>按键</font>检测
STM32CubeMX学习笔记2:GPIO按键外部中断控制LED状态
MCU:STM32F103ZET6 IDE: MDK-ARM V5 +STM32CubeMX5.0.0 本次实现的功能是通过按键的外部中断,来改变对应LED的状态,需要将按键的I/O端口映射到外部中断线上。 需要初始化的按键I/O口分别对应PA0PE2PE3PE4,LEDI/O口分别为PC0PC1PC2PC3PC4。 一. 在 Pinout&Configuration---System Core中: 1. 首先设置时钟RCC的HSE(外部高速时钟)为晶振模式:Crystal/ceramic Resonator 2. 设置系统SYS的Debug为Serial Wire: 3. 设置GPIO中的LED
[单片机]
STM32CubeMX学习笔记2:<font color='red'>GPIO</font><font color='red'>按键</font>外部中断控制<font color='red'>LED</font>状态
STM32单片机学习】第8章 GPIOLED点灯
本章实验的目的是通过LED点灯,让读者熟悉STM32F103最基本的外设GPIO。首先介绍了GPIO的一些基本概念和知识,然后介绍开发板LED灯部分硬件设计,再结合硬件进行软件设计,最后展示实验效果。本章阅读提示:8.1 关于GPIO(介绍GPIO的一些知识,刚开始概念有些多,读者慢慢理解)8.2 硬件设计(分析LED灯部分的硬件设计和RGB灯,需要理解)8.3 软件设计(讲解如何编写LED程序,需要重点理解)8.4 实验效果(展示实验效果,操作即可) 8.1 关于GPIO GPIO(General-Purpose IO ports,通用输入/输出接口),用于感知外界信号(输入模式)和控制外部设备(输出模式),如图 6.1
[单片机]
【<font color='red'>STM32</font>单片机学习】第8章 <font color='red'>GPIO</font>—<font color='red'>LED</font>点灯
STM32时钟与GPIO分析 基于STM32LED灯开发
一、 STM32时钟分析 寄存器 :寄存器的功能是存储二进制代码,它是由具有存储功能的触发器组合起来构成的。一个触发器可以存储1位二进制代码,故存放n位二进制代码的寄存器,需用n个触发器来构成 在计算机领域,寄存器是CPU内部的元件,包括通用寄存器、专用寄存器和 控制寄存器 。寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快。 控制寄存器 :相当一排可通过0/1进行设置外设功能的开关,程序中通过地址查找到对应的寄存器,所以说控制寄存器的地址是唯一。 芯片时钟:芯片工作时,是需要脉冲,脉冲相当于给芯片起振,可保证芯片的正常工作,类似于人,心脏正常跳动,人体生命特征才能正常。 1HZ:一秒产生1个脉冲 频率换算单位:
[单片机]
<font color='red'>STM32</font>时钟与<font color='red'>GPIO</font>分析 基于<font color='red'>STM32</font>的<font color='red'>LED</font>灯开发
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved