STM32学习笔记(CubeMX配HAL)(第三天:中断)

今天可能会学得比较多,所以说三四五可能会全部连着一起更新

如果说时间比较紧张的话,一天还是只学一节就差不多了

今天学一下中断,中断这个东西很重要,在单片机微处理器这些环节里面,中断的核心位置是难以动摇的。

首先中断包括啥呢,中断源,中断向量(中断源的地址啥的),中断优先级,中断服务函数啥啥啥的。

对于STM32而言,是M3内核的,有16个内部中断,240个外部中断。256个中断优先级。因为STM32相较于51这种旧时代的微处理器而言,更加智能,所以说。STM32的中断通道存在多个中断共用的情况。就是说啥呢,某一个中断服务函数,被多个中断源所共同使用。所以说,在终端服务函数的入口处,就需要一个判别机制,判断优先级或者哪个中断又中断了谁谁谁。

STM32有两个优先级:抢占优先级和响应优先级

处理过程存在一个规律,大概就是:存在多个抢占优先级的中断,就看谁的抢占优先级高。如果说抢占优先级一样高,就处理响应优先级高的。如果谁抢占优先级和响应优先级一样高,这时候就按照中断的自然排序来处理中断。

在内核中有个叫NVIC的东西,就会对中断进行统一的一个协调和控制。主要就是来控制中断使能和确定中断优先级。

然后来了解下STM32的外部中断。(即来自外部GPIO的中断请求)

STM32有61个外部中断源,EXTI0---15,其中0-4都是专用的,其他的全是共用的。

EXTI0的引脚就是PA0----PG0

EXTI1就独赢的是PA1----PG1

        ...........

       以此类推

中断源的触发条件主要是三种:上升沿,下降沿,双边沿----

那么接下来就需要一些程序的设计思路:

首先:GPIO初始化配置

然后:配置GPIO的引脚与中断线的映射关系

再者:配置GPIO对应的中断触发条件

之后:配置NVIC并使能中断

最后:编写中断服务函数

那么对于STM32CubeMX,GPIO就需要配置中断初始化参数了,在程序中需要写中断回调函数;

那么接下来就举一个例子,用一个key按键作为外部中断,设置为下降沿触发,然后编写中断函数,使得LED电平翻转(感觉就是换个思路处理按键。。。。)

其中CubeMX中需要吧GPIO设置为GPIO_EXTI功能,然后设置触发条件(上面提到的那三种)

最后使能一下NVIC的通道;

然后剩下的就是编写中断服务函数了

其中中断函数会涉及到的东西可以列在这里做一个小小的解读:

由于我这里使用的是F103RC,调用的是PC13的引脚,所以CubeMX给我的函数是:
EXTI15_10_IRQHandler(就是说10-15位置的意思)

之后第一行使用了一个中断的处理函数:

HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);

一般看不懂的时候就用ctrl+F进入函数定义的位置去看一看。

一般来说

HAL_GPIO_EXTI_IRQHandler中只需要看明白两句话就行(因为其他看不太懂……)

第一个是:

HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN):主要是清除中断标志,然后才会让内核发现

HAL_GPIO_EXTI_Callback(GPIO_PIN):回调函数,这玩意儿的定义是用的_ _WEAK就是一个虚函数。(因为C++没有学到面向对象编程,所以对虚函数不是特别的了解)

然后用户重写虚函数之后,它大致实现怎样的功能呢?就是判断GPIO_PIN是否是GPIO_PIN_13,然后直接对LED进行反转,之后就一直循环读取GPIO13,来判断是否为低电平。

这次就在CubeMX里的设置就会多一点点东西。虽然LED灯我们还是设置为OUTPUT的模式,但是按键我们就不再设置为输入模式了,而是设置为EXTI的模式,然后进入GPIO的设置后,KEY的设置就是上拉电阻,然后分别选择下降沿或上升沿(作为实验使用,一般来说,你想设置成啥触发,都是看项目要求来决定的)

然后就可以生成代码。

这里一般来说,多了一个函数

这个函数主要是处理中断所用。

在gpio.c里面也多了几行:

STM32学习笔记(CubeMX配HAL)(第三天:中断)_第1张图片

即NVIC的一个初始化;

那么接下来,我们就需要重写一下回调函数;

我们可以通过ctrl+F来找到Callback的函数位置。

因为它是一个虚函数,啥也没做,所以需要重新写。一般来说在main里面写或者你用新的头文件写都可以。

STM32学习笔记(CubeMX配HAL)(第三天:中断)_第2张图片

我们直接吧函数体复制到main.c函数的主题上方,重新void一个函数,就可以产生作用了。

那么我定义了如下的新的回调函数:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == GPIO_PIN_13){
	
	   HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_2);
	
	}
	if(GPIO_Pin == GPIO_PIN_0){
	
		HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_3);
		
	}
}

 这样就可以达到中断反转电平的效果了!!!

但是我好像还是没搞明白一些事儿,所以我决定再看看函数体的一个定义。因为再IF语句中,没有提到GPIO的A-G选择的问题。我因为这个疑问,翻了下中断使能以及很多的声明,还是没有发现有函数在括号里选择了GPIOx。所以我姑且认为如下:

因为CubeMX最开始的初始化中,只有PC13和PA0的中断和GPIO是进行了初始化的。所以说当我们使用EXTI0和EXTI13的时候,虽然GPIOA-G都是可以使用的,但是由于初始化GPIO口就他俩,所以说使用了这俩的中断,而其他的GPIO端口NVCI是没有进行初始化的。所以说,需要只有他俩可以使用中断(感觉发现后,我有点小蠢。。。)

你可能感兴趣的:(笔记,stm32)