单片机第三季-第七课:STM32中断体系

目录

1,NVIC

2,中断和事件的区别

3,优先级的概念 

4,如何实际编程使用外部中断

5,STM32开发板通过按键控制LED 

5.1,打开相应GPIO模块时钟

5.2,NVIC设置

5.3,外部中断线和配套的GPIO进行连接映射

5.4,代码文件 

6,FSMC


1,NVIC

NVIC: Nested Vector Interrupt Control,嵌套向量中断控制器;

68个可屏蔽中断通道。

数据手册得向量表结合起始代码查看: 

可以理解为数组里(__Vectors )定义了数据类型为DCD的许多个元素。

下边图中可理解为复位时调用Reset_Handler函数,先执行SystemInit,然后执行__main: 

本章节我们关注的是外部中断相关的内容: 

起始代码中为我们提供了中断函数默认的执行程序,即下图中的 B    . ,其含义即是C中的while(1)。

起始文件中的这些函数属性是[WEAK],即弱函数。 

始代码文件是用汇编语言编写,[WEAK]标志代表该函数是弱函数,如果在其它地方定义这些函数则以定义的函数执行,也就是不再执行默认的while(1)函数,如果没有在其它地方定义则以起始文件中的函数为准。

起始代码的作用可以认为是建立了中断向量表,中断向量表是软件实现的,但是是由硬件决定的。

即下图中的地址是硬件设计时就决定了的。

中断要配置使能,中断处理程序要清中断挂起。

2,中断和事件的区别

中断需要CPU参与,事件不需要CPU参与,中断使用CPU处理程序比较灵活,事件不需要CPU参与通过产生脉冲直接与外设交互,可以节省CPU资源。

3,优先级的概念 

抢占优先级 NVIC_IRQChannelPreemptionPriority

子优先级 NVIC_IRQChannelSubPriority

级别的数字越小,优先级越高。

抢占优先级内部划分子优先级,同一抢占优先级内的中断子优先级必须不同。

优先级为0的抢占优先级可以打断优先级为1的抢占优先级。

同一抢占优先级内等级为0的子优先级中断不能打断等级为1的子优先级中断,只有两个不同子优先级的中断同时发生时,子优先级高的中断才会处于优先地位。

4,如何实际编程使用外部中断

 
(1)时钟设置并打开相应GPIO模块时钟
(2)将相应GPIO配置为浮空输入
(3)NVIC设置
(4)将外部中断线和配套的GPIO进行连接映射
(5)外部中断线使能触发
(6)准备好ISR,并在ISR处等待执行中断程序即可

在下一节中通过相应的代码对应对上述步骤。

5,STM32开发板通过按键控制LED 

中断相关标准库代码在misc.c中,misc是miscellaneous(杂项)的缩写。 

在51单片机中已经通过使用中断,通过识别外部按键操作来控制LED灯。本节在STM32开发板上,通过使用标准库中的中断函数来控制LED灯,达到的效果为:按一个按键打开LED灯,按另一个按键关闭这个LED灯,主程序中控制另外一个LED灯闪烁。

5.1,打开相应GPIO模块时钟

本例中按键使用PIN角为PB8和PB9连接按键,所以要使能GPIOB端口所在的APB2总线时钟,LED灯使用PA0和PA。

对应的标准库函数是stm32f10x_rcc.c文件中的RCC_APB2PeriphClockCmd(),要使能该总线时钟,对应的命令如下:

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);

5.2,NVIC设置

第一步,优先级组设置,设置有几个抢占优先级,以及有几个子优先级

对于抢占优先级和子优先级,因为本例中通过按键控制LED灯只需要识别一个中断,因此抢占优先级和子优先级可以随意设置,即NVIC_PriorityGroupConfig()函数的输入参数可以设置下列代码中的任意值,对于具体的项目可以根据中断个数和优先级进行设置。 

/*** @brief  Configures the priority grouping: pre-emption priority and subpriority.* @param  NVIC_PriorityGroup: specifies the priority grouping bits length. *   This parameter can be one of the following values:*     @arg NVIC_PriorityGroup_0: 0 bits for pre-emption priority*                                4 bits for subpriority*     @arg NVIC_PriorityGroup_1: 1 bits for pre-emption priority*                                3 bits for subpriority*     @arg NVIC_PriorityGroup_2: 2 bits for pre-emption priority*                                2 bits for subpriority*     @arg NVIC_PriorityGroup_3: 3 bits for pre-emption priority*                                1 bits for subpriority*     @arg NVIC_PriorityGroup_4: 4 bits for pre-emption priority*                                0 bits for subpriority* @retval None*/
void NVIC_PriorityGroupConfig(uint32_t NVIC_PriorityGroup)
{/* Check the parameters */assert_param(IS_NVIC_PRIORITY_GROUP(NVIC_PriorityGroup));/* Set the PRIGROUP[10:8] bits according to NVIC_PriorityGroup value */SCB->AIRCR = AIRCR_VECTKEY_MASK | NVIC_PriorityGroup;
}

第二步,NVIC初始化

标准库misc.c中的NVIC_Init()函数

/*** @brief  Initializes the NVIC peripheral according to the specified*         parameters in the NVIC_InitStruct.* @param  NVIC_InitStruct: pointer to a NVIC_InitTypeDef structure that contains*         the configuration information for the specified NVIC peripheral.* @retval None*/
void NVIC_Init(NVIC_InitTypeDef* NVIC_InitStruct)
{uint32_t tmppriority = 0x00, tmppre = 0x00, tmpsub = 0x0F;/* Check the parameters */assert_param(IS_FUNCTIONAL_STATE(NVIC_InitStruct->NVIC_IRQChannelCmd));assert_param(IS_NVIC_PREEMPTION_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority));  assert_param(IS_NVIC_SUB_PRIORITY(NVIC_InitStruct->NVIC_IRQChannelSubPriority));if (NVIC_InitStruct->NVIC_IRQChannelCmd != DISABLE){/* Compute the Corresponding IRQ Priority --------------------------------*/    tmppriority = (0x700 - ((SCB->AIRCR) & (uint32_t)0x700))>> 0x08;tmppre = (0x4 - tmppriority);tmpsub = tmpsub >> tmppriority;tmppriority = (uint32_t)NVIC_InitStruct->NVIC_IRQChannelPreemptionPriority << tmppre;tmppriority |=  NVIC_InitStruct->NVIC_IRQChannelSubPriority & tmpsub;tmppriority = tmppriority << 0x04;NVIC->IP[NVIC_InitStruct->NVIC_IRQChannel] = tmppriority;/* Enable the Selected IRQ Channels --------------------------------------*/NVIC->ISER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);}else{/* Disable the Selected IRQ Channels -------------------------------------*/NVIC->ICER[NVIC_InitStruct->NVIC_IRQChannel >> 0x05] =(uint32_t)0x01 << (NVIC_InitStruct->NVIC_IRQChannel & (uint8_t)0x1F);}
}

5.3,外部中断线和配套的GPIO进行连接映射

首先,确定按键和LED对应的PIN端口。通用I/O端口以下图的方式连接到16个外部中断/事件线上,若按键确定连接到PA0上,则对应的中断线为EXTI0。

在外部中断配置寄存器(AFIO_EXTICRX,X = 1,2,3,4)中设置中断线与哪个PIN角对应。

对应的设置函数是标准库GPIO.c文件中的GPIO_EXTILineConfig()函数:

/*** @brief  Selects the GPIO pin used as EXTI Line.* @param  GPIO_PortSource: selects the GPIO port to be used as source for EXTI lines.*   This parameter can be GPIO_PortSourceGPIOx where x can be (A..G).* @param  GPIO_PinSource: specifies the EXTI line to be configured.*   This parameter can be GPIO_PinSourcex where x can be (0..15).* @retval None*/
void GPIO_EXTILineConfig(uint8_t GPIO_PortSource, uint8_t GPIO_PinSource)
{uint32_t tmp = 0x00;/* Check the parameters */assert_param(IS_GPIO_EXTI_PORT_SOURCE(GPIO_PortSource));assert_param(IS_GPIO_PIN_SOURCE(GPIO_PinSource));tmp = ((uint32_t)0x0F) << (0x04 * (GPIO_PinSource & (uint8_t)0x03));AFIO->EXTICR[GPIO_PinSource >> 0x02] &= ~tmp;AFIO->EXTICR[GPIO_PinSource >> 0x02] |= (((uint32_t)GPIO_PortSource) << (0x04 * (GPIO_PinSource & (uint8_t)0x03)));
}

如果要设置PIN角PA0能够检测中断,调用此函数:

GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);

确定模式是中断还是事件;

typedef enum
{EXTI_Mode_Interrupt = 0x00,EXTI_Mode_Event = 0x04
}EXTIMode_TypeDef;

配置上升沿/下降沿触发选择寄存器;

因开发板上的按键接通时是接地的,因此需要将中断设置为下降沿触发,设置下降沿触发选择寄存器(EXTI_FTSR)

对应的标准库中代码:

typedef enum
{EXTI_Trigger_Rising = 0x08,EXTI_Trigger_Falling = 0x0C,  EXTI_Trigger_Rising_Falling = 0x10
}EXTITrigger_TypeDef;

重写中断函数ISR:

注意中断函数的名称要使用起始代码中的对应中断函数名称,也就是对这个弱函数重写。

注意要在ISR中清除中断挂起寄存器(EXTI_PR),如果不在ISR中清除中断就会反复进入中断:

对应的标准库函数在stm32f10x_exti.c中的EXTI_ClearFlag(),

/*** @brief  Clears the EXTI's line pending flags.* @param  EXTI_Line: specifies the EXTI lines flags to clear.*   This parameter can be any combination of EXTI_Linex where x can be (0..19).* @retval None*/
void EXTI_ClearFlag(uint32_t EXTI_Line)
{/* Check the parameters */assert_param(IS_EXTI_LINE(EXTI_Line));EXTI->PR = EXTI_Line;
}

5.4,代码文件 

中断相关.c和.h文件:

#ifndef _exti_H
#define _exti_H#include "system.h"void My_EXTI_Init(void);#endif

注意:需将AFIO使能,因为中断线和端口的对应配置是在AFIO相关寄存器:外部中断配置寄存器(AFIO_EXTICR)

#include "exti.h"
#include "led.h"
#include "SysTick.h"
#include "key.h"void My_EXTI_Init(void)
{NVIC_InitTypeDef NVIC_InitStructure;EXTI_InitTypeDef  EXTI_InitStructure;RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);  //注意需将AFIO使能GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource8);GPIO_EXTILineConfig(GPIO_PortSourceGPIOB, GPIO_PinSource9);NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);  NVIC_InitStructure.NVIC_IRQChannel = EXTI9_5_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;NVIC_InitStructure.NVIC_IRQChannelSubPriority =3;	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			NVIC_Init(&NVIC_InitStructure);	EXTI_InitStructure.EXTI_Line=EXTI_Line8|EXTI_Line9; EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;EXTI_InitStructure.EXTI_LineCmd=ENABLE;EXTI_Init(&EXTI_InitStructure);}void EXTI9_5_IRQHandler(void)
{if(EXTI_GetITStatus(EXTI_Line8)==1){delay_ms(10);if(KEY1==0){led2=0;}}else if(EXTI_GetITStatus(EXTI_Line9)==1){delay_ms(10);if(KEY2==0){led2=1;}}EXTI_ClearITPendingBit(EXTI_Line8|EXTI_Line9);
}

 main.c函数:

#include "system.h"
#include "SysTick.h"
#include "led.h"
#include "key.h"
#include "exti.h"int main()
{u8 i;SysTick_Init(72);LED_Init();KEY_Init();My_EXTI_Init();  while(1){i++;if(i%20==0){led1=!led1;}delay_ms(10);	}
}

6,FSMC

Flexible static memory controller(FSMC)灵活的静态存储控制器

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/361416.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【学亮IT手记】angularJS select2多选下拉框实例

永远保持对大部分知识的好奇心&#xff0c;学习从不枯燥&#xff0c;也没有被逼学习一说&#xff0c;乐此不疲才是该有的心态和境界&#xff01;&#xff01;&#xff01; 引入相关js库&#xff1a; html部分代码&#xff1a; angularJS定义数据源变量&#xff1a; 更多专业前端…

虚拟主机相关业务知识介绍

什么是虚拟主机&#xff1f; 虚拟主机是使用特殊的软硬件技术&#xff0c;把一台运行在因特网上的服务器主机分成一台台“虚拟”的主机&#xff0c;每一台虚拟主机都具有独立的域名&#xff0c;具有完整的Internet服务器&#xff08;WWW、FTP、Email等&#xff09;功能&#xf…

在CXF API和拦截器中添加Gzip压缩

如今&#xff0c;由于我们在响应中发送大量数据&#xff0c;因此必须对API响应执行Gzip压缩。 它节省了网络带宽和交付时间&#xff0c;当然还节省了Internet上的空间。 CXF提供了以多种方式使用Gzip压缩的选项。 蓝图 注解 蓝图&#xff1a; <bean id"gZipInterce…

zTree树形菜单交互选项卡效果实现

1、 添加自定义属性 page 2、 为 ztree 每个树形节点&#xff0c;添加点击事件 1 <!DOCTYPE html>2 <html>3 4 <head>5 <meta charset"UTF-8">6 <title>ztree树形菜单的使用</title>7 <!-- 导入…

windows 服务部署管理

通过创建bat文件&#xff0c;能够快速的对服务进行部署和卸载。 部署的命令如下&#xff1a; $SystemRoot%\Microsoft.NET\Framework\v4.0.30319\installutil.exe [exename] Net Start [servicename] sc config [servicename] startauto 卸载的命令如下: $SystemRoot%\Microsof…

oracle中sql语句的优化(转帖)

一、执行顺序及优化细则 1.表名顺序优化 (1) 基础表放下面,当两表进行关联时数据量少的表的表名放右边 表或视图: Student_info (30000条数据) Description_info (30条数据) select * from description_info di ,student_info si --学生信息表 where si.student…

Devoxx Hackergarten的企业Web应用程序原型

我已经连续10年参加DevoxxBe了 。 这是我最喜欢的Java会议&#xff0c;但是谈话时间表并不总是最佳的&#xff1a;有时我想同时看2个精彩的谈话&#xff01; 因此&#xff0c;在Devoxx的Hackergarten&#xff0c;在参加讲座之间&#xff0c;我们中的一些人开始构建Web应用程序以…

C# 加载C++的dll

[DllImport("kernel32")] private static extern IntPtr LoadLibrary([MarshalAs(UnmanagedType.LPStr)]string fileName) 转载于:https://www.cnblogs.com/sky-jyq/p/11509059.html

谈一谈Http Request 与 Http Response

谈一谈Http Request 与 Http Response   写在前面的话&#xff1a;最近帮朋友弄弄微信商城&#xff0c;对于微信的基础开发&#xff0c;基本上就是各种post、get&#xff0c;有时是微信服务器向我们的服务器post、get数据&#xff0c;有时需要我们自己的服务器向微信服务器各…

Linux常用命令和vi,gdb的使用

1.ls 命令 --------------------------------------------------------------------- ls以默认方式显示当前目录文件列表 ls -a显示所有文件包括隐藏文件 ls -l显示文件属性&#xff0c;包括大小&#xff0c;日期&#xff0c;符号连接&#xff0c;是否可读写及是否可执行 -----…

增压的jstack:如何以100mph的速度调试服务器

使用jstack调试实时Java生产服务器的指南 jstack就像U2一样-从时间的黎明就一直在我们身边&#xff0c;我们似乎无法摆脱它 。 除了笑话&#xff0c;到目前为止&#xff0c;jstack是您调试军用生产服务器中最方便的工具之一。 即便如此&#xff0c;我仍然认为它在情况恶化时能够…

(网页)css和js的版本号问题

HTML页面自动清理js、css文件的缓存,之前用的是?v11每次都要找寻到网页进行更改,非常的麻烦. <script type"text/javascript"> document.write("<script typetext/javascript srcjs/xxxx?v" new Date().getTime() ">"); </s…

wchar_t 的输出问题

wchar_t 定义的变量之所以不能输出呢&#xff1f;我查了一下资料&#xff0c;就是说宽字符类型要本地化&#xff0c;否则输不出想要结果。本地化有三条语句可以使用&#xff0c;任取其一。最后一句是全局函数&#xff0c;前两个是wcout的一个成员函数的两种表达方式。std::wcou…

Apache Cassandra和Java入门(第二部分)

要求 要遵循本教程&#xff0c;您应该已经有一个正在运行的Cassandra实例&#xff08; 一个小型集群会很好 &#xff0c;但不是必需的&#xff09;&#xff0c;已安装Datastax Java驱动程序&#xff08; 请参阅第I部分 &#xff09;&#xff0c;并且已经在这里进行了10分钟的演…

Zabbix监控多个JVM进程

一、场景说明&#xff1a; 我们这边的环境用的是微服务&#xff0c;每个程序都是有单独的进程及单独的端口号&#xff0c;但用jps查询出来的结果有些还会有重名的情况&#xff0c;所以某些脚本不太适用本场景&#xff1b; 二、需求说明&#xff1a; 需使用Zabbix-server监控每个…

(网页)swiper.js轮播图插件

Swiper4.x使用方法 1.首先加载插件&#xff0c;需要用到的文件有swiper.min.js和swiper.min.css文件。可下载Swiper文件或使用CDN。 <!DOCTYPE html> <html> <head>...<link rel"stylesheet" href"path/to/swiper.min.css"> <…

Android 4.0 Launcher源码分析系列(二)

原文&#xff1a;http://mobile.51cto.com/hot-314700.htm 上一节我们研究了Launcher的整体结构&#xff0c;这一节我们看看整个Laucher的入口点&#xff0c;同时Laucher在加载了它的布局文件Laucher.xml时都干了些什么。 我们在源代码中可以找到LauncherApplication&#xff0…

使用JFace Viewer延迟获取模型元素

Eclipse JFace Viewers显示的模型元素有时需要花费大量时间来加载。 因此&#xff0c; 工作台提供了IDeferredWorkbenchAdapter类型以在后台获取此类模型元素。 不幸的是&#xff0c;似乎仅通过DeferredTreeContentManager派生的AbstractTreeViewer支持此机制。 因此&#xff…

架构设计

好的架构是进化出来的 &#xff0c;不是设计出来的&#xff1b; 不同时期和不同环境有着不同的最佳架构&#xff1b; 存在即合理&#xff0c;合适的才是最好的&#xff1b; 转载于:https://www.cnblogs.com/sky-jyq/p/11527254.html

(网页)js每隔5分钟执行一次ajax请求的实现方法(转)

转自脚本之家: 一个页面好像只能有一个 window.οnlοadfunction(){}&#xff0c;所以要有多个事件&#xff0c;这样写就好了 window.onloadfunction(){ //假设这里每个五分钟执行一次test函数 publicBusi(); personBusi(); } function publicBusi(){ setTimeout(perso…