【STM32+cubemx】0007 HAL库开发:外部中断,优先级和中断向量表

这一节我们以外部中断为例子,讲讲中断的优先级和中断向量表的知识。

1)cubemx生成代码

首先还是在cubemx中生成代码,选择器件、设置SYS(调试接口)、设置RCC(外部晶振时钟源)。

然后设置GPIO引脚,选择PC13作为输出(用于LED指示),如下图选择PA0设置为外部中断输入引脚:

然后设置中断使能和优先级,如下图:

这里的几处选项解释一下:

最上面的Priority group是选择优先级分组,STM32(更确切地说是contex-M3内核的单片机)使用4个bit位来分组,这里可以设置用几个bit来区分抢占优先级响应优先级

比如图中选择的是3bit用来区分抢占优先级、1bit用来区分响应优先级,则抢占优先级可以选择为0~7(图中选的是6),响应优先级可以选择为0~1(图中选的是1);数值越小则优先级越高;

抢占优先级高的可以中断低优先级的中断,中断嵌套的形式实现;

抢占优先级相同时,有多个中断同时发生,则先运行响应优先级高的中断。

由于咱们这个例子只有一个中断,选哪个都不影响,但是要勾上使能。

到GPIO页面下,将PA0的状态改为上拉、中断下降沿触发:

之后,在时钟选项卡设置主时钟为72M;在project Manager选项卡设置工程名和路径,生成工程代码。

2)HAL库函数的使用

生成的工程中,已经有比较完善的初始化代码。我们直接看中断服务程序,在stm32f1xx_it.c中:

其中的HAL_GPIO_EXTI_IRQHandler函数实现如下:

我们重写它的回调函数,实现翻转一次PC13(LED翻转):

编译下载到板子上后,将PA0引脚接触一下GND,可以看到LED有翻转。

由于这里没有去抖,将PA0接触GND时可能会产生多次中断,有可能LED的状态来回变化多次,可以在调试模式下,在中断中设置断点来观察,是否每次接触都会进入中断。

3)中断向量表的概念

在中断发生时,为什么会跳到如下这个函数来执行呢?

首先,我们在初始化时,开启了外部中断0(这是配置完cubemx自动生成的):

在MCU中,每个中断源会对应一个地址,当某个中断产生时,程序就会保存现场,自动跳转到这个地址去执行,执行完后再恢复现场,回到原来的程序执行。这些中断源对应的地址就是中断向量表。

如下图,stm32的工程代码中,启动文件中设置的中断向量表,都是跳转到某个函数执行:

这个启动文件里的中断向量表是从程序存储的地址起始开始往下排列的,每行占用4个字节(32bit),也就是说,EXTI0_IRQHandler在第23行,对应地址22*4=0x00000058;我们查看stm32f103的数据手册,发现这个地址就是外部中断0的中断向量地址:

所以,产生外部中断0时,会自动跳到其对应的中断向量表0x00000058处去执行,也就是调用EXTI0_IRQHandler函数。

4)中断向量表的重映射

在某些应用中,需要将中断向量表移到别处。比如说含有IAP功能的程序,一般bootlooder程序是从MCU默认启动的位置(地址0)执行,其中断向量表也在从0起始的位置;而app程序一般存储在bootlooder之后的一段地址中,这样app程序中定义的中断向量表就会偏离0地址。

为了正确访问中断向量表的地址,需要在app程序的起始,进行中断向量表的映射,可以用以下函数实现:

void NVIC_SetVectorTable(uint32_t NVIC_VectTab, uint32_t Offset)
{ 
  /* Check the parameters */
  assert_param(IS_NVIC_VECTTAB(NVIC_VectTab));
  assert_param(IS_NVIC_OFFSET(Offset));     
  SCB->VTOR = NVIC_VectTab | (Offset & (uint32_t)0x1FFFFF80);
}

如下使用,可以将中断向量表起始地址设置为0x08003000:

NVIC_SetVectorTable(0x08000000, 0x3000);

这里说明一下, stm32芯片的rom地址是从0x08000000开始的,如keil中的默认设置:

stm32芯片在内部自动进行了映射,把0x08000000和地址0进行了映射,所以app程序烧写到0x08000000地址,不用进行其他设置,也是可以访问到中断向量表的。

但是,如果app程序被烧写到了别的地址,如0x08003000,则需要程序中重新映射一下,使用这个函数:NVIC_SetVectorTable(0x08000000, 0x3000),这个用法以后讲到IAP的时候会用到。

好了,这一节的内容基本讲完了。

欢迎关注我的公众号,可留言“资料”获取相关程序和软件:

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:数字20 设计师:CSDN官方博客 返回首页
评论

打赏作者

xiaobaibai_2021

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值