STM32-HAL库(快速入门)-2-GPIO与EXTI

本文详细介绍了如何使用STM32F407ZGT6开发板的GPIO进行基本操作,如设置电平、复用模式和模拟输入输出,并结合EXTI实现外部中断,如按键触发LED灯的亮灭。还展示了如何在Cubemx中配置GPIO和EXTI以及相应的代码编写和中断处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

基于正点原子探索者开发板(STM32F407ZGT6)

代码文件:

链接:https://pan.baidu.com/s/1PsnWg_g7Dty-eOfZP8iC_Q?pwd=hy9g 
提取码:hy9g 

一、GPIO基本原理

GPIO:通用输入输出端口

可以理解为一个输出电平的点,你可以让他输出高电平或低电平,并可以设置上拉下拉(默认高电平、默认低电平)

工作模式分为四个大类:输入模式,输出模式,复用模式、模拟输入输出

输入模式:捕获电平变化

输出模式:控制电平变化,选择推挽模式,开漏模式用于通信之中

复用模式:其他外设占用该引脚

模拟输入输出:AD and DA模式专用

二、cubemx配置——GPIO

目标:使用GPIO的改变电平功能使LED灯进行闪烁

找到原理图中的LED(不同板子引脚使用不一样),查到需要控制PF9,PF10即可

在右下角选择PF9,PF10,设置为输出模式

选择初始电平为高电平:初始LED灭

不上拉也不下拉:由于我们一直控制着电平变化,所以无所谓,单片机采用的是弱上下拉,如果我们控制了引脚,则约等于设置了也无效果

User Label:写为对应的LED,这样会非常方便移植,例如你想换个引脚来控制外部LED,那么就可以直接把那个引脚的User Label改为对应LED的名字,代码不需要改变

这样GPIO控制引脚的设计就设计完成了,生成代码即可。

三、代码编写——GPIO

GPIO的API

DeInit:使对应GPIO引脚恢复为默认的配置

Init:使用结构体来初始化GPIO(cubemx会配置好,不需要再配置) 

ReadPin:读取对应GPIO引脚的电平状态

WritePin:设置对应GPIO引脚的电平状态

TogglePin:翻转电平状态

void HAL_GPIO_DeInit(GPIO_TypeDef  *GPIOx, uint32_t GPIO_Pin)
void HAL_GPIO_Init(GPIO_TypeDef  *GPIOx, GPIO_InitTypeDef *GPIO_Init)
GPIO_PinState HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)
void HAL_GPIO_WritePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin, GPIO_PinState PinState)
void HAL_GPIO_TogglePin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin)

 可以看到,当我们使用UserLabel之后,对应的GPIO宏定义就是被重定义为更一般的名称,移植代码会变得非常方便。

代码实现

      HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
      HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
      HAL_Delay(500);
      HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);
      HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);
      HAL_Delay(500);

 注意:要在user code begin while与user code begin end之间写代码,不然修改cubemx重新生成代码之后就会被清楚。

四、EXTI基本原理

EXTI:外部中断

外部中断的作用:就是可以检测电平的变化,检测到之后进入中断回调函数,在该回调函数中,实现我们要实现的功能。

中断触发方式:上升沿触发、下降沿触发和双边沿触

上升沿触发:当PA0从低电平跳变到高电平,则会自动触发EXTI0的中断,其他两种类似

它把每个GPIO相同引脚号分配为一组,用一个多路选择器选出一个,来作为EXTI引脚,例如用PA0做EXTI引脚后PB0就无法使用了,所以最多16个外部中断。EXTI所管理的16个外部中断线只提供7个中断通道。EXTI0-EXTI4有独立的中断通道,独立的中断处理函数。EXTI5-EXTI9共享1个中断通道,共享中断处理函数,EXTI10-EXTI15共享1个中断通道,共享中断处理函数。

代码执行过程:

可以看到,中断通用处理函数中会先判断是否有中断,然后帮我们清除中断标志位,所以我们只管判断是哪个中短线触发的然后编写执行代码即可。

中断回调函数弱若定义的,我们可以在main下面重写一下,就可以自己配置中断回调函数了。

五、cubemx配置——EXTI

目标:利用按键来改变GPIO引脚变化,并设置EXTI检测电平变化,回调函数中来改变LED灯亮灭,用KEY0来同时改变LED0、LED1

找到原理图中的KEY:

选择GPIO_EXTI4功能

 

按照原理图,按下按键后引脚被拉到低电平,那么我们应该选择上拉模式,让他默认为高电平,然后检测它的下降沿。

NVIC使能EXTI4的中断线

六、代码编写——EXTI

EXTI的API

HAL_EXTI_ClearConfigLine(EXTI_HandleTypeDef *hexti)
HAL_EXTI_ClearPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
HAL_EXTI_GenerateSWI(EXTI_HandleTypeDef *hexti)
HAL_EXTI_GetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)
HAL_EXTI_GetHandle(EXTI_HandleTypeDef *hexti, uint32_t ExtiLine)
HAL_EXTI_GetPending(EXTI_HandleTypeDef *hexti, uint32_t Edge)
HAL_EXTI_IRQHandler(EXTI_HandleTypeDef *hexti)
HAL_EXTI_RegisterCallback(EXTI_HandleTypeDef *hexti, EXTI_CallbackIDTypeDef CallbackID, void (*pPendingCbfn)(void))
HAL_EXTI_SetConfigLine(EXTI_HandleTypeDef *hexti, EXTI_ConfigTypeDef *pExtiConfig)

代码实现

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == KEY0_Pin)  //按键按下
    {
        HAL_Delay(20);
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)
		{
            HAL_GPIO_TogglePin(LED0_GPIO_Port,LED0_Pin);
            HAL_GPIO_TogglePin(LED1_GPIO_Port,LED1_Pin);
		}
    }
}

注意:

HAL_Delay函数本质也是打断程序去执行延时操作,那么,就一定要让系统滴答定时器抢占优先级高于外部中断的抢占优先级(数字越小级别越高),下面是配置优先级步骤:

先修改为抢占优先级与响应优先级各用2位配置(可以不改)

默认系统滴答定时器是最低,我们要把它改为1,然后外部中断比它低一个等级——2即可

 

有什么bug直接发在评论区

 

<think>好的,用户想了解GPIO EXTI的用法或相关的技术问题解决。首先,我需要回顾一下GPIOEXTI的基本概念。GPIO是通用输入输出端口,用于连接微控制器外部设备。EXTI是外部中断/事件控制器,用于检测外部信号的变化并触发中断。 接下来,用户可能需要知道如何配置GPIO作为EXTI的中断源。例如,在STM32中,需要配置GPIO的模式为中断模式,选择触发边沿(上升沿、下降沿或两者),然后启用NVIC中断。这部分需要详细步骤,包括代码示例,可能用HAL或者寄存器配置。 然后,常见的问题可能包括中断无法触发、多次触发或者优先级冲突。需要分析可能的原因,比如GPIO配置错误、中断服务程序(ISR)没有正确编写、或者没有清除中断标志位。此外,还可能涉及到软件消抖处理,因为机械开关可能会产生噪声信号。 用户可能还关心不同微控制器之间的差异,比如STM32和AVR在EXTI配置上的不同,但通常会以STM32为例,因为比较常见。需要确保提供的代码示例正确,并且符合最佳实践,比如在ISR中尽量减少处理时间,使用标志位在主循环中处理任务。 另外,可能需要提到中断优先级配置,确保关键中断能够及时响应。还有DMAEXTI的结合使用,但可能这属于进阶内容,用户的问题可能更基础。 最后,生成相关问题时要覆盖配置步骤、常见问题解决、应用场景、不同开发环境的差异以及中断处理的最佳实践。需要确保问题有针对性,能够帮助用户进一步深入学习或解决问题。</think>### GPIO EXTI使用故障排查 #### 一、GPIO EXTI基础原理 GPIO EXTI(External Interrupt/Event Controller)是嵌入式系统中实现外部信号实时响应的核心机制,通过检测GPIO引脚电平变化触发中断。其工作流程包含三个关键阶段: 1. 信号边沿检测:配置为$V_{IL}<V_{PIN}<V_{IH}$范围内的电压跳变检测 2. 中断请求生成:产生EXTIx中断信号(x对应引脚编号) 3. NVIC响应:通过Nested Vectored Interrupt Controller处理中断优先级[^1] #### 二、STM32配置示例(HAL) ```c // GPIO初始化 GPIO_InitTypeDef GPIO_InitStruct = {0}; __HAL_RCC_GPIOA_CLK_ENABLE(); GPIO_InitStruct.Pin = GPIO_PIN_0; GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING; // 上升沿触发 GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // EXTI中断配置 HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); HAL_NVIC_EnableIRQ(EXTI0_IRQn); // 中断服务函数 void EXTI0_IRQHandler(void) { HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); // 用户处理代码 } ``` #### 三、常见问题排查表 | 现象 | 检测点 | 解决方法 | |------|--------|----------| | 中断不触发 | 1. GPIO时钟使能<br>2. NVIC配置<br>3. 引脚复用冲突 | 使用__HAL_RCC_GPIOx_CLK_ENABLE()<br>检查中断优先级设置<br>查看数据手册Alternate Function映射 | | 多次误触发 | 1. 机械抖动<br>2. 中断标志未清除 | 添加硬件RC滤波(通常τ=10ms)<br>在ISR中调用__HAL_GPIO_EXTI_CLEAR_IT() | | 系统死机 | 1. 中断服务程序超时<br>2. 堆栈溢出 | 遵循ISR短小原则(建议<100周期)<br>调整启动文件Stack_Size值 | #### 四、高级应用技巧 1. 软件消抖算法实现: $$ t_{debounce} = \frac{1}{f_{sys}} \times N_{samples} $$ 建议采样周期数$N_{samples}$取5-10次系统时钟周期 2. 低功耗模式下配置: ```c // 在STOP模式下保持EXTI唤醒功能 HAL_PWR_EnableWakeUpPin(PWR_WAKEUP_PIN1); HAL_PWR_EnterSTOPMode(PWR_LOWPOWERREGULATOR_ON, PWR_STOPENTRY_WFI); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值