前言

上一节我们学习了单片机独立按键操作,实际上我们采用的是查询的方法,MCU实时检测有无按键按下比较占用MCU资源,本节我们将使用中断的方法实现按键操作。

一、基础知识

1. STM32物联网套件简介

STM32物联网套件目前有两个版本:基础版和高级版,后续会增加应用版本和语音版,核心板均采用STM32F103C8T6核心板,基础版主要元器件如下所示:

高级版版主要元器件如下所示:

STM32物联网套件致力于带领大家入门物联网,不仅学习STM32,也了解转微信小程序开发、物联网服务器后台开发,真正做到了解一个物联网项目的方方面面,基于此,我们定制了一套通用的WIFI通讯协议(可以理解为类似AT指令,不过集成度更高,几条指令就可以直连接云平台),如三条指令连接腾讯云实例。

后续我们会继续增加涂鸦智能、电信云、移动Onenet、阿里云等主流云平台的支持,力争做到,一套STM32代码,通过定制的WIFI模块可以连接到不同的云平台,也欢迎有产品开发需求的朋友私聊我们咨询、定制物联网方案!

本套物联网套件可以支持大学生参加物联网相关比赛、申请学校大创项目、完成毕业设计等,我们的定位是做一家开源智能硬件服务商,和大家一起探索物联网,我们的使命是推动更多物联网产品的落地和普及,让技术不再是阻碍!

2.中断简介

中断是指CPU在执行A事件的时候,突然收到B事件发出的(中断)请求,CPU停止手中的事情,转而去执行B事件,B事件执行完毕后,又回到原来A事件被打断的地方,继续执行程序的过程,示意图如下所示:

STM32单片机使用NVIC(嵌套向量中断控制器)来管理中断,主要有三部分:中断使能、抢占优先级设置、响应优先级设置,注意:优先级数值越小,优先级别越高;

其中中断使能控制中断是否打开,抢占优先级用来判断中断是否可以相互打断,高抢占优先级可以打断低抢占优先级(低抢占优先级任务正在执行时候来了高抢占优先级中断,系统会暂停执行当前任务,转去执行高抢占优先级任务,执行完毕后继续返回执行低抢占优先级任务)。

当两个中断抢占优先级相同时候,系统会根据相应优先级的高低选择执行任务,

3.中断优先级分组

问题来了,已经说到STM32单片机可以使用NVIC管理诸多中断,那么STM32一共有多少个中断呢? 我们打开startup_stm32f103xb.s启动文件中中断向量表分配,如下:

__Vectors       DCD     __initial_sp               ; Top of StackDCD     Reset_Handler              ; Reset HandlerDCD     NMI_Handler                ; NMI HandlerDCD     HardFault_Handler          ; Hard Fault HandlerDCD     MemManage_Handler          ; MPU Fault HandlerDCD     BusFault_Handler           ; Bus Fault HandlerDCD     UsageFault_Handler         ; Usage Fault HandlerDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     0                          ; ReservedDCD     SVC_Handler                ; SVCall HandlerDCD     DebugMon_Handler           ; Debug Monitor HandlerDCD     0                          ; ReservedDCD     PendSV_Handler             ; PendSV HandlerDCD     SysTick_Handler            ; SysTick Handler; External InterruptsDCD     WWDG_IRQHandler            ; Window WatchdogDCD     PVD_IRQHandler             ; PVD through EXTI Line detectDCD     TAMPER_IRQHandler          ; TamperDCD     RTC_IRQHandler             ; RTCDCD     FLASH_IRQHandler           ; FlashDCD     RCC_IRQHandler             ; RCCDCD     EXTI0_IRQHandler           ; EXTI Line 0DCD     EXTI1_IRQHandler           ; EXTI Line 1DCD     EXTI2_IRQHandler           ; EXTI Line 2DCD     EXTI3_IRQHandler           ; EXTI Line 3DCD     EXTI4_IRQHandler           ; EXTI Line 4DCD     DMA1_Channel1_IRQHandler   ; DMA1 Channel 1DCD     DMA1_Channel2_IRQHandler   ; DMA1 Channel 2DCD     DMA1_Channel3_IRQHandler   ; DMA1 Channel 3DCD     DMA1_Channel4_IRQHandler   ; DMA1 Channel 4DCD     DMA1_Channel5_IRQHandler   ; DMA1 Channel 5DCD     DMA1_Channel6_IRQHandler   ; DMA1 Channel 6DCD     DMA1_Channel7_IRQHandler   ; DMA1 Channel 7DCD     ADC1_2_IRQHandler          ; ADC1_2DCD     USB_HP_CAN1_TX_IRQHandler  ; USB High Priority or CAN1 TXDCD     USB_LP_CAN1_RX0_IRQHandler ; USB Low  Priority or CAN1 RX0DCD     CAN1_RX1_IRQHandler        ; CAN1 RX1DCD     CAN1_SCE_IRQHandler        ; CAN1 SCEDCD     EXTI9_5_IRQHandler         ; EXTI Line 9..5DCD     TIM1_BRK_IRQHandler        ; TIM1 BreakDCD     TIM1_UP_IRQHandler         ; TIM1 UpdateDCD     TIM1_TRG_COM_IRQHandler    ; TIM1 Trigger and CommutationDCD     TIM1_CC_IRQHandler         ; TIM1 Capture CompareDCD     TIM2_IRQHandler            ; TIM2DCD     TIM3_IRQHandler            ; TIM3DCD     TIM4_IRQHandler            ; TIM4DCD     I2C1_EV_IRQHandler         ; I2C1 EventDCD     I2C1_ER_IRQHandler         ; I2C1 ErrorDCD     I2C2_EV_IRQHandler         ; I2C2 EventDCD     I2C2_ER_IRQHandler         ; I2C2 ErrorDCD     SPI1_IRQHandler            ; SPI1DCD     SPI2_IRQHandler            ; SPI2DCD     USART1_IRQHandler          ; USART1DCD     USART2_IRQHandler          ; USART2DCD     USART3_IRQHandler          ; USART3DCD     EXTI15_10_IRQHandler       ; EXTI Line 15..10DCD     RTC_Alarm_IRQHandler        ; RTC Alarm through EXTI LineDCD     USBWakeUp_IRQHandler       ; USB Wakeup from suspend
__Vectors_End

其中从Reset_Handler开始,一直到SysTick_Handler,总计10个, 为不可屏蔽中断,属于内核中断,其余中断为外部中断,而NVIC就是管理外部中断的,接下来我们看下中断优先级分组

举个例子:

设置分组1,中断3(RTC)的抢占优先级为1,响应优先级为0,中断7(外部中断1)的抢占优先级为1,响应优先级为2,中断8(外部中断2)的抢占优先级为0,响应优先级为2,则三个中断优先级为:中断8 > 中断3 > 中断7。

4.按键检测原理

简单的独立按键连接电路原理图如下所示

独立按键电路中,按键一边接GND,另一边接到单片机IO口上,当按键按下时候,按键两边1和2导通,单片机P2.5引脚直接连接GND,电平为低电平,所以只需要让单片机不断的检测P2.5引脚的I/O口是否为低电平,一旦程序检测到I/O口引脚变为低电平说明按键按下了。

4. 硬件设计

本次按键实验按键部分原理图如下,按键一端引脚均接地,另一端接到单片机PB4,当按键按下时候PB4为低电平。

实物图如下所示:

其中,PB12引脚输出低电平可以点亮LED灯,当按键按下时候,单片机检测到下降沿中断,PB4引脚为低电平,点亮LED灯。

二、实例

1. 新建工程

使用STM32CubeMX创建一个新的工程,参考环境搭建章节配置方式,设置RCC和PB12引脚输出,PB4为GPIO_EXIT4

设置中断触发方式为下降沿

使能NVIC配置中断优先级分组4,并使能EXIT line4中断,GPIO设置抢占优先级为2

进入Clock configuration页面,选择HSE时钟源,倍频后主时钟为72MHz

切换到Project Manager栏目,设置工程名字、工程保存目录、工具链等信息,具参数如下图所示

点击左边栏目Code Generator,然后勾选Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral,勾选此选项,外设将单独保存在一个文件中,而不是全部都在main.c中。

2.函数说明

(1) 首先查看下gpio.c中MX_GPIO_Init()函数

void MX_GPIO_Init(void)
{GPIO_InitTypeDef GPIO_InitStruct = {0};/* GPIO Ports Clock Enable */__HAL_RCC_GPIOC_CLK_ENABLE();__HAL_RCC_GPIOD_CLK_ENABLE();__HAL_RCC_GPIOB_CLK_ENABLE();__HAL_RCC_GPIOA_CLK_ENABLE();/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOC, GPIO_PIN_13, GPIO_PIN_RESET);/*Configure GPIO pin Output Level */HAL_GPIO_WritePin(GPIOB, GPIO_PIN_12, GPIO_PIN_RESET);/*Configure GPIO pin : PC13 */GPIO_InitStruct.Pin = GPIO_PIN_13;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_NOPULL;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);/*Configure GPIO pin : PB12 */GPIO_InitStruct.Pin = GPIO_PIN_12;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);/*Configure GPIO pin : PB4 */GPIO_InitStruct.Pin = GPIO_PIN_4;GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/* EXTI interrupt init*/HAL_NVIC_SetPriority(EXTI4_IRQn, 2, 0);HAL_NVIC_EnableIRQ(EXTI4_IRQn);}

在GPIO初始化函数中,首先使能GPIOB时钟,然后初始化PB12 PB13为输出模式,PB4为输入模式,中断操作NVIC配置中断优先级,并使能EXTI4_IRQn中断;EXTI是外部中断/事件控制器,一共管理20个中断/事件线,每个中断/事件线都对应一个边沿检测器,可单独配置为中断或者事件,中断/事件线具体对应关系如下:

(2) 中断处理函数
当中断来临时候,会进入上文中断向量表对应的void EXTI4_IRQHandler(void)函数,函数在stm32f1xx_it.c中

/*** @brief This function handles EXTI line4 interrupt.*/
void EXTI4_IRQHandler(void)
{/* USER CODE BEGIN EXTI4_IRQn 0 *//* USER CODE END EXTI4_IRQn 0 */HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);/* USER CODE BEGIN EXTI4_IRQn 1 *//* USER CODE END EXTI4_IRQn 1 */
}

打开stm32f1xx_hal_gpio.c,HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)定义如下:

/*** @brief  This function handles EXTI interrupt request.* @param  GPIO_Pin: Specifies the pins connected EXTI line* @retval None*/
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);}
}/*** @brief  EXTI line detection callbacks.* @param  GPIO_Pin: Specifies the pins connected EXTI line* @retval None*/
__weak void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{/* Prevent unused argument(s) compilation warning */UNUSED(GPIO_Pin);/* NOTE: This function Should not be modified, when the callback is needed,the HAL_GPIO_EXTI_Callback could be implemented in the user file*/
}

当确认外部中断线4发生中断时候,系统会调用HAL_GPIO_EXIT_Callback(uint16_t GPIO_Pin)函数,该函数为一个__weak函数,用户可以在应用层重写该函数,如果用户忘记定义了,系统也不会报错,会进入这个__weak函数,但是什么也不执行

3. 修改程序

在gpio.c中重定义 void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)函数

volatile int key_flag= 0;void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{// 按键按下key_flag = 1;
}

在main.c中根据中断处理函数标志位,做进一步处理,当按键按下时候按键标志清零,翻转LED灯

/* USER CODE BEGIN 0 */
extern volatile int key_flag;
/* USER CODE END 0 *//*** @brief  The application entry point.* @retval int*/
int main(void)
{/* USER CODE BEGIN 1 *//* USER CODE END 1 *//* MCU Configuration--------------------------------------------------------*//* Reset of all peripherals, Initializes the Flash interface and the Systick. */HAL_Init();/* USER CODE BEGIN Init *//* USER CODE END Init *//* Configure the system clock */SystemClock_Config();/* USER CODE BEGIN SysInit *//* USER CODE END SysInit *//* Initialize all configured peripherals */MX_GPIO_Init();/* USER CODE BEGIN 2 *//* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */if ( key_flag ){HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_12);key_flag = 0;}HAL_Delay(10); }/* USER CODE END 3 */
}

三、下载运行

按照环境搭建章节方式给核心板下载程序,可以看到每次按下按键,红色LED灯点亮或者熄灭。

四、小结

如您在使用过程中有任何问题,请加QQ群进一步交流。

QQ交流群:906015840 (备注:物联网项目交流)

源码获取:关注公众号,回复xiaoyi_stm32kits获取资料

硬件获取:某宝搜索小驿物联

小驿物联出品:宁愿做过了后悔,也不要后悔没去做!

STM32物联网套件基础版05-外部中断相关推荐

  1. 【STM32标准库】【基础知识】外部中断

    文章目录 外部中断 什么是外部中断 外部中断的触发 上升沿触发 下降沿触发 上升下降沿触发 外部中断初始化 初始化思路 1.初始化GPIO 2. 打开时钟 3.GPIO和外部中断的连接 4.外部中断初 ...

  2. 笔记:STM32——IO口的复用功能外部中断

    在STM32里面一般有五组寄存器分别是A--E组,每组寄存器的端口基本都有复用功能,这样可以使得端口的不被浪费,而达到极致利用. 使用复用端口的时候需要打开AFIO的时钟才能使用IO口的复用端口.每个 ...

  3. STM32学习笔记(三)——外部中断的使用

    开发板芯片:STM32F407ZGT6 硬件连接:PE3-KEY1 一.STM32F4的中断介绍 STM32F4的每个IO都可以作为外部中断输入,很强大的功能吧!以前学习的51只有两个外部中断. ST ...

  4. STM32学习笔记(三)——外部中断的使用 1

    开发板芯片:STM32F407ZGT6 硬件连接:PE3-KEY1 一.STM32F4的中断介绍 STM32F4的每个IO都可以作为外部中断输入,很强大的功能吧!以前学习的51只有两个外部中断. ST ...

  5. 单片机基础知识点 05 (中断-1)

    一.中断概念 先来了解中断的概念,我们拿生活中举个例子,就比如你原本在洗衣服,洗着洗着水开了,这时候你跑过去把关火,把水灌入水瓶后,在回来洗衣服,那么这个过程实际上就是发生一次中断. 对单片机来讲,中 ...

  6. STM8L探索套件学习笔记-EXTI外部中断

    http://blog.chinaunix.net/uid-23085164-id-3534045.html

  7. STM32 外部中断详解(原理+配置代码)

    本文介绍了STM32基于标准外设库的外部中断配置,以及基于参考手册如何更加寄存器配置外部中断 文章目录 1 前言 2 STM32的外部中断 3 中断服务函数的映射关系 4 外部中断的配置 5 寄存器的 ...

  8. STM32外部中断总结

    STM32外部中断总结 STM32的外部中断是我们在学习stm32的一个必要模块,外部中断的用途可以增加人机交互的体验,也可以增加程序的执行效率.下面将以一个小实验来记录外部中断的使用需要注意的事项 ...

  9. STM32 基础系列教程 3 – 外部中断

    前言 学习stm32 GPIO 的外部中断使用,用中断模式实现简单的按键输入功能,用按实现基础实验二中的LED亮灭切换功能! 示例详解 基于硬件平台: STM32F10C8T6最小系统板, MCU 的 ...

最新文章

  1. LeetCode 547. Friend Circles--Python解法--笔试算法题
  2. spring配置文件中分别使用多个properties文件
  3. linux守护进程原理及创建详解
  4. esp32树莓派_用 ESP32 制造炫彩 LED 球
  5. 眨眼算什么,让蒙娜丽莎像你一样唠上嗑才算硬核
  6. S4 KNUMH的设计原理
  7. EasyDarwin开源手机直播方案:EasyPusher手机直播推送,EasyDarwin流媒体服务器,EasyPlayer手机播放器...
  8. Windows Phone 7 XNA触控操作之Gestures
  9. 数据之路 - Python爬虫 - PySpider框架
  10. 春季:@Component与@Bean
  11. (转)android studio工程编译不出来的一些error
  12. CISCO 模拟器 Dynamips 使用说明
  13. SpringCloud第十章zuul路由网关
  14. 2012年读书年度小结
  15. WebSphere 异常问题记录
  16. C# 类库组件在工具箱不显示问题
  17. Flask:工厂函数和蓝本
  18. 若依后台实现表连接查询显示,一对一查询
  19. 项管行知02--工作环境
  20. 详解爬电距离和电气间隙

热门文章

  1. 服务器命令提示符修复,怎么用命令提示符来修复XP系统
  2. 深入理解 V8 的 Call Stack
  3. EI会议推荐-计算机主题
  4. 无需下载, HTML5版QQ斗地主正式上线
  5. 在idea中部署远程Tomcat
  6. 企业文档加密软件选择标准是什么
  7. 如何从零开始架设邮件服务器
  8. JAVA超市进销存管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
  9. html video各种控制命令,HTML Video controls用法及代码示例
  10. Noah Mt4跟单系统制作第三篇 Mt4TradeApi获取报价篇