STM32 NVIC中断向量表设置以及EXTI中断寄存器设置

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
图4 3. EXTI_RTSR(Rising trigger selection register)上升沿触发寄存器
图5 4. EXTI_FTSR (Falling trigger selection register)下降沿触发器
图6
需要说明的是,作为外部唤醒线是边沿触发的,这些线上不能出现毛刺信号。 5. EXTI_SWIER (Software interrupt event register) 软件中断事件寄存器
图 10 比如 IP[6]对应着中断 0(应为中断 0 的中断号为 6,具体参考 STM32 参考手册英文版 P203),其中有 8 个 bit,但是在设置优先级时 STM32 只使用了高 4 位,由这高四位 决定了抢占优先级和响应优先级的级别。具体抢占优先级和响应优先级的分配位数 怎么确定的即由优先级分组寄存器控制 SCB-AIRCR g. 关于中断优先级具体设置中,还有几个地方需要特别注意。那就是 AMR 内置的基本 部件的优先级设定,如 SysTick、PendSV 等。这些部分的优先级设定,需要对 SCB->SHPRx
第 1 行我们写入信息为,设定优先级组别为组 2,即有抢占优先级和响应优先级各有
两位控制,分级 0-3. 第 2 行意思是打开中断编号为 6 的中断,即允许外部中断 0 第 3 行意思即设定中断编号为 6 的中断优先级具体分配情况,0XA0—1010 0000,即 抢占优先级和响应优先级都设置为 2. 这里需要注意,我并没有设置中断偏移,采用了默认设置,如果有需要时,则要对 SCB->VOTR 进行相关设置 4、 中断函数的书写 A. 中断函数名的书写有要求,否则会找不到中断入口。在 3.5 库函数之前,在 stm32f10x_it.c 中就预先写好了个外部中断的函数名称,我们只要将对应的执行过程 填充进去就可以;但 3.5 库函数里没有给出,因此我们参考之前的。比如例程中我 写的中断函数名称就为 void EXTI0_IRQHandler(void)。 B. 在进入中断后我们需要做的动作有 2 部,一次执行中断过程,2 是清除中断挂起标 识,因为执行完毕了。如果不清除中断挂起标识,则无法再次进入中断。 看例程
图7 我们可以通过对相应位置写 1,来软件触发中断,对响应 PR 位写 1,清除软件中断。 该寄存器复位值为 0 6. EXTI_PR (Pending Register) 中断挂起寄存器
图8 该寄存器复位值是不确定的,如果某个激活了某个中断,则对应的挂起位会置 1, 如果要手动清除挂起,则我们需要往对应位写 1. 这里需要说明一下,就是中断和中断事件不是同一个概念。从图 2 中我们可以看到 两者的来源都是一致的,但是中断是需要 CPU 参与的,需要软件的中断服务函数才能 完成中断后产生的结果;但是事件,是靠脉冲发生器产生一个脉冲,进而由硬件自动完 成这个事件产生的结果,当然相应的联动部件需要先设置好,比如引起 DMA 操作,AD 转换等。 分析程序
图1 从寄存器配置中我们可以看到每个中断由四位配置,那么 STM32 总计有 16 个外部 中断(具体参照 STM32 参考手册 P133 页),因此 EXTIR 有四组,在书写时要注意。 具体对应关系如下:0000: PA[x] pin,0001: PB[x] pin,0010: PC[x] pin,0011: PD[x] pin 0100: PE[x] pin,0101: PF[x] pin,0110: PG[x] pin。假设我们需要设定外部中断 0 由 GPIOB_0 来控制,那么我就可以写成 AFIO->EXTIR[0] |=0X01; 2、 中断寄存器的设置 A. 首先我们可以观察一下下图
图9 我们需要操作的寄存器有 a. ISER(Interrupt Set-Enable Register)-中断使能寄存器,该寄存器通过写 1 来使能中断,
写 0 无效 b. ICER(Interrupt Clear-Enable Register)-中断失能寄存器,通过对相应位写 1,失能中断,
写 0 无效 c. ISPR(Interrupt Set- Pending Register)-中断挂起寄存器,写 0,无效,但当中断处于中
二、具体设置 1、 端口设置
void GPIOA_init(void) {
GPIO_DeInit(GPIOA); RCC->APB2ENR |= 0X00000005; GPIOA->CRL &= 0XFFFFFF00; GPIOA->CRL |= 0x00000038; GPIOA->ODR = 0X00000000; GPIOA->ODR |= 0X00000001; AFIO->EXTICR[0] |= 0X00; } a. 在对端口进行任何操作之前,必须打开对应的时钟信号,其设置才能生效。这里使 用了 GPIOA.00 端口作为中断 0 输入,作为输入时一般我们设置为上拉输入,如果要 设置成浮空输入的话,外部一定要加上拉电阻,这样对于过滤输入波动很有益处(假 设在电压在 3.3-2.0 之间进行波动,时间上没尝试按键操作,因为一旦有按键,就应 该为 0,那么接了上拉的话,除非产生了低电平,否则小波动都会被拉高过滤掉) b. 复用端口时钟信号的开启 这里需要特别注意的是因为我们要对复用端口寄存器进行操作,所以必须打开复用 端口寄存器时钟
断时,写 1 无效,否则写 1 则将该中断挂起。读寄存器,1-中断挂起,0-中断未挂 起 d. ICPR(Interrupt Clear-Pending Register)-清除中断挂起寄存器。写 0 无效,写 1 则清除 当前中断挂起状态,但是如果该中断正在执行,则写 1 也无效。读寄存器,1-中断 挂起,0-中断未挂起 e. IABR(Interrupt Active Bit Register)-中断激活寄存器。只读寄存器,1-对应中断激活, 0-对应中断未激活 f. IPR/IP(Interrupt Priority Register)-中断优先级寄存器。这是个很关键的寄存器,这里 在 STM32F10XX 系列中,每个字的高 4 位用于设定优先级,需要配合优先级分组寄 存器使用 SCB->AIRCR。如下图 10 所示
NVIC 中断向量表设置以及 EXTI 中断寄存器设置
一、开始中断的步骤 A. 端口设置。这里包括了输入引脚的设置,务必记得打开 GPIO 的时钟和 AFIO 的时钟 信号 B. 中断寄存器的设置 C. NVIC 中断向量寄存器的设置。这里关键点有优先级分组设置以及中断入口地址的设 置 D. 中断函数的书写
c. AFIO->EXTICR[0] |= 0X00 ,EXTICR(External interrupt configuration register)即外部中断 配置寄存器。因为所有的外部中断输入来源都是经由 GPIO 口输入的,所以我们需要 选择哪一个中断是经由那个 IO 口输入的。我所写的这条代码的意思是 EXTI0 的中断 来源为 GPIOX_0 口输入。
#ifdef VECT_TAB_SRAM SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in
Internal SRAM. */ #else SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in
图2 从图中,我们可以看到和中断相关的寄存器总共有 6 个,他们分别是 1.EXTI_IMR(Interrupt mask register )中断屏蔽寄存器。
图3 该寄存器复位值为 0,往对应寄存器内写 1 则打开中断 2. EXTI_EMR( Event mask register )中断事件屏蔽寄存器
Priority Group 0
High 4 bit 1111
Low 4 bit 1110
1
1111
1100
2
1111
1000
4
3(011)
1111
0000
3
4(100)
1110
0000
2
5(101)
1100
0000
1
6(110)
1000
0000
Leabharlann Baidu
0
7(111)
0000
0000
表1
这样就可以对比看出共同点就是分组,0-无抢占优先级,1-一个抢占优先级。
因此在 STM32 中,写入 SCB-AIRCR[10-8]的数字,0 组对应的写入 111。
j. Vector table offset register (SCB_VTOR)-向量表漂移寄存器
图 13 第 29 位,写入 1-对应中断向量表位于 CODE 区-内置 Flash,写 0-中断向量表位于 SRAM, 即外部 RAM 区 写入漂移的地址有如下要求:必须先求出系统中共有多少个向量,再把这个数字向上 “圆整”到 2 的整次幂,而起始地址必须对齐到后者的边界上。例如,如果一共有 32 个中断,则共有 32+16(系统异常)=48 个向量,向上圆整到 2 的整次幂后值为 64, 因此向量表重定位的地址必须能被 64*4=256 整除,从而合法的起始地址可以是: 0x0, 0x100, 0x200 等。(这里为什么要乘 4,是由于 CM3 规定向量占用 4 字节, 因此需要 256 字节) 可以通过看头函数,在库函数版本 3.5 中,提供的初始化函数已经自动将向量漂移 地址设置好了。使用语句如下
void EXTI_Inition(void) {
EXTI->IMR = 0X0001; // EXTI->EMR = 0X0001;
EXTI->FTSR = 0X0001; // EXTI->RTSR = 0X0001; }
第一条语句,我们打开了中断 0 的使能信号,第二句是打开中断事件寄存器(在软件 仿真我们选择关闭),第三、四行选择触发方式。 3、 NVIC 中断向量寄存器设置 该部分在 STM32 参考手册里没有详细的介绍,关于这部分我们可以从 Cortex M3 的编程 手册里了解到。涉及到的寄存器如下图
图 11 具体的分组信息如下图 12 所示。Cortex-M3 中必须强调的是必须保证有一个抢占优 先级
图 12-01
图 12-02 i.图中的 bit[7:4]即对应着 IP[0]的高 4 位。
需要特别强调的是这里所提及的中断号是其位置号。如中断 0,在中断向量表中位 置号为 6,位置号为 0 对应的中断是窗口定时器中断。 在对 SCB->AIRCR 进行操作是,如果要使写入的数据有效,则必须向其高 4 字写入 0X05FA 才能生效,比如 SCB->AIRCR=0X05FA0000|0X0500,这里 0X05FA 就像开门的要 是,这一点要注意.还有就是一旦设置了,中途则不能改变,且所有的可设置的中断
进行设置。具体信息如下图:
这一部分内容可以参考 Cortex-M3 编程手册 P138 的 4.4.8。需要特别注意的是,在 STM32 3.5 的库函数中,对应的操作位为 SCB->SHP[0-11]。可以查看 core_cm3.h 第 347 行。
h. SCB_AIRCR(Application interrupt and reset control register )-中断应用复位寄存器,其中 关系到分组的为其 8-10 位寄存器。图 11
Internal FLASH. */ #endif 库函数名称 void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset) 接下来看例程
void NVIC_interrupt_init() { SCB->AIRCR=0X05FA0500; NVIC->ISER[0]=(0X01<<6); NVIC->IP[6] = 0xA0; }
都选择了同样的组别。
图 12-01 是 STM32 对应的组别,而图 12-02 是 Cortex M3 定义的,这两者有差别的。 因为优先级组的是 MSB 对其的,而 STM32 的优先级由高四位决定,那么由 Cortex M3
转移到 STM32 上,则是直接保留高四位,如下表 1 所示
Group Name
相关文档
最新文档