stm32中断NVIC与EXTI.docx

上传人:b****8 文档编号:10562993 上传时间:2023-02-21 格式:DOCX 页数:10 大小:43.70KB
下载 相关 举报
stm32中断NVIC与EXTI.docx_第1页
第1页 / 共10页
stm32中断NVIC与EXTI.docx_第2页
第2页 / 共10页
stm32中断NVIC与EXTI.docx_第3页
第3页 / 共10页
stm32中断NVIC与EXTI.docx_第4页
第4页 / 共10页
stm32中断NVIC与EXTI.docx_第5页
第5页 / 共10页
点击查看更多>>
下载资源
资源描述

stm32中断NVIC与EXTI.docx

《stm32中断NVIC与EXTI.docx》由会员分享,可在线阅读,更多相关《stm32中断NVIC与EXTI.docx(10页珍藏版)》请在冰豆网上搜索。

stm32中断NVIC与EXTI.docx

stm32中断NVIC与EXTI

stm32中断(NVIC与EXTI)

一、本章大纲

一、嵌套向量中断控制器—NVIC

CM3内核搭载了一个异常响应系统,通过NVIC(嵌套向量中断控制器)来管理和配置。

NVIC是一个总的控制器,相当于51的IE,不论是来自CM3内部的异常还是来自外设的中断,都进入该控制器进行处理和逻辑控制。

并且NVIC还通过优先级系统,来控制中断的嵌套。

1.中断优先级

①优先级的数值越小,则优先级越高。

②NVIC支持中断嵌套,使得高优先级异常会抢占低优先级异常。

③有3个系统异常:

复位、NMI(不可屏蔽中断)以及硬件失效(Hardfault),它们有固定的优先级,并且它们的优先级号是负数,从而高于所有其他异常。

原则上,NVIC支持3个固定的高优先级和多达256级的可设置优先级,用一个字节的8个比特位来表示。

STM32F107采用最高有效位对齐,在设计时裁掉表达优先级的4个低端有效位,所以只支持16级优先级。

2.抢占优先级与从优先级

NVIC中有一个寄存器是“应用程序中断及复位控制寄存器”,它里面有一个位段名为“优先级组”。

它把优先级分为2个位段:

MSB所在的位段对应抢占优先级,抢占优先级决定了抢占行为。

LSB所在的位段对应从优先级,从优先级则处理“内务”。

在STM32F107中,只使用4个位来表达优先级([7:

4]),如果抢占优先级组从比特5处分,则得到4级抢占优先级,且在每个抢占优先级的内部有4个从优先级(00011011)。

3.中断输入与悬起

当中断输入脚被置为有效后,该中断就被“悬起”。

所谓“悬起”,也就是等待、就绪的意思。

即使后来中断源撤消了中断请求,已经被标记成悬起的中断也被记录下来。

当某中断的服务程序开始执行时,就称此中断进入了“活跃”状态,并且其悬起位会被硬件自动清除。

在一个中断活跃后,直到其服务例程执行完毕,并且返回后,才能对该中断的新请求予以响应。

当NVIC响应一个中断时,会自动完成以下三项工作,以便安全、准确地跳转到相应的中断服务程序:

入栈:

把8个寄存器的值压入栈。

当响应中断时,如果当前的代码正在使用PSP,则压入PSP(进程堆栈),否则就压入MSP(主堆栈)。

一旦进入了服务例程,就一直使用主堆栈。

在自动入栈的过程中,将寄存器写入堆栈的顺序与时间顺序无关,CM3会保证正确的寄存器被保存到正确的位置。

取向量:

当数据总线(系统总线)进行入栈操作时,指令总线(I-Code总线)正在从向量表中找出正确的中断向量与对应的服务程序入口地址。

更新寄存器。

注意:

①如果在某个中断得到响应之前,其悬起状态被清除了,则中断被取消。

②新请求在得到响应时,由硬件自动清零其悬起标志位。

③如果中断源咬住请求信号不放,该中断就会在其上次服务例程返回后再次被置为悬起状态。

④如果某个中断在得到响应之前,其请求信号以若干的脉冲的方式呈现,则被视为只有一次中断请求

⑤如果在服务例程执行时,中断请求释放了,但是在服务例程返回前又重新被置为有效,则NVIC会记住此动作,重新悬起该中断。

4.中断返回

当中断完成,返回主程序时,NVIC自动完成以下两步:

①出栈:

先前压入栈中的寄存器在这里恢复。

内部的出栈顺序与入栈时的相对应,堆栈指针的值也改回先前的值。

②更新NVIC寄存器:

伴随着中断的返回,它的活动位也被硬件清除。

对于外部中断,倘若中断输入再次被置为有效,则悬起位也将再次置位,新一次的中断响应序列也会再次开始。

5.CM3异常和中断系统--SYSTICK定时器

SysTick定时器被捆绑在NVIC中,用于产生SysTick异常(异常号15)。

它又叫滴答中断,它的作用是规定不同任务执行时间,防止一个任务一直霸占系统。

此外,还有操作系统提供的各种定时功能,都与滴答中断有关。

在STM32F107中,系统嘀嗒校准值固定为9000,当系统嘀嗒时钟设定为9MHz(HCLK/8的最大值)时产生1ms时间基准。

对于SysTick,库函数文件misc.c中也有一个函数可以对其时钟源进行配置,该函数的原型为:

SysTick_CLKSourceConfig()/*source(源头);config(配置)

voidSysTick_CLKSourceConfig(uint32_tSysTick_CLKSource);

SysTick_CLKSource

描述

SysTick_CLKSource_HCLK_Div8

SysTick时钟源为 AHB时钟除以8

SysTick_CLKSource_HCLK

SysTick时钟源为 AHB时钟

6.中断向量

当发生了异常或中断,并且要响应它时,CM3需要定位其服务程序的入口地址。

通过入口地址找到相应的中断服务程序。

这些入口地址存储在“(异常)向量表”中。

缺省情况下,CM3认为(异常)向量表位于零地址处,且各向量占用4字节。

STM32F107的异常响应系统是CM3的裁剪和细化。

在STM32F107中,这种映射关系具体体现在启动代码startup_stm32f10x_cl.s文件中。

该文件已经对这些向量表等进行了映射和配置,并指定了中断服务程序的名称,出于标准化和固件库的要求,一般不建议进行修改。

该文件由汇编写成。

【代码4-2】startup_stm32f10x_cl.s

/*复位异常服务函数,函数名为Reset_Handler。

PROC表示:

定义子程序。

与ENDP相对应。

Reset_HandlerPROC

/*输出一个标号,供全局使用。

[WEAK]表示如果其他文件同样定义了该标号,则不使用[WEAK]定义的本标号。

EXPORTReset_Handler[WEAK]

;从其他文件读入一个标号SystemInit

IMPORTSystemInit

;从其他文件读入一个标号main

IMPORT__main

将SystemInit标号地址赋值给R0并跳转

LDRR0,=SystemInit

BLXR0

;将main标号地址赋值给R0并跳转

LDRR0,=__main

BXR0

ENDP

 

二、外部中断/事件控制器EXTI

与NVIC不同,外部中断/事件控制器EXTI是STM32F107的一个外设,不属于CM3内核的范畴,主要用于配置GPIO的外部中断线。

对于一般中断来说,还需要配合NVIC设置其优先级才能真正的正常工作。

主要特性为:

EXTI由20个产生事件/中断请求的边沿检测器组成。

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

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

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

检测脉冲宽度低于APB2时钟宽度的外部信号。

 

三、NVIC库函数配置

NVIC涉及的库函数存放在misc.c文件中,并非类似stm32f10x_gpio.c的命名,这是因为NVIC属于CM3内核部件,遵从CMSIS接口协议。

就其库函数来看,NVIC主要是设置中断的优先级,以达到控制其运行先后及嵌套等功能。

下面以实例来介绍:

配置EXTI3中断的抢占优先级为0x07,从优先级为0x07,并使能该中断。

 

voidNVIC_Config(void)

{

NVIC_InitTypeDefNVIC_InitStructure;

/*配置中断通道为EXTI3,channel(通道)*/

NVIC_InitStructure.NVIC_IRQChannel=EXTI3_IRQn;

/*在NVIC_InitStructure中配置中断抢占优先级为3,preemption抢先占有,

priority优先权*/

NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x07;

/*在NVIC_InitStructure中配置中断从优先级为1,sub潜水艇,地铁,替补队员*/

NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01;

NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;

NVIC_Init(&NVIC_InitStructure);

}

注:

抢占优先级去从优先级的选择

NVIC_PriorityGroup

PreemptionPriority

SubPriority

描述

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 位

 

下面以介绍如何编写EXTI函数来介绍EXTI:

voidEXTI_Config(void)

{

EXTI_InitTypeDefEXTI_InitStructure;

/*定义结构体

RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

/*配置GPIO线上的外部中断,必须先使能AFIO时钟。

这句是rcc.h中的一句函数:

RCC_APB2PeriphClockCmd(uint32_tRCC_APB2Periph,FunctionalStateNewState);

GPIO_EXTILineConfig(GPIO_PortSourceGPIOD,GPIO_PinSource3);

/*配置PD3管脚作为EXTI线,这句是gpio.h中的函数,参数为(uint8_tGPIO_PortSource(端口源),uint8_tGPIO_PinSource(引脚源));

EXTI_InitStructure.EXTI_Line=EXTI_Line3;

EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;

/*中断模式:

Interrupt中断模式;Event事件模式

EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;

/*触发方式:

Falling下降沿触发;Rising上升沿触发;Rising_Falling边沿触发

EXTI_InitStructure.EXTI_LineCmd=ENABLE;

/*指定中断状态:

ENABLE使能,DISABLE关闭

EXTI_Init(&EXTI_InitStructure);

 

下面以实际例子来介绍如何编写中断程序

将PD3管脚接一个按键,作为外部中断线3的输入源,每次按下该按键产生一个中断,在中断服务函数中驱动PC9管脚控制LED4灯翻转输出状态。

①编写main函数:

#Include“stm32x.h”

voidGPIO_Config(void);

voidNVIC_Config(void);

voidEXTI_Config(void);

Intmain(void)

{

GPIO_Config();

NVIC_Config();

EXTI_Config();

while

(1);

{

}

}

②编写GPIO_Config()

voidGPIO_Config(void);

{

GPIO_InitTypeDefGPIO_InitStructure;

RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC|RCC_APB2Periph_GPIOD,ENABLE);

/*配置PC9管脚作为推挽输出*/

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;

GPIO_Init(GPIOC,&GPIO_InitStructure);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高等教育 > 经济学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1