Stm32CubeMX+Proteus仿真--STM32外部中断

Stm32CubeMX+Proteus仿真入门

文章仿真和代码下载链接:

我用夸克网盘给你分享了「第9章 STM32外部中断」,点击链接或复制整段内容,打开「夸克APP」即可获取。

/78893YWbPG😕

链接:https://pan.quark.cn/s/86b268349691

第 九 章

1、外部中断

1.1中断基础及NVIC介绍

中断

中断其实就是当 CPU 执行程序时,由于发生了某种随机的事件(外部或内部),引起 CPU 暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程就称为中断,引发中断的称为中断源。如果在执行低级中断的过程发生高级中断,CPU将优先执行高级中断服务程序。举个栗子,你在宿舍准备午睡了,发现有个很喜欢的快递到了,于是你打算晚点睡去拿快递先,去的路上遇到了女同学拖着个大快递步履阑珊找你帮忙,你于心不忍先帮她扛到她宿舍楼下再去拿你自己的快递然后回宿舍睡觉。这个过程,原本执行的主程序就是睡觉,去拿自己的快递就是低级中断,帮助女同学就是高级中断。完成高级中断请求再完成低级中断然后执行主程序。

NVIC

NVIC 英文全称是 Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于 M3 内核的一个外设,控制着芯片的中断相关功能。由于 ARM 给 NVIC 预留了非常多的功能,但对于使用 M3 内核设计芯片的公司可能就不需要这么多功能,于是就需要在 NVIC 上裁剪。ST 公司的 STM32F103 芯片内部中断数量就是 NVIC 裁剪后的结果。Crotex-M3 内核支持 256 个中断,其中包含了 16 个内核中断和 240 个外部中断。但 STM32 并没有使用 M3 内核的全部东西,而是只用了它的一部分。

STM32F10x 芯片有 84 个中断通道,包括 16 个内核中断和 68 个可屏蔽中断,对于STM32F103系列芯片只有60个可屏蔽中断,在 STM32F107 系列才有 68 个。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。这些中断通道已按照不同优先级顺序固定分配给相应的外部设备。从 STM32F10x 中文参考手册的中断向量表可以知道具体分配到那些外设,这里只截取一部分,如需了解更详细可参考《STM32F10x 中文参考手册》-9 中断和事件章节内容,中断向量表。

只有当两个中断函数优先级一致的时候,才会通过中断向量表的优先级大小来进行判断,优先级小的先执行。

如下图所示

1.2中断优先级

前面说了 STM32F103 芯片支持 60 个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8 位,理论上每个外部中断优先级可以设置为0-255,数值越小,优先级越高。但是 STM32F103 中只使用 4 位,高 4 位有效),用于表达优先级的高 4 位又被分组成抢占式优先级和响应优先级。

STM32F103 中指定中断优先级的寄存器位有 4 位,这 4 位的分组方式如下图所示

NVIC优先级分组 NVIC_IRQ抢占优先级 NVIC_IRQ子优先级 描述

NVIC_PriorityGroup_0 0 0~15 抢占优先级0位,子优先级4位

NVIC_PriorityGroup_1 0~1 0~7 抢占优先级1位,子优先级3位

NVIC_PriorityGroup_2 0~3 0~3 抢占优先级2位,子优先级2位

NVIC_PriorityGroup_3 0~7 0~1 抢占优先级3位,子优先级1位

NVIC_PriorityGroup_4 0~15 0 抢占优先级4位,子优先级0位

第 0 组:所有 4 位用于指定响应优先级

第 1 组:最高 1 位用于指定抢占式优先级,最低 3 位用于指定响应优先级

第 2 组:最高 2 位用于指定抢占式优先级,最低 2 位用于指定响应优先级

第 3 组:最高 3 位用于指定抢占式优先级,最低 1 位用于指定响应优先级

第 4 组:所有 4 位用于指定抢占式优先级

总结:以上所说的中断知识,一头雾水也没关系,先自己使用过中断再回头看才会比较理解。用stm32cubemx做初始化,注意以下步骤即可。

\1. 配置中断源

\2. 设置中断优先级分组

\3. 编写中断服务函数

配置好中断后如果有触发,即会进入中断服务函数,那么中断服务函数也有固定的函数名,可以在 startup_stm32f10x_md.s 启动文件查看。不要任意修改中断服务函数名,因为启动文件内中断服务函数名已经固定。

下面用外部中断做例子,其他中断如定时器会在对应的章节做具体讲解。

1.3EXIT外部中断/事件控制器

1、特性

对于互联型产品,外部中断/事件控制器由20个产生事件/中断请求的边沿检测器组成,对于其它产品,则有19个能产生事件/中断请求的边沿检测器。每个输入线可以独立地配置输入类型(脉冲或挂起)和对应的触发事件(上升沿或下降沿或者双边沿都触发)。每个输入线都可以独立地被屏蔽。挂起寄存器保持着状态线的中断请求。

EXTI特性在芯片参考手册中的描述如下:

● 每个中断/事件都有独立的触发和屏蔽

● 每个中断线都有专用的状态位

● 支持多达20个软件的中断/事件请求

● 检测脉冲宽度低于APB2时钟宽度的外部信号。参见数据手册中电气特性部分的相关参数。

这个20表示有20个事件/中断线,这个与上面提到的EXTI的特性相关,这20个线分别对应的事件/中断请求如下:

EXTI0EXTI15:GPIOx_Pin0GPIOx_Pin15,其中x表示A~I;

EXTI16:PVD输出;

EXTI17:RTC闹钟事件;

EXTI18:USB唤醒事件;

EXTI19:以太网唤醒事件(只使用互联型);

本章节重点介绍外部中断,外部事件忽略。通用I/O端口以下图的方式连接到16个外部中断/事件线上。

EXIT0可以设置为PA0 PB0 PC0等GPIO的0号引脚,同理其他中断线也是可以配置的。

1.4硬件设计

PA0和PA1接到LED灯,按键分别接到PA12-PA15,分别取别名为KEY4-KEY1。LED灯控制脚设置为推挽输出,按键控制脚设置为上拉输入。4 个独立按键的控制管脚连接到单片机的PA12-PA15脚上。其中 K1 连接在PA15上,K2 连接在PA14上,K3 连接在PA13上,K4 连接在PA14上。4 个按键另一端全部连接在 GND,当按键按下后,对应 IO 口即为低电平。

1.5工程代码配置

复制第7章工程代码,基于此基础上做修改,主要包括以下几点:

设置引脚为外部中断下降沿触发External Interrupt Mode with Falling edge trigger detection

配置NVIC

选中"NVIC"(Nested Vectored Interrupt Controller, 嵌套向量中断控制器),勾选列表中"EXTI line [15-10] interrupts的Enable。将页面上方的优先级组"Priority Group"选为2 bits for pre-emption priority 2 bits for subpriority,即抢占优先级和响应优先级都用2bit来设定。

这需要注意一点除了EXIT0-EXIT4是单独的中断源有独自的中断地址,EXIT5-9共用一个中断源,EXIT10-15共用一个中断源。

配置完成点生成代码

代码编写:

1.本次我们需要实现外部中断,由前面电路知道,当按下按键时,会生成下降沿,只要将相应的GPIO设置为EXTI模式,就会自动触发外部中断。进入中断后实现的功能,不是写在主函数中,而是写在外部中断的回调函数中。

2.Keil中打开工程,双击"main.c"文件。

3.本次仿真我们用到EXTI线侦测回调函数HAL_GPIO_EXTI_Callback(),这个回调函数可以在"stm32f1xx_hal_gpio.c"程序中找到,这里的回调函数前面有一个"弱函数"的关键字"_weak",该关键字的作用是,如果工程的任何一个源文件中都没有与该"弱函数"同名的函数,则编译器会编译该"弱函数";但是当工程中有另一个同名函数定义出现时,编译器会忽略"弱函数"而编译另一个没有标注"_weak"关键字的同名函数。

复制代码
__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.我们在/* USER CODE BEGIN 4 /和/ USER CODE END 4 */间添加这个回调函数。

复制代码
/* USER CODE BEGIN 4 */

/*中断回调函数*/

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

 if(GPIO_Pin == GPIO_PIN_12)  /*检测到EXTI12线产生外部中断事件*/

 {

   LED1=0;

 }

 else if(GPIO_Pin == GPIO_PIN_13) /*检测到EXTI13线产生外部中断事件*/

 {

   LED1=1;

 }

  else if(GPIO_Pin == GPIO_PIN_14) /*检测到EXTI14线产生外部中断事件*/

 {

   LED2=0;

 }

  else if(GPIO_Pin == GPIO_PIN_15) /*检测到EXTI15线产生外部中断事件*/

 {

   LED2=1;

 }

 

}

/* USER CODE END 4 */

5.编译产生新的hex文件,proteus仿真更新hex路径。

实验现象:KEY4控制LED1熄灭,KEY3控制LED1点亮,KEY2控制LED0熄灭,KEY1控制LED0点亮。

相关推荐
森利威尔电子-2 小时前
森利威尔SL8700 降压型大功率 LED 恒流驱动器:5A/95%效率,支持 PWM/模拟调光
单片机·嵌入式硬件·集成电路·芯片·电源芯片
三佛科技-187366133973 小时前
GP8892SEH贴片SOP7省外围5V2A隔离型原边反馈芯片直接替代MT3723
单片机·嵌入式硬件
Quinn273 小时前
正点原子 STM32MP257 修复异核 FreeRTOS 例程 osDelay() 函数比 HAL_Delay() 延时快的问题
stm32·单片机·嵌入式硬件
周周记笔记3 小时前
【元器件专题】三极管性能
单片机·嵌入式硬件
23124_806 小时前
【无标题】
单片机·嵌入式硬件
ytttr8736 小时前
STM32 读写 SD 卡源码(SPI 模式 + FATFS 文件系统)
stm32·单片机·嵌入式硬件
Quinn277 小时前
正点原子 STM32MP257 修复异核 FreeRTOS+OpenAMP 例程里 SysTick 延时异常的问题
stm32·嵌入式硬件·正点原子·arm linux
Deitymoon7 小时前
STM32——OLED显示图片
stm32·单片机·嵌入式硬件
山木嵌入式7 小时前
STM32 UART串口通信协议与3种底层驱动实现(寄存器/标准库/HAL库)
stm32·单片机·串口·uart