STM32中断的学习

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

                它属于内核的外设,在HAL库中,如何使用配置NVIC可在_cortex.c后缀的文件中找到。

它管理着中断向量表中的中断,而它同样是由各种寄存器所组合而成的。

① ISER[8]: "Interrupt Set-Enable Registers",一个中断使能寄存器。

②ICER[8] :   "Interrupt Clear-Enable Registers",中断除能寄存器。

③ISPR[8] :   "Interrupt Set-Pending Registers",  中断挂起控制寄存器,通过置1,将正在进行的中断挂起,执行优先级更高的中断,写0无效。

④ICPR[8] :  “Interrupt Clear-Pending Registers”, 中断解挂控制寄存器,作用与ISPR相反。写一解除挂起,写0无效。

⑤IABR[8] :  “Interrupt Active Bit Registers ”,中断激活标志位寄存器,对应的位和ISER一样,这是个只读寄存器,可通过它知道正在执行中断的是哪一个,中断结束后由硬件自动清零。

⑥ **IP[240] :  "Interrupt Priority Registers ",是一个中断优先级控制的寄存器。优先级:先看抢占优先级,若同级再看响应优先级。(都是数字越小优先级越高)(PS:若都相同,则有硬件优先标识符决定)

        那么我们既然了解了nvic的寄存器组成,用hal库该怎样去配置呢?

1.先进行中断优先级的分组

        使用 " HAL_NVIC_SetpriorityGrouping()函数 " 

//函数定义
void HAL_NVIC_SetPriorityGrouping(uint32_t PriorityGroup)
{
  /* Check the parameters */
  assert_param(IS_NVIC_PRIORITY_GROUP(PriorityGroup));

  /* Set the PRIGROUP[10:8] bits according to the PriorityGroup parameter value */
  NVIC_SetPriorityGrouping(PriorityGroup);
}

PS:如果使用CuneMax生成代码,那么这个会放在HAL_Init()函数中,并且该函数所需参数已经宏定义完成,我们只需按照此仿照即可(NVIC_PRIORITYGROUP_4),这个为默认值。

2.设置抢占优先级和响应优先级

        中断分组设置完成后,要开始对组内的优先级进行设置。每个分组有各自的抢占优先级和响应优先级的位数。

        

        之后我们再对使能中断通道。

//用来设置单个优先级的抢占优先级和响应优先级的值
void HAL_NVIC_SetPriority(IRQn_Type IRQn,uint32_t PreemptPriority, uint32_t SubPriority);
//用来使能某个中断通道
void HAL_NVIC_EnableIRQ(IRQn_Type IRQn);
//用来清除某个中断使能的,也就是中断失能
void HAL_NVIC_DisableIRQ(IRQn_Type IRQn);

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

        实际在使用HAL库开发时,nvic大多被软件配置完成,我们只需配置EXTI部分即可。

但我们本着学习的态度,还是要了解exti的相关寄存器。

如图所示,EXTI经检测后会传递给NVIC,由其在进行相关处理。

1.外部中断/事件线路映像(即I/O口对应的中断线)

        PA0 --  PG0都对应EXTI0......其他的类似(到EXTI15截止)

        而EXTI16-19也作为EXTI外设的输入线,如图:

但这么多的中断线并不是都有独立的中断服务函数,只能使用7个中断服务函数

其各自对应的中断服务函数名可以在启动文件中找到,如:EXTI0_IRQHandler......

2.EXTI功能框图

        

只有输入给NVIC后,中断才会被处理,上升沿和下降沿触发选择寄存器在设置时,选择其一或全选都行。其中的事件屏蔽寄存器和软件中断事件寄存器很少进行操作,默认置1。

脉冲发生器那块不需要cpu处理,因为运行速度很快,由硬件自动完成。此脉冲一般用来触发TIM或ADC.

3.EXTI各个寄存器描述

        ①上升沿/下降沿触发选择寄存器(EXTI_RTSR/FTSR)

                ②中断/事件屏蔽寄存器 (EXTI_IMR/EMR)

        ③软件中断事件寄存器(EXTI_SWIER)

        ④挂起寄存器(EXTI_PR)

在认识了这些寄存器后,我们该在HAL库中如何使用函数来实现这个功能呢?

        首先初始化中断的GPIO为EXTI模式,有中断就有中断服务函数,然后我们有两步处理中断的方法,①直接跳转到指定的中断服务函数中,然后执行中断服务函数,再执行外部中断通用处理函数,其中调用了外部中断回调函数,然后在最后判断并清除中断标志。(我们可以再中断通用处理函数那里面直接写需求,这样可以不用写回调函数了)

②在main.c中直接重新写一个外部中断回调函数。(好用)

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	switch (GPIO_Pin)
	{
		case GPIO_PIN_0:
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_8,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);  
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
		break;
		case GPIO_PIN_1:
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_9,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);  
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
		break;
		case GPIO_PIN_2:
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_All,GPIO_PIN_SET);
			HAL_GPIO_WritePin(GPIOC,GPIO_PIN_10,GPIO_PIN_RESET);
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_SET);  
			HAL_GPIO_WritePin(GPIOD,GPIO_PIN_2,GPIO_PIN_RESET);
		break;
			
		default :
			break;
	}
}

      

  • 13
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值