• STM32不使用 cubeMX实现外部中断


    这篇文章将介绍如何不使用 cubeMX完成外部中断的配置和实现。


    前言

    • 实验开发板:STM32F103C8T6。
    • 所需软件:keil5 , cubeMX 。
    • 实验目的:如何不使用 cubeMX实现外部中断 。
    • 实验:使用外部中断控制 key 点亮 led.

    如果大家想了解如何 cubeMX实现外部中断,可以参考我之前的文章:最详细STM32,cubeMX外部中断

    一、文件加入工程

    这里采用封装的思想,将编写的两个文件 exti.c 和 exti.h 放到自己创建的文件夹 user 中。

    1. 将文件夹加入工程。
      点击 KEY 文件夹,右击选择 Manage Project Items.
      在这里插入图片描述
      这里点击新建,命名后,点击 OK 即可。
      在这里插入图片描述
    2. 将 .c 文件加入工程。(双击刚刚创建的文件夹,即可将 .c 文件加入工程)
      在这里插入图片描述
    3. 添加头文件路径。(选择“魔法棒”,选择 C/C++, 点击 “…”)
      在这里插入图片描述
      这里点击 新建,即可加入头文件路径。
      在这里插入图片描述

    二、代码解析

    exti.c

    1. 首先创建一个 GPIO_InitTypeDef 结构体,这个结构体中包含了 端口号,工作模式,是否上拉/下拉电阻等。
    2. 调用 __HAL_RCC_GPIOA_CLK_ENABLE 函数使能端口。(这里按键对应的是 PA0 ,led 对应 PB4, 所以使能 GPIOA ,GPIOB)
    3. 配置 GPIO_InitTypeDef 结构体,调用 HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 函数完成初始化。
    4. 使用 HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0); 设置优先级。使用 HAL_NVIC_EnableIRQ(EXTI0_IRQn); 使能中断。
    5. 发生中断时,先调用 EXTI0_IRQHandler( ) , 执行里面的函数 HAL_GPIO_EXTI_IRQHandler 时,再会自动调用 中断回调函数 HAL_GPIO_EXTI_Callback( uint16_t GPIO_Pin )
    #include "exti.h"
    
    
    /* exti 初始化函数  */
    void exti_Init(void)
    {
      GPIO_InitTypeDef GPIO_InitStruct = {0};
    
      /* GPIO Ports Clock Enable */
      __HAL_RCC_GPIOD_CLK_ENABLE();
      __HAL_RCC_GPIOA_CLK_ENABLE();
      __HAL_RCC_GPIOB_CLK_ENABLE();
    
      /*Configure GPIO pin : PA0 */
      GPIO_InitStruct.Pin = GPIO_PIN_0;
      GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;					// 双边沿触发中断
      GPIO_InitStruct.Pull = GPIO_PULLDOWN;									// 下拉电阻
      HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    
      /*Configure GPIO pin : PB4 */
      GPIO_InitStruct.Pin = GPIO_PIN_4;
      GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
      GPIO_InitStruct.Pull = GPIO_NOPULL;
      GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
      HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
    
      HAL_NVIC_SetPriority(EXTI0_IRQn, 0, 0);
      HAL_NVIC_EnableIRQ(EXTI0_IRQn);
    }
    
    /* 中断处理函数 */
    void EXTI0_IRQHandler()
    {
    	HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
    }
    
    /* 中断回调函数 */
    void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
    {
    	if(GPIO_Pin == GPIO_PIN_0)
    	{
    		key_value = HAL_GPIO_ReadPin(GPIOA,GPIO_PIN_0);
    	}
    }
    
    /* 获取按键的电平状态 */
    uint8_t Get_key(void)
    {
    	return key_value;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50

    exti.h

    这里的 key_value 变量要设置为 静态 static 的,只能在本文件中使用。

    #ifndef _EXTI_H_
    #define _EXTI_H_
    
    
    #include "main.h"
    
    
    static int key_value = 0;
    
    
    void exti_Init(void);
    uint8_t Get_key(void);
    
    
    #endif
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    main.c

    当按键按下时 led 点亮,按键松开时 led 熄灭。

    if(Get_key() == 0)
    {
    	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_SET);
    }
    else if(Get_key() == 1)
    {
    	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_4,GPIO_PIN_RESET);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    注意

    之前我们使用的是 延时函数 HAL_Delay(10); 这里为什么使用 外部中断控制 按键 点亮 led 呢?

    前面我们使用 延时函数进行按键的消抖。但是延时函数在项目工程中最好是少使用,延时函数的大量使用会造成系统的卡顿。所以,这里我们使用外部中断来改进按键消抖

    使用 延时函数消抖的文章我之前写过:最详细STM32,cubeMX 按键点亮 led


    总结

    下篇文章为大家介绍 STM32 的 定时器。

  • 相关阅读:
    SpringBoot项目如何进行打包部署
    压力传感器
    “医药分离”大背景下,连锁药店如何加速扩张
    让DAO再次伟大
    JSP EL关系运算符
    vue里使用elementui的级联选择器el-cascader进行懒加载的怎么实现数据回显?
    免费的mac电脑内存清理工具有哪些?内存不足如何优化
    微信小程序左滑删除(Slideview)
    C++ 语法基础课4 —— 数组
    实例详解在Go中构建流数据pipeline
  • 原文地址:https://blog.csdn.net/wuyiyu_/article/details/133968220