首页 > 其他分享 >STM32 HAL库 通过外部中断控制一个灯亮灭

STM32 HAL库 通过外部中断控制一个灯亮灭

时间:2024-03-20 20:58:05浏览次数:35  
标签:灯亮 HAL 函数 中断 void STM32 GPIO EXTI

个人学习理解

       在我们学习写代码的过程中,我们配合着开发指南中的程序设计的配置步骤并与我们的学习视频结合着、对比着学习,这能更加让我们对程序设计步骤理解得更加透彻。

硬件了解

1、LED灯

LED0 – PB5

LED1 – PE5

2、独立按键

KEY0 – PE4

KEY1 – PE3

KEY2 – PE2

KEY_UP – PA0

3、原理图

EXTI外部中断配置步骤

STM32f103战舰v4开发指南中的程序设计步骤

1)使能对应GPIO口时钟 本实验用到的GPIO 和按键输入实验是一样的,因此GPIO时钟使能也是一样的,请参考 上一章代码。

2)设置GPIO工作模式,触发条件,开启AFIO时钟,设置IO口与中断线的映射关系 这些步骤HAL库全部封装在HAL_GPIO_Init函数里面,我们只需要设置好对应的参数, 再调用HAL_GPIO_Init函数即可完成配置。

3)配置中断优先级(NVIC),并使能中断。 配置好 GPIO 模式以后,我们需要设置中断优先级和使能中断,中断优先级我们使用 HAL_NVIC_SetPriority 函数设置,中断使能我们使用HAL_NVIC_EnableIRQ函数设置。

4)编写中断服务函数。 每开启一个中断,就必须编写其对应的中断服务函数,否则将导致死机(CPU将找不到中 断服务函数)。中断服务函数接口厂家已经在startup_stm32f103xe.s 中做好了,STM32F1 的 IO 口外部中断函数只有7个,分别为:

void EXTI0_IRQHandler();

void EXTI1_IRQHandler();

void EXTI2_IRQHandler();

void EXTI3_IRQHandler();

void EXTI4_IRQHandler();

void EXTI9_5_IRQHandler();

void EXTI15_10_IRQHandler();

中断线0-4,每个中断线对应一个中断函数,中断线5-9共用中断函数EXTI9_5_IRQHandler, 中断线10-15共用中断函数EXTI15_10_IRQHandler。一般情况下,我们可以把中断控制逻辑直 接编写在中断服务函数中,但是HAL库把中断处理过程进行了简单封装,请看步骤5讲解。

5)编写中断处理回调函数HAL_GPIO_EXTI_Callback HAL库为了用户使用方便,提供了一个中断通用入口函数HAL_GPIO_EXTI_IRQHandler, 在该函数内部直接调用回调函数HAL_GPIO_EXTI_Callback。 我们先看一下HAL_GPIO_EXTI_IRQHandler函数定义:

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);  //清除中断标志位
    HAL_GPIO_EXTI_Callback(GPIO_Pin);    //外部中断回调函数
  }
}

该函数实现的作用非常简单,通过入口参数GPIO_Pin判断中断来自哪个IO口,然后清除 相应的中断标志位,最后调用回调函数HAL_GPIO_EXTI_Callback()实现控制逻辑。在所有的外 部中断服务函数中直接调用外部中断共用处理函数HAL_GPIO_EXTI_IRQHandler,然后在回调函数HAL_GPIO_EXTI_Callback 中通过判断中断是来自哪个 IO 口编写相应的中断服务控制逻 辑。

因此我们可以在HAL_GPIO_EXTI_Callback里面实现控制逻辑编写。

源码

exti.c

#include "./BSP/EXTI/exti.h"
#include "./SYSTEM/delay/delay.h"

void exti_init(void)
{
    GPIO_InitTypeDef gpio_init_struct;
    __HAL_RCC_GPIOE_CLK_ENABLE();                       //GPIO时钟使能

    gpio_init_struct.Pin = GPIO_PIN_4;
    gpio_init_struct.Mode = GPIO_MODE_IT_FALLING;       //下降沿触发
    gpio_init_struct.Pull = GPIO_PULLUP;                //上拉输入
    HAL_GPIO_Init(GPIOE, &gpio_init_struct);

    HAL_NVIC_SetPriority(EXTI4_IRQn,2,0);               //设置中断优先级
    HAL_NVIC_EnableIRQ(EXTI4_IRQn);                     //使能中断

}
void EXTI4_IRQHandler()                                 //编写外部中断服务函数
{
    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);               //中断通用入口函数
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_4);               //清除中断标志位

}
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)          //外部中断回调函数
{
    delay_ms(10);
    if(GPIO_Pin == GPIO_PIN_4)
    {
        if(HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_4) == 0)
        {
            HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);       //翻转为PB5
        }        //因为原来设置的是PE5-LED1灯亮翻转成PB5,PE5就会灭
    }

}

 exti.h

#ifndef __EXTI_H
#define __EXTI_H

#include "./SYSTEM/sys/sys.h"

void exti_init(void);


#endif

main.c 

#include "./SYSTEM/sys/sys.h"
#include "./SYSTEM/delay/delay.h"
#include "./SYSTEM/usart/usart.h"
#include "./BSP/LED/led.h"
#include "./BSP/EXTI/exti.h"


int main(void)
{
    HAL_Init();                                 /* 初始化HAL库 */
    sys_stm32_clock_init(RCC_PLL_MUL9);         /* 设置时钟,72M */
    delay_init(72);                             /* 初始化延时函数 */
    led_init();                                 /* 初始化LED */
    exti_init();
    
    while(1)
    {

        LED1(1);                                /* LED1 灭 */
        delay_ms(500);

        LED1(0);                                /* LED1 亮 */
        delay_ms(500);
    }
}

标签:灯亮,HAL,函数,中断,void,STM32,GPIO,EXTI
From: https://blog.csdn.net/2302_79878697/article/details/136786205

相关文章

  • 江科大STM32学习笔记(上)
    @目录前言外设篇GPIO输出GPIO位结构GPIO模式外设的GPIO配置查看实战1:如何进行基本的GPIO输入输出OLED显示屏及调试Keil的调试模式演示EXTI外部中断NVIC基本结构EXTI结构代码实战2:如何使用中断和对射式红外传感器&旋转编码器TIM(Timer)定时器1.1基本定时器(TIM6和TIM7)1.1_1_时基单元......
  • STM32发送串口数据丢失字节的解决办法
    发送数据函数voidUsart3_Send_Array(u8*buf,u8len){u8t;GPIO_WriteBit(GPIOB,RS485AB_EN_PIN,1);for(t=0;t<len;t++) //循环发送数据{while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==RESET);USART_SendData(USART3,......
  • 学习STM32第八天
    TIM基础1、TIM编码器接口通过定时器的编码器接口进行自动计次,之前的编码器计次是通过触发外部中断然后在中断函数中进行计次,当测量的是高速旋转的电机时,则每秒会产生成千上万个中断,程序会频繁进入中断但是中断所完成的任务又仅仅是简单的加一减一,极大地浪费软件资源。使用......
  • 02_STM32软件+硬件SPI读写W25Q64(HAL库)
    目录1、SPI简介2、SPI时序单元2.1模式0(应用最多)2.2模式12.3 模式22.4 模式33、SPI移位示意图4、简单软件SPI代码(HAL库)5、简单硬件SPI读写W25Q64(HAL库)6、例程下载1、SPI简介2、SPI时序单元2.1模式0(应用最多)2.2模式12.3 模式2模式2与模式0类似,区别在......
  • 记一次 HalconControl 无法正常显示埋下的坑 关于Shown,Load,警钟长鸣
    最近在写一个视觉软件demo(基于Halcon) 根据MEF框架下进行 后台代码的解耦。首推这一款框架,在自动化,运动控制,视觉领域可运用范围极广。首先简单介绍一下什么是MEF,MEF,全称ManagedExtensibilityFramework(托管可扩展框架)。单从名字我们不难发现:MEF是专门致力于解决扩展性问题......
  • STM32_LVGL移植流程及注意事项
    STM32——LVGL移植流程及注意事项下载源码(lvgl8.2):点击git下载.源码精简lvgl-8.2​|build:使用Cmake工具编译的相关文件​|demos:lvgl官方的测试demos​|docs:lvgl文档​......
  • datawhale-动手学数据分析task4笔记
    动手学数据分析task4数据可视化matplotlib的图像都位于figure对象中,创建新的对象用plt.figure。plt.subplot()方法可以更方便地创建一个新figure,并返回一个含有以创建的subplot对象的numpy数组。'''参数说明:nrows=int,subplot的行数ncols=int,subplot的列数sharex=Bool......
  • stm32库函数_小知识
    stm32库函数值计算#definePOSITION_VAL(VAL)(__CLZ(__RBIT(VAL)))在STM32中的作用是计算指定值VAL在二进制表示中最高位的位置。这里使用了一些内置的CMSIS函数,包括__RBIT(反转位顺序)和__CLZ(计算前导零位数)。解释:__RBIT(VAL):反转VAL的位顺序。例如,如果VAL的二进......
  • STM32工具使用--J-Flash烧录程序
            最近客户那边需要给他们烧程序,他们需要把板子给寄给我,我烧写好之后又发回去,这样一来一回就浪费不少时间,而且也比较麻烦,所以最近给它们出了一个如何烧写.hex程序文件的步骤,这样以后就不用再麻烦自己给他们烧写了,他们根据教程就能完成。    我使用的是P......
  • STM32 TIM3 定时器应用之数码管显示定时时间
     实现目标1、STM32基于HAL库定时器的使用;2、加强数码管的学习。一、定时器概述?1、生活中哪些场景会用到定时器?2、STM32F1定时器二、原理图设计三、STM32CubeMX配置1.定时器时钟配置2.定时器3、数码管、蜂鸣器的配置  3.开启定时器3中断四、程序......