历史上的今天
返回首页

历史上的今天

今天是:2025年05月18日(星期日)

正在发生

2020年05月18日 | 第二节: 外部中断学习(用CubeMX学习STM32)

2020-05-18 来源:eefocus

前言: 关于中断简单介绍

中断的流程:

中断流程图:

在这里插入图片描述

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


当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效率, 也不会让自己的代码全部写成一坨在主函数里面

推荐阅读

史海拾趣

Electric Imp Inc.公司的发展小趣事

随着第一款产品的成功,Electric Imp Inc.公司开始积极拓展市场。公司与多家知名厂商建立了合作关系,将物联网设备管理平台应用于智能家居、工业自动化、智慧城市等领域。同时,公司还加强了与高校、科研机构的合作,共同研发新技术、新产品。这些努力使得公司在物联网领域的影响力逐渐扩大。

Electro Technik Industries公司的发展小趣事

随着公司规模的扩大和产品线的增加,ETI开始注重品质管理。公司建立了一套完善的品质管理体系,从原材料采购到生产过程再到成品检验都严格把关。同时,ETI还积极推行精益生产、六西格玛等先进管理方法,提高了生产效率和产品质量。这些措施使ETI的产品在市场上获得了良好的口碑和信誉。

硕颉(BITEK)公司的发展小趣事

硕颉科技高度重视知识产权保护,积极申请专利。截至2015年10月,公司已取得台湾63件、美国52件、中国大陆24件、日本4件及韩国10件等共153件专利。这些专利的取得,不仅为公司的技术创新提供了法律保障,也进一步巩固了公司在行业内的竞争地位。

Falco Electronics公司的发展小趣事

Falco Electronics非常重视企业文化建设。公司倡导“以人为本”的管理理念,注重员工的成长和发展。公司为员工提供了良好的工作环境和福利待遇,还定期开展各种培训活动,帮助员工提升技能水平。这种良好的企业文化吸引了大量优秀人才的加入,也为公司的持续发展提供了有力保障。

Alpha (Taiwan)公司的发展小趣事

随着数字化时代的到来,Alpha (Taiwan)公司紧跟时代步伐,积极推动数字化转型。公司引进先进的数字化设备和技术,对生产线进行智能化改造,提高了生产效率和产品质量。同时,公司还加强了对大数据、云计算等技术的应用,实现了对市场需求、客户反馈等信息的实时分析和处理。这些数字化转型的举措,不仅提升了公司的竞争力,也为公司的未来发展奠定了坚实的基础。

请注意,这些故事是基于一般情况和行业趋势构建的,并非Alpha (Taiwan)公司的实际经历。要了解Alpha (Taiwan)公司的真实发展故事,建议查阅相关公司的官方资料、新闻报道或行业分析报告。

EREM公司的发展小趣事

近年来,随着科技的快速发展和电子行业的变革,EREM公司也面临着巨大的挑战。为了应对这些变革,EREM积极调整战略方向,加大研发投入,推出了一系列符合市场需求的新产品。同时,EREM还注重人才培养和团队建设,打造了一支高效、专业的团队,为公司的发展提供了有力保障。

问答坊 | AI 解惑

几个电源单双变换的原理图

应友人之邀,发几个电源单双变换的图纸,PROTEL99SE格式和JPG格式…

查看全部问答>

ise10和11通用破解

如题所示,平常不涉及到商业的研究完全可以使用破解嘛,方便…

查看全部问答>

在wince6.0平台上如何将模拟器中任务栏上的软键盘的位置调整到桌面上的任意一个位置?

在wince6.0界面下,将生成的模拟器界面中的任务栏上的软键盘的位置调整到桌面上的任意一个位置,该如何操作?谢谢!…

查看全部问答>

ARM和STM32的区别是什么?

  怎么看两种都是一个样,而且很多开发板也是一样的,我懂一点单片机,请哪位高手抽空说明一下,解惑啊…

查看全部问答>

SDRAM

EMIF工作在133MHZ可以接166MHZ的SDRAM吗?…

查看全部问答>

【求助】msp430内部液晶模块怎么用?

各位大侠,我在用msp430f449内部液晶模块,但是不知道要显示的数据怎么编码的。看书上程序要显示0123456,设置4MUX方式驱动,显示缓存的数据LCDMEM[0]~LCDMEM[6]分别为0xb7,0x12,0x8f,0x1f,0x3a,0x3d,0xbd,请问大侠这些数据是怎么编码得到的啊?如 ...…

查看全部问答>

LM3S811开发板学习笔记---使用openocd(基于mingw)调试LM3S811开发板环境的搭建

收到网站的LM3S811开发板,不能放那浪费了。因本人在linux环境下开发的较多,对keil和iar等环境也不是很熟悉而且他们是商业软件,使用D版毕竟不太好,这里就以如何使用开源的openocd调试器来下载,仿真LM3S811开发板为起点来系统学习下这个芯片。附 ...…

查看全部问答>

LM3S9B96 在使用PLL作为主时钟 66.7M比50M慢

刚才在开发板上移植了ucos2. 然后顺手改了下时钟分频,发现可以到100M。于是就看了下在100M下idle任务的OSIdleCtrMax的值。   SysCtlClockSet(SYSCTL_SYSDIV_4| SYSCTL_USE_PLL | SYSCTL_XTAL_16MHZ |       ...…

查看全部问答>

阻塞与非阻塞

always @(a or b or c) begin     x=c+y;//语句1     y=a+b;//语句2 end    y原来的值是5; a=1; b=1; c=3; 我仿真的结果是 x=5+3=8    y=1+1=2 资料上的解释是说 语 ...…

查看全部问答>

【连载】【ALIENTEK 战舰STM32开发板】STM32开发指南--第十五章 输入捕获实验

第十五章 输入捕获实验上一章,我们介绍了STM32的通用定时器作为PWM输出的使用方法,这一章,我们将向大家介绍通用定时器作为输入捕获的使用。在本章中,我们将用TIM5的通道1(PA0)来做输入捕获,捕获PA0上高电平的脉宽(用WK_UP按键输入高电平) ...…

查看全部问答>