锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

STM32 NVIC嵌套向量中断控制器函数分析

时间:2024-05-19 02:07:12

中断管理函数 CM3内核支持256个中断,其中包含了16个内核中断和240个外部中断,并且具有256级的可编程中断设置。但STM32并没有使用CM3内核的全部东西,而是只用了它的一部分。 STM32有76个中断,包括16个内核中断和60个可屏蔽中断,具有16级可编程的中断优先级。而我们常用的就是这60个可屏蔽中断,所以我们就只针对这60个可屏蔽中断进行介绍。
在MDK内,与N 相关的寄存器,MDK为其定义了如下的结构体: typedef struct { vu32 ISER[2]; u32 RESERVED0[30]; vu32 ICER[2]; u32 RSERVED1[30]; vu32 IR[2]; u32 RESERVED2[30]; vu32 ICPR[2]; u32 RESERVED3[30]; vu32 IABR[2]; u32 RESERVED4[62]; vu32 IPR[15]; } NVIC_TypeDef;

ISER[2]:Interrupt set enable registers中断使能寄存器组
ICER[2]:interrupt clear enable registers 中断除能寄存器组
ISPR[2]:interrupt set pending registers 中断挂起寄存器组
ICPR[2]: interrupt clear pending registers 中断解挂寄存器组
IABR[2]:interrupt active bit registers 中断激活标志寄存器组

主要分析
IPR[15]:interrupt priority registers 中断优先级控制寄存器组




使用函数实现中断分组: 可选分组0--4

MY_NVIC_PriorityGroupConfig(u8 NVIC_Group)
{
u32 temp,temp1; //设置中转变量
temp1=(~NVIC_Group)&0x07; //取后3位
temp1<<=8; //左移8位
temp=SCB->AR; //读取先前设置
temp&=0x0000F8FF; //清空先前设置
temp|=0x05FA0000; //插入密钥
temp|=temp1; //分组设置赋值进
SCB->ACB=temp; //设置完的值赋值给中断分组寄存器
}

语句解读:

temp1=(~NVIC_Group)&0x07; 由于
所以组号取反与111 即得到分组所需寄存器值
temp|=0x05FA0000;
密钥


使用函数实现中断优先级设置:
void MY_NVIC_Init(u8 NVIC_PreemptionPriority,u8 NVIC_SubPriority,u8 NVIC_Channel,u8 NVIC_Group)
{
u32 temp;
u8 IPRADDR=NVIC_Channel/4; //每组只能存4个得到组地址
u8 IPROFFSET=NVIC_Channel%4; //得到组内偏移地址
IPROFFSET=IPROFFSET*8+4; //得到确切地址
MY_NVIC_PriorityGroupConfig(NVIC_Group); //设置分组
temp=NVIC_Preemptionpriority<<(4-
NVIC_Group); // 设置抢占优先级
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group); //设置响应优先级
temp&=0xf; //取低4位
if(NVIC_Channel<32) NVIC->ISER[0]|=1< else
NVIC->ISER[1]|=1<<(NVIC_Channel-32);
NVIC->IPR[IPRADDR]|=temp< }


语句解读:

u8 IPRA =NVIC_Channel/4; //ISER[2]组可以设置60个中断优先级,每组15个寄存器,每个寄存器32位 每个可中断8位,每个寄存器可以设置4个中断, 组地址=channel/4; //选择中断号组(0--3)(4--7),,,(56---59)
u8 IPROFFSET=NVIC_Channel%4; 组内偏移地址 //选择第几个中断号
IPROFFSET=IPROFFSET*8+4; //由于每个中断8位,只用了前4位,所以偏移4






temp=NVIC_Preemptionpriority<<(4-NVIC_Group); //抢占优先级在左边,根据抢占位多少进行左移
temp|=NVIC_SubPriority&(0x0f>>NVIC_Group); //响应优先级在右边,根据响应位多少进行右移
temp&=0xf; //得到分组值

外部中断配置函数:

STM32的EXTI控制器支持19个外部中断/事件请求。每个中断设有状态位,每个中断/事件都有独立的触发和屏蔽设置。STM32的19个外部中断为: 线0~15:对应外部IO口的输入中断。
线16:连接到PVD输出。
PVD(Programmable Voltage Detector),即可编程电压监测器。应用于STM32芯片中,作用是监视供电电压,在供电电压下降到给定的阀值以下时,产生一个中断,通知软件做紧急处理。当供电电压又恢复到给定的阀值以上时,也会产生一个中断,通知软件供电恢复。

线17:连接到RTC闹钟事件。 RTC是多种名词的缩写,如:(Real-Time Clock) 线18:连接到USB唤醒事件。 对于外部中断EXTI控制MDK定义了如下结构体: typedef struct { vu32 IMR; vu32 EMR; vu32 RTSR; vu32 FTSR; vu32 SWIER; vu32 PR; } EXTI_TypeDef;


IMR:
中断屏蔽寄存器Interrupt Mask Register 32位寄存器前19位有效
EMR: 事件屏蔽寄存器Event mask register 32位寄存器前19位有效
RTST: 上升沿触发选择寄存器Rising edge trigger select register
FTSR:下降沿触发选择寄存器Falling edge trigger select register
SWIER:软件中断事件寄存器Software interrupt event register
PR: 挂起寄存器Pending Register

I/O口复用里的配置寄存器EXTICR 每个I/O口可以配置成中断输入


STM32 任何一个IO口都可以配置成中断输入口,但是IO口的数目远大于中断线数(16个)。于是STM32就这样设计,GPIOA~GPIOG的[15:0]分别对应中断线15~0。这样每个中断线对应了最多7个IO口,以线0为例:它对应了GPIOA.0、PIOB.0、GPIOC.0、GPIOD.0、 GPIOE.0、GPIOF.0、GPIOG.0。而中断线每次只能连接到1个IO口上,这样就需要EXTICR来决定对应的中断线配置到哪个GPIO上了。















EXTICR在AFIO的结构体中定义如下

typedef struct { vu32 EVCR; vu32 MAPR; vu32 EXTICR[4];
} AFIO_TypeDef;

EXTIRC寄存器总共4个,因为编译器的寄存器都是从0号开始的,所以EXTICR[0]---EXTICR[3]对应
<>中的EXTICR1---EXTICR4 每个EXTICR用了其中低16位.

外部中断配置函数:
void Ex_NVIC_Config(u8 GPIOx,u8 BITx,u8 M)
{
u8 EXTADDR;
u8 EXTOFFSET;
EXTADDR=BITx/4; //得到中断寄存器组编号

EXTOFFSET=(BITx%4)*4; //得到偏移量 具体哪个I/O口进行设置
RCC->APB2ENR|=0x01; //使能复用I/O口
AFIO->EXTICR[EXTADDR]|=GPIOx< EXTI->IMR|=1< EXTI->EMR|=1< if(TRIM&0x01) EXIT->FTSR|=1< if(TRIM&0x02) EXIT->RTSR|=1<
}

注:
TRIM为触发方式选择变量; 0x01下降沿触发 0x02 上升沿触发 0x03任意电平触发.

-电子元器件采购网(www.ruidan.com)是本土元器件目录分销商,采用“小批量、现货、样品”销售模式,致力于满足客户多型号、高质量、快速交付的采购需求。 自建高效智能仓储,拥有自营库存超过50,000种,提供一站式正品现货采购、个性化解决方案、选型替代等多元化服务。
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章