一.中断的简单介绍
对于之前的串口配置,之所以把串口中断搁置是因为它牵扯到中断这一概念,而我觉得中断对于像我这样的初学者来说是较为难理解的概念,所以,我专门把中断这个应用拿出来。但是也是很浅显的一点点,毕竟中断牵扯的确实有点多,外部中断(EXIT),串口中断,ADC中断及各种外设中断,我并不想在这里解释太多,因为我自己还有很多地方要学习,所以把外部中断拿来分享一下。
中断
中断是指计算机正在运行程序时,出现某些意外需要主机干预,主机可以暂停正在进行的事情,转而去干预处理意外事件,等到处理完意外事件时,可以继续返回原先被暂停的事情中继续执行。
外部中断
外部中断是单片机实时地处理外部事件的一种内部机制。当某种外部事件发生时,单片机的中断系统将迫使 CPU 暂停正在执行的程序,转而去进行中断事件的处理;中断处理完毕后.又返回被中断的程序处,继续执行下去。
(之后我们所说的中断无特殊说明均为外部中断。)
其中,我们还要理解优先级的概念,虽然我们摆脱了标准库函数中对于NVIC的各种配置(包括优先级的配置),但是还是要理解一下这个概念,如果,你设置了多个中断就需要考虑这些。
eg.打个比方,你正在吃西瓜,但是西瓜不幸让你肚子难受起来。这个时候你要去窜了 上厕所,那么,这个上厕所就是意外事件,打断了你吃西瓜的事情,并且,上厕所这个事的优先级比吃西瓜要高,所以,你必须中断吃西瓜,而应该选择更重要的事窜 ,可是,这时你妈妈敲门表示要进屋,这个优先级就更高了,你要先给妈妈开门,再去上厕所。等你上完了,这个中断事件完全结束,你又可以返回吃西瓜的状态了可能你还要窜。
“道理我都懂,单片机上怎么触发呢?”
我们这时需要一个中断源,他可能是按键,或者ADC等等,通过外部连接我们的IO口,实际上连接到我们单片机的控制模块上。我使用的STM32F103ZETx,144个IO口,对应16根中断线,其中是怎么运行的呢?
在STM32中文参考手册V10上表明了他的工作方式,我们可以看到PX对应的数字就是EXIT的中断线数字标号,这也同时说明了,如果我们使用PA0为中断对应IO,EXIT0就被用掉了,PB0再用中断IO就不可以了,而这些都是在EXIT的寄存器里修改的,(我只能说寄存器yyds),
而在这张图的注释一中有关AFIO的注释,这与我们的GPIO可是不同,如果你看过库函数,对这个问题感兴趣,可以钻研一下,GPIO是不复用的通用输入输出引脚,而在原理图上一个引脚可能会有不同功能,这时要关注它挂在APB1还是APB2总线上,在这里给大家一个传送门供大家参考,以后有机会再赘述。STM32F103:什么时候需要复用IO(AFIO)?
下面我会演示用外部中断接收来自信号发生器的PWM信号。
二.CUBEMX相关配置
1.初始化引脚
最好在此之前打开之前配置好的uart工程,如果你想使用 PA1 作为外部中断的接收引脚,那么你只需要点击 PA1,在点击它对应的 GPIO_EXTIx。
这里我用used label注明PWM,以便我之后在中断函数中调用。
使能中断
在GPIO里点击PA1,在下面configuration按图操作
这个地方与此前不同的地方在于 GPIO mode。
External Interrupt Mode with Rising edge trigger detection//上升沿触发
External Interrupt Mode with Falling edge trigger detection//下降沿触发
External Interrupt Mode with Rising/Falling edge trigger detection//上升沿或下降沿触发
注意标黄的地方,是外部中断,与后面的EVENT事件中断不一样,我们每接收一次PWM波中上升沿就进一次中断,之后pull down(拉低),以便再次接收到上升沿信号。
点击NVIC,勾选EXIT line1 interrupt使能(ENBALE),
Project Manager配置在之前我的文章里配置GPIO
之后检查无误后点击
生成代码文件。
3.添加相关代码
在你的/* USER CODE BEGIN 4 */与/* USER CODE END 4 */之间添加
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
}
这是我们的外部中断回调函数,直接放在这里,其中加入我们的判断与中断相关操作,比如我们在这里判断检测的引脚是否接收到了GPIO_Pin_0的中断触发信号,这时我们将设置一个每检测一次就自增的值
if(GPIO_Pin == PWM_Pin)
{ // 判断触发引脚是否是定义的引脚
pwm_value++;
}
/* USER CODE BEGIN PV */
int pwm_value=0;
/* USER CODE END PV */
main函数中添加
while (1){
pwm_value = 0; // pwm_value置0,这个是必须要做的,数据要刷新
HAL_Delay(1000); // 延时1s
printf("[tmain]info:pwm_value=%drn",pwm_value); // 读取pwm_value
}
编译并运行,将信号发生器输出端连接在PA1上,再与单片机共地。
改变频率值,效果如图:
上一篇:STM32F1系列启动过程简单讲解
下一篇:STM32F1系列HAL库配置串口通信(2)——串口重定向以及log信息格式输出
推荐阅读最新更新时间:2024-11-06 11:15