第二节: 外部中断学习(用CubeMX学习STM32)

发布者:technology1最新更新时间:2020-05-18 来源: eefocus关键字:外部中断  CubeMX  STM32 手机看文章 扫描二维码
随时随地手机看文章

前言: 关于中断简单介绍

中断的流程:

中断流程图:

在这里插入图片描述

中断方式传送数据具有可以有效提高单片机工作效率, 适合于实时控制系统等优点, 相对于查询方式更为常用。


当CPU处理某件事情的时候, 外部发生的某一事件(如电平的改变、脉冲边沿跳变、定时器/计数器溢出等)请求CPU迅速处理, 于是CPU暂时中断当前的工作, 转去处理发生的事件。 处理完该事件后, 再回到原来中断处, 继续工作。 这样的过程称为中断 上图为中断流程图


这个中断的概念是不是有点晦涩难懂? 主要是这个是书上的内容, 所以不是很形象. 我再解释一遍:想象一个场景,


1、当有一天你正在和川建国同志吃饭(你和他吃饭这个事情就是主程序);

2、突然有个电话打给你, 说有个十五亿的小单子需要你去处理一下(这件事就是中断源),

3、 你停止吃饭, 川建国同志在这等你, 你去处理你的十五亿小合同(就是响应中断请求, 签合同过程就是中断服务程序),

4、处理完合同之后你又回到餐桌继续和他就餐(这就是返回主程序, 然后继续执行主程序).


这样解释是不是清晰一点.

在这里插入图片描述

关于STM32F407的中断介绍可以看一下原子的或者火哥的pdf, 如果实在看得下去, 看官方手册也行。 这里就不赘述, 通过Cube配置以及编程过程理解这个外部中断会好很多, 通过现象再回去看本质


同样的, 还使用前面两篇博客所用到的工程即可, 也可以自己新建一个, 当做对自己的测试


2-1. 使用核心板自带按键

操作简介:通过板子上的两个按钮控制LED灯的亮灭 WK_UP按键按下则进入中断, 并翻转LED0的状态, KEY0按下时翻转LED1的状态. 两者虽然功能一样, 但却有质的区别


这里要做的和按键那一篇一样, 只是把其中一个按键改为中断, 而不是作为GPIO_input 所以可以看完上一篇直接看这一篇继续。 点击下方蓝字可以看上一篇的博客


第一节补充: 按键操作(CubeMX加HAL库学STM32系列)


Step1

RCC&SYS配置这些都不用动, 时钟树的配置也不用动


(1) RCC&SYS以及时钟树配置不用改变

在这里插入图片描述
在这里插入图片描述

(2)更改一下PA0引脚配置:

把WKUP按键对应的PA0引脚模式由GPIO_input改为GPIO_EXIT0, 再把GPIO的配置更改一下即可 具体操作见下图


注 : 如果是用的原来的工程, 只改这个即可, 其他的LED引脚和按键引脚不用动, 如果是自己又新建了一个工程, 那其他引脚按照前面两篇的介绍配置, 然后这个PA0按照这一篇配置就好了, 问题不大

在这里插入图片描述

对应GPIO配置改为下图

在这里插入图片描述

(3)中断NVIC配置

我们设置了中断, 在NVIC里面要记得使能PA0引脚的中断

在这里插入图片描述

NVIC ( Nested Vectored Interrupt Controller ) : 中断向量控制器


在中断向量表里面使能EXIT line0中断


关于抢占优先级和子优先级: 当你使用多个中断的时候会用到这个。 就是为了防止多个中断冲突, 所以需要给他们每个中断排个号, 就不会乱了。 抢占优先级高的先执行, 若抢占优先级相同, 再看子优先级


(4)以上配置完之后就可以Generate CODE

Step2 <程序编写>

(1) 中断服务函数

stm32f4xx_it.c 这个文件里面看到我们要用的中断服务函数

我们要在中断里面做什么事情, 就要写在中断服务函数里面, 然后中断到来之后, 单片机就回去处理中断服务函数里面的工作

在这里插入图片描述

这个函数里面调用了 HAL_GPIO_EXTI_IRQHandler() 这个函数, 这个函数是处理GPIO外部中断的函数 可以看到里面的参数是GPIO_PIN_0, 因为我们用的是PA0即GPIOA的0引脚


Go to definition 一下, 可以看这个函数的定义


/**

  * @brief  This function handles EXTI interrupt request. // 这个功能是处理外部中断请求

  * @param  GPIO_Pin Specifies the pins connected EXTI line // GPIO_Pin指定连接EXTI线的引脚

  * @retval None    // 无返回值

  */

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)

{

  /* EXTI line interrupt detected */

  if(__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != RESET)

  {

    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);     // 清除这个引脚的中断标识位

    HAL_GPIO_EXTI_Callback(GPIO_Pin);       // 回调外部中断

  }

}


综上: 中断服务函数最终会执行中断回调函数 HAL_GPIO_EXTI_Callback()


(2) 中断回调函数

中断回调函数如下图 这个函数是空的, 所以我们可以自己重构这个函数, 在它内部实现我们要做的功能

在这里插入图片描述

我们需要重构中断回调函数

在main.c里面写入我们的代码 :


提示 : 不要忘了把代码写在 /* USER CODE BEGIN / / USER CODE END */ 之间

在这里插入图片描述

/* USER CODE BEGIN 0 */

// 重构中断回调函数  

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

// 判断是否为WKUP引脚(即GPIO_PIN_0)进入中断

if (WKUP_Pin == GPIO_Pin)

{

HAL_GPIO_TogglePin(LED0_GPIO_Port, LED0_Pin); // 翻转LED0的的电平状态

/* 下面这一句话与上面一句是等价的, 因为LED0是我们给这个引脚起的别名, 在main.h文件里面有对应的宏定义     */

//HAL_GPIO_TogglePin(GPIOF, GPIO_PIN_10); 

}

}


/* USER CODE END 0 */


(3) 主函数

在主函数里面用KEY0做一个一样的功能, 作为对比

在这里插入图片描述

  /* USER CODE BEGIN WHILE */

  while (1)

  {

    /* USER CODE END WHILE */


    /* USER CODE BEGIN 3 */

// 在while(1)里面循环扫描, 判断读取的按键引脚状态

// 下面扫描KEY0按键的引脚信号

    if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)

{

HAL_Delay(10); // 延时10ms, 做一个软件的消抖, 防止因抖动而检测到按键按下

if (HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET)

{

// 做一个松手检测, 若KEY0一直是RESET(低电平),则一直在死循环

// 当KEY0位SET才会跳出,进而继续执行下面的对 LED1 的操作

while(HAL_GPIO_ReadPin(KEY0_GPIO_Port, KEY0_Pin) == GPIO_PIN_RESET);

HAL_GPIO_TogglePin(LED1_GPIO_Port, LED1_Pin);

    }

    }

  }

  /* USER CODE END 3 */


(4) 编译下载到单片机, 看看单片机什么反应

在这里插入图片描述

左边的红色按键是WKUP, 左边的蓝色LED是LED0

在这里插入图片描述

仔细看一下动图中的效果可以发现, 中断的WKUP按键的功能并不是很完美, 这是因为没有消抖导致的, 在中断里面加个软件消抖的程序就可以了。


此外, 虽然两种方式实现的功能是一样的, 但是他们的区别就在于, KEY0翻转LED状态实在while(1)循环里面做的,   这就相当于主函数里面一直循环扫描这个按键的状态, 比较耗费资源.


而WKUP按键按下翻转LED是在中断里面做的,不影响主函数里面做其他事情. 如果以后做的东西要求写很多代码, 最好多多利用中断,这样会更高效。只有当事情来了CPU再去处理,其他时间主函数里面正常做其他事情。 这样既能提高MCU效率, 也不会让自己的代码全部写成一坨在主函数里面

关键字:外部中断  CubeMX  STM32 引用地址:第二节: 外部中断学习(用CubeMX学习STM32)

上一篇:第一节:用Cube学32之简单IO口操作(点灯及按键)
下一篇:STM32CubeMX串口配置及库printf打印

推荐阅读最新更新时间:2024-11-10 11:14

stm32专题十六:IIC(二)stm32 IIC通讯过程 标志位
1 IIC进入主模式的步骤: 在主模式时,I 2 C接口启动数据传输并产生时钟信号。串行数据传输总是以起始条件开始并以停止条件结束。当通过START位在总线上产生了起始条件,设备就进入了主模式。 以下是主模式所要求的操作顺序: ● 在I2C_CR2寄存器中设定该模块的输入时钟以产生正确的时序 ● 配置时钟控制寄存器 ● 配置上升时间寄存器 ● 编程I2C_CR1寄存器启动外设 ● 置I2C_CR1寄存器中的START位为1,产生起始条件 2 作为主机发送器时的传送时序图 主发送器发送流程及事件说明如下: (1) 控制产生起始信号(S),当发生起始信号后,它产生事件“EV5”,并会对 SR1 寄存器的“SB”位置 1
[单片机]
<font color='red'>stm32</font>专题十六:IIC(二)<font color='red'>stm32</font> IIC通讯过程 标志位
循环冗余校验技术,以及在STM32中的一些具体使用体会
在嵌入式产品应用中,常常需要应对系统数据在存储或者传输过程中的完整性问题。 所谓完整性是指数据在其生命周期中的准确性和一致性。这些数据可能存储在EEPROM/FLASH里,或者基于通信协议进行传输,它们有可能因为外界干扰或者程序错误,甚至系统入侵而导致被破坏。如果这些数据在使用前不做校验,产品功能可能失效。在一些特定领域,严重时可能会危及用户财产甚至生命安全。 本文就来聊聊使用较为广泛的循环冗余校验技术,以及在STM32中的一些具体使用体会。 所谓循环冗余校验(CRC:Cyclic Redundancy Check)是一种错误检测算法,通常在通信协议中或存储设备中用于检测原始数据的意外变动。可以简单理解成对有用数据按照一定的算法进
[单片机]
循环冗余校验技术,以及在<font color='red'>STM32</font>中的一些具体使用体会
STM32 GPIO 简单操作函数
STM32库函数太多,而且不能识别大小写,经常记错,GPIO简单记忆。 ---第一步--模式配置 void GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE); //对应GPIO所在的总线时钟必须打开 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1; //哪个GPIO口 GPIO_InitStructu
[单片机]
STM32——硬件和软件I2C协议
I2C协议 I2C 通讯协议(Inter-Integrated Circuit)是由 Phiilps 公司开发的,由于它引脚少,硬件实现简单,可扩展性强,不需要 USART、CAN 等通讯协议的外部收发设备,现在被广泛地使用在系统内多个集成电路(IC)间的通讯。 对于通讯协议,我们以分层的方式来理解,最基本的是把它分为物理层和协议层。物理层规定通讯系统中具有机械、电子功能部分的特性,确保原始数据在物理媒体的传输。协议层主要规定通讯逻辑,统一收发双方的数据打包、解包标准。 I2C 物理层 物理层的特点 支持多个通讯主机和多个通信从机。 使用两条线 时钟线(SCL)和数据线(SDA)。 每个连接到总线的设备都有独立
[单片机]
<font color='red'>STM32</font>——硬件和软件I2C协议
STM32 不断进入串口中断问题 解决方法
STM32 有时候会不断进入中断,解决方法如下 1.串口初始化配置时,需要打开ORE 溢出中断,如下红色代码所示 void Usart_Init(void) { GPIO_InitTypeDef GPIO_InitStructure; NVIC_InitTypeDef NVIC_InitStructure; USART_InitTypeDef USART_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); // 开启串口时钟 GPIO_PinA
[单片机]
关于STM32驱动点阵的问题整理及科研思维小酌
之前用51单片机成功将5块级联的16*16点阵成功驱动,闲来无事,沉积内功,用STM32驱动这几个点阵,本觉易事,没想到点阵豆豆竟三天耍脾气,不配合。一筹莫展之际,和别人聊微信,顺手掐断了豆豆的VCC,GND,惊呼哇塞,预期效果。真是无心插柳柳成荫。正预深入测试下去,停电,兴奋若狂,迫不及待,莫非上帝知道问题要揭晓了,急了,连断电的招都使。停电两小时,由缺VCC可正常显示,加VCC反而不亮,已推断出问题范围。入夏的夜,和豆豆玩到10点半,终把豆豆抱。 硬件配置:MCU :STM32,工作电压3.3V; 驱动芯片74HC595; 16*16点阵:五块 问题一:.点阵上电不亮,掉电正常显示 答:74hc595工作电压
[单片机]
STM32中GPIO的8种工作模式
最近在看数据手册的时候,发现在Cortex-M3里,对于GPIO的配置种类有8种之多: (1)GPIO_Mode_AIN 模拟输入 (2)GPIO_Mode_IN_FLOATING 浮空输入 (3)GPIO_Mode_IPD 下拉输入 (4)GPIO_Mode_IPU 上拉输入 (5)GPIO_Mode_Out_OD 开漏输出 (6)GPIO_Mode_Out_PP 推挽输出 (7)GPIO_Mode_AF_OD 复用开漏输出 (8)GPIO_Mode_AF_PP 复用推挽输出 对于刚入门的新手,我想这几个概念是必须得搞清楚的,平时接触的最多的也就是推挽输出、开漏输出、上拉输入这三种,但一直未曾对这些做过归纳。因此,在这里做一个总
[单片机]
<font color='red'>STM32</font>中GPIO的8种工作模式
STM32CubeMX的SDIO模式下对SD卡读写测试
1.问题描述:使用STM32CubeMX,配置SDIO的4bit模式,对SD卡进行读写测试。 2.准备工作: 软件版本:STM32CubeMX–4.22.0 ;KEIL5 硬件平台:原子战舰V3 (1)软件设置: I. SDIO选择,这里选择4bits模式,实际选1bits也可以。 II. 时钟树配置 III. SDIO模式时钟分频设置,其他默认。 其他详细配置请自行打开源码压缩包里的MP3_Test.ioc查看。 (2)Keil工程测试代码: 测试代码参考硬石的HAL库例程,其资料下载地址在最下方。 I.首先是测试要用到的宏定义及变量的声明。 II.接下来是对主函数代码的添加与修改。 III.主要代码段修
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

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

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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