完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
|
|
相关推荐
1个回答
|
|
中断介绍
中断就是当CPU 执行程序时,由于发生了某种随机的事件(外部或内部),引起CPU 暂时中断正在运行的程序,转去执行一段特殊的服务程序(中断服务子程序或中断处理程序),以处理该事件,该事件处理完后又返回被中断的程序继续执行,这一过程就称为中断,引发中断的称为中断源。比如:看电视时突然门铃响,那么门铃响就相当于中断源。有些中断还能够被其他高优先级的中断所中断,那么这种情况又叫做中断的嵌套。中断示意图如图所示: Crotex-M3 内核支持256 个中断,其中包含了16 个内核中断和240 个外部中断。 但STM32 并没有使用M3 内核的全部东西,而是只用了它的一部分。STM32F10x 芯片有84 个中断通道,包括16 个内核中断和68 个可屏蔽中断,对于STM32F103 系列芯片只有60 个可屏蔽中断,在STM32F107 系列才有68 个。除了个别异常的优先级被定死外,其它异常的优先级都是可编程的。这些中断通道已按照不同优先级顺序固定分配给相应的外部设备。从STM32F10x 中文参考手册的中断向量表可以知道具体分配到那些外设,这里只截取一部分,中断向量表如图所示: NVIC 介绍 NVIC 英文全称是Nested Vectored Interrupt Controller,中文意思就是嵌套向量中断控制器,它属于M3 内核的一个外设,控制着芯片的中断相关功能。由于ARM 给NVIC 预留了非常多的功能,但对于使用M3 内核设计芯片的公司可能就不需要这么多功能,于是就需要在NVIC 上裁剪。ST 公司的STM32F103 芯片内部中断数量就是NVIC 裁剪后的结果。上面说到NVIC 控制着芯片的中断相关功能,那么肯定有很多对应的寄存器,在固件库core_cm3.h 文件内定义了一个NVIC 结构体,里面定义了相关寄存器, 如下: typedef struct { __IO uint32_t ISER[8]; //中断使能寄存器 uint32_t RESERVED0[24]; __IO uint32_t ICER[8]; //中断清除寄存器 uint32_t RSERVED1[24]; __IO uint32_t ISPR[8]; //中断使能悬起寄存器 uint32_t RESERVED2[24]; __IO uint32_t ICPR[8]; //中断清除悬起寄存器 uint32_t RESERVED3[24]; __IO uint32_t IABR[8]; //中断有效位寄存器 uint32_t RESERVED4[56]; __IO uint8_t IP[240]; //中断优先级寄存器 uint32_t RESERVED5[644]; __O uint32_t STIR; //软件触发中断寄存器 } NVIC_Type; 在配置中断时,我们通常使用的只有ISER、ICER 和IP 这三个寄存器: ISER 是中断使能寄存器,ICER 是中断清除寄存器,IP 是中断优先级寄存器。在固件库core_cm3.h 文件后面,还提供了一些对NVIC 操作的库函数,这些函数都是遵循CMSIS 标准,所以只要是基于Cortex-M3 内核的芯片都可以用这些函数来操作NVIC,只不过我们很少这样做,甚至不使用这些函数,因为在后面我们会有更简单的办法来配置中断。至于这些函数内容,可以打开库函数版本任意程序,找到core_cm3.h 文件查看即可。 中断优先级 前面说了STM32F103 芯片支持60 个可屏蔽中断通道,每个中断通道都具备自己的中断优先级控制字节(8 位,理论上每个外部中断优先级可以设置为0-255,数值越小,优先级越高。但是STM32F103 中只使用4 位,高4 位有效),用于表达优先级的高4 位又被分组成抢占式优先级和响应优先级,通常也把响应优先级称为“亚优先级”或“副优先级”,每个中断源都需要被指定这两种优先 级。高抢占式优先级的中断事件会打断当前的主程序或者中断程序运行,俗称中断嵌套。在抢占式优先级相同的情况下,高响应优先级的中断优先被响应。当两个中断源的抢占式优先级相同时,这两个中断将没有嵌套关系,当一个中断到来后,如果正在处理另一个中断,这个后到来的中断就要等到前一个中断处理完之后才能被处理。如果这两个中断同时到达,则中断控制器根据他们的响应优先级高低来决定先处理哪一个;如果他们的抢占式优先级和响应优先级都相等,则根据他们在中断表中的排位顺序决定先处理那一个,越靠前的先执行。STM32F103 中指定中断优先级的寄存器位有4 位,这4 位的分组方式如图: 第0 组:所有4 位用于指定响应优先级 第1 组:最高1 位用于指定抢占式优先级,最低3 位用于指定响应优先级 第2 组:最高2 位用于指定抢占式优先级,最低2 位用于指定响应优先级 第3 组:最高3 位用于指定抢占式优先级,最低1 位用于指定响应优先级 第4 组:所有4 位用于指定抢占式优先级 设置优先级分组可调用库函数NVIC_PriorityGroupConfig()实现,有关NVIC 中断相关的库函数都在库文件misc.c 和misc.h 中,所以当使用到中断时, 一定要记得把misc.c 和misc.h 添加到工程组中。 NVIC_PriorityGroupConfig()函数代码如下: 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_PriorityGroupConfig 函数带一个形参用于中断优先级分组,该值范围可以是 NVIC_PriorityGroup_0-NVIC_PriorityGroup_4,对应优先级与占用的位数信息如下: 函数内最终将分组值给SCB-》AIRCR,说明控制中断优先级寄存器是内核外设SCB 的AIRCR 寄存器的PRIGROUP[10:8]位。 中断配置 前面讲解了那么多中断知识,如果大家不理解也没有关系,我们会应用即可,等到后面STM32 熟练了,再回过头深入了解自然就会明白。要使用中断我们就需要先配置它,通常都需经过这几步: (1)使能外设某个中断,这个具体是由外设相关中断使能位来控制,比如定时器有溢出中断,这个可由定时器的控制寄存器中相应中断使能位来控制。 (2)设置中断优先级分组,初始化NVIC_InitTypeDef 结构体,设置抢占优先级和响应优先级,使能中断请求。 NVIC_InitTypeDef 结构体如下: typedef struct { uint8_t NVIC_IRQChannel; //中断源 uint8_t NVIC_IRQChannelPreemptionPriority; //抢占优先级 uint8_t NVIC_IRQChannelSubPriority; //响应优先级 FunctionalState NVIC_IRQChannelCmd; //中断使能或失能 } NVIC_InitTypeDef; 下面我们对NVIC_InitTypeDef 结构体成员进行一下简单介绍。 1.NVIC_IRQChannel:中断源的设置,不同的外设中断,中断源不一样,自然名字也不一样,所以名字不能写错,否则不会进入中断。中断源放在stm32f10x.h 文件的IRQn_Type 结构体内,由于内容太多,这里就不复制所有中断源,只截取一部分,如下: typedef enum IRQn { //Cortex-M3 处理器异常编号 NonMaskableInt_IRQn = -14, MemoryManagement_IRQn = -12, BusFault_IRQn = -11, UsageFault_IRQn = -10, SVCall_IRQn = -5, DebugMonitor_IRQn = -4, PendSV_IRQn = -2, SysTick_IRQn = -1, //STM32 外部中断编号 WWDG_IRQn = 0, PVD_IRQn = 1, TAMP_STAMP_IRQn = 2, // 限于篇幅,中间部分代码省略,具体的可查看库文件stm32f10x.h DMA2_Channel2_IRQn = 57, DMA2_Channel3_IRQn = 58, DMA2_Channel4_5_IRQn = 59 }IRQn_Type; 2.NVIC_IRQChannelPreemptionPriority:抢占优先级,具体的值要根据优先级分组来确定,可以参考前面中断优先级分组内容。 3.NVIC_IRQChannelSubPriority:响应优先级,具体的值要根据优先级分组来确定,可以参考前面中断优先级分组内容。 4.NVIC_IRQChannelCmd:中断使能/失能设置,使能配置为ENABLE,失能配置为DISABLE。 (3)编写中断服务函数 配置好中断后如果有触发,即会进入中断服务函数,那么中断服务函数也有固定的函数名,可以在startup_stm32f10x_hd.s 启动文件查看,启动文件提供的只是一个中断服务函数名,具体实现什么功能还需要我们自己编写,可以将中断服务函数放在stm32f10x_it.c 文件内,也可以放在自己的应用程序中。通常我们把中断函数放在应用程序中。这里提醒一下,不要任意修改中断服务函数名,因为启动文件内中断服务函数名已经固定,如果要修改,你还必须在启动文件内把原中断函数修改。 |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1763 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1617 浏览 1 评论
1059 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
723 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1670 浏览 2 评论
1933浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
726浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
566浏览 3评论
592浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
550浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 09:47 , Processed in 0.663091 second(s), Total 45, Slave 39 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号