STM32F1基于HAL库的学习记录实用使用教程分享(三、外部中断 按键)

往期内容

STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)
STM32F1基于HAL库的学习记录实用使用教程分享(二、GPIO_Input 按键)


前言

本文记录了通过使用STM32F103ZET6单片机进行GPIO_Input的学习

随着嵌入式行业的兴起,于此记录个人的一些学习过程并进行分享,本次是单片机控制里很重要的一个概念:外部中断


声明:本文章在编写过程中,我始终致力于尊重并保护所有原创内容及其知识产权。然而,由于信息来源的多样性和复杂性,可能存在个别内容未明确标注出处、存在事实性错误或无意中侵犯了他人的知识产权的情况。对于任何可能存在的上述问题,我深感歉意,并在此提前向受影响的作者表示最诚挚的歉意。我始终秉持着尊重原创、维护知识产权的原则,绝无意侵犯任何人的合法权益。一旦收到您的反馈,我将立即核实并在第一时间内对文章进行修改。这包括但不限于补充相关引用信息、更正错误内容或删除涉嫌侵权的内容。再次感谢您的关注与支持,期待与您共同营造一个更加美好的知识共享空间。新手文章诸多不足,还望海涵。

一、外部中断

中断机制在计算机系统中区分为硬件中断和软件中断两大类别。
硬件中断源自外部设备,如硬盘I/O的信号或通过定时器到达,它们通过发送信号以异步方式请求CPU的注意,即中断的发生与CPU当前执行的程序逻辑无直接关联。
外部中断实际上是硬件中断的一个子集。

软件中断是由程序内部执行的特定指令(如中断指令或系统调用)所触发,其发生时间与程序执行流程紧密相关,因此被视为同步的。

这两种中断机制共同协作,确保了计算机系统既能及时响应外部事件,又能灵活管理内部资源和服务调用。

1.概念

中断:打断CPU执行正常的程序,转而处理紧急程序,然后返回原暂停的程序继续运行。
举例:学习ing-------听到老妈叫:吃饭啦!(中断请求)-------前去干饭-------吃完了-------继续学习

2.中断的作用

一般来讲,中断有三个作用:
实时控制:当温度较高时,自动开启空调功能。
故障处理:出现错误时及时修正。
数据传输:串口或其他通信方式进行数据的传输

3.中断优先级

在中断处理机制中,优先级系统是为确保系统资源的高效分配和紧急事件的及时处理。

包括抢占优先级(pre)和响应优先级(sub)两个关键层面。抢占优先级决定了中断的打断能力,即高抢占优先级的中断能够打断正在执行的低抢占优先级中断,确保紧急任务得到优先处理。而响应优先级则在抢占优先级相同的情况下发挥作用,它决定了中断的响应顺序,即响应优先级高的中断会先被执行,但不同响应优先级的中断间不能相互打断。

当抢占优先级和响应优先级都相同时,自然优先级(通常基于中断向量表中的位置)将作为决定因素,自然优先级越高的中断将先被执行。这里的自然优先级实质上反映了中断在硬件或固件设计中的优先级排序。

在中断优先级体系中,通常遵循“数值越小,优先级越高”的原则,这意味着更低数值的优先级设置代表更高的中断处理优先级,从而确保系统能够迅速响应最紧急的事件

二、配置

在选择好芯片并进入配置界面后的操作如下进行

1.RCC

外部的高速和低速时钟均有三个可选项目,具体情况需根据个人的硬件情况进行个性化配置,一般选择高速时钟下的:Crystal/Ceramic Resonator(外部晶体/陶瓷谐振器)如图2-1所示:
图2-1 RCC

2.SYS

(1).Debug

在STM32CubeMX中配置系统(SYS)时,关于调试接口的设置是一个重要环节。默认情况下,调试功能可能被启用,但如果不需要实时调试或希望优化资源使用,可以选择关闭调试(即选择“No Debug”选项)。然而为了开发便利,我们一般都保留调试接口。

在调试协议的选择上,STM32CubeMX提供了SW(Serial Wire)和JTAG两种选项。鉴于SWD(Serial Wire Debug)模式仅需要两个引脚,且兼容性好、调试效率高,因此它是许多开发者的首选。我选择使用SW协议

(2).System Wake-Up

System Wake-Up功能允许STM32微控制器在低功耗模式下被特定的外部事件唤醒。这些外部事件可以包括但不限于外部中断、RTC闹钟、USART接收数据等。

通过配置System Wake-Up功能,微控制器可以在不需要时进入低功耗模式以节省电能,同时在需要时能够快速响应外部事件并恢复正常工作。

(3).Timebase Source

通过对 Timebase Source进行合理配置以确保程序的正确运行。通过选择合适的Timebase Source(如SysTick或TIMx),并合理配置其参数,可以实现高效、可靠的时间管理功能。
图2-2 SYS

3.时钟树

依此点击:PLL、Enable CSS、HCLK(MHz)改为72之后回车即可。
图2-3 时钟树

4.引脚配置

(1).选择引脚和模式

本文是基于第一篇文章的LED后进行的操作,有不了解的同学可以移步STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)进行配置。
根据硬件点击所需要使用的引脚,之后在弹窗里选择GPIO_EXIT,如图2-4 :
图2-4 GPIO_EXIT

(2).进行细节配置

根据硬件进行细节配置,如图2-5 :

(A).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

上升沿或下降沿触发外部中断

External Event Mode with Rising edge trigger detection

上升沿触发外部事件

External Event Mode with Falling edge trigger detection

下降沿触发外部事件

External Event ode with Rising/Falling edge trigger detection

上升沿或下降沿触发外部事件

(B).GPIO Pull-up/Pull-down

通过电路的硬件结构进行上拉或下拉配置

©.User Laber

用户标号,给引脚定义一个易识别的名称,以此以提高代码的可读性和可维护性。我直接定义为:KEY(在此我仅以PE6举例,其他引脚(按键)同理)。
图2-5 细节配置

(D).配置优先级
Priority Group

默认为4个比特位,一般情况下不需要改。

Preemption Priority & Sub Priority

抢占优先级,数字越小,优先级越高
若抢占优先级相同,判断子优先级,同样,数字越小,优先级越高
图2-6 NVIC 优先级

6.工程项目生成

(1).项目及编译器

(A).Project Name

给工程起个名字

(B).Project Location

给工程选个存放位置,避免中文路径

©.Toolchain/lDE

IDE选择,我在这里选择的是MDK-ARM(即Keil 5)
图2-8 项目命名及选择编译器

(2).代码生成

以下配置勾选后点击界面右上角的:GENERATE CODE

(A).Copy all used libraries into the project folder

将所有使用过的库复制到项目文件夹中

(B).Generate peripheral initialization as a pair of’c/.h’ files per peripheral

每个外设生成独立的’.c/.h’文件
图2-9 代码生成

三、程序

sys.h、led.h、stm32f1xx_it.c和stm32f10x_it.h在我的第一篇博客STM32F1基于HAL库的学习记录实用使用教程分享(一、GPIO_Output)里。

1.HAL_GPIO_ReadPin(GPIO_TypeDef* GPIOx, uint16_t GPIO_Pin);

此函数用于读取引脚状态,通过GPIO的IDR寄存器读取。
电平输出HAL函数
GPIOX代表目标引脚的端口号,例如GPIOE。
GPIO_Pin代表目标引脚的引脚号,例如GPIO_Pin_6。
在main.h中可找到宏定义:

/* Private defines -----------------------------------------------------------*/
#define KEY_Pin GPIO_PIN_6
#define KEY_GPIO_Port GPIOE
#define KEY_EXTI_IRQn EXTI9_5_IRQn

设置按键回调函数为

  /* USER CODE BEGIN 4 */
  void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin == KEY_Pin)
	{
			if(Exit_flag == 0)
			{
					Exit_flag = 1;
					LED_flag = HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin);
			}
	}
}
  /* USER CODE END 4 */

在主函数循环内检测

 while (1)
  {
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
		if(Exit_flag == 1)
		{
			Exit_flag = 2;
			if(LED_flag== GPIO_PIN_RESET)
			{
				HAL_Delay(20);
				if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_RESET)
				{
					HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
					Exit_flag = 0;
				}
				else
				{
					Exit_flag = 0;
				}
			}
			else if(LED_flag== GPIO_PIN_SET)
			{
				HAL_Delay(20);
				if(HAL_GPIO_ReadPin(KEY_GPIO_Port, KEY_Pin) == GPIO_PIN_SET)
				{
					HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
					Exit_flag = 0;
				}
				else
				{
					Exit_flag = 0;
				}
			}
   	 	}
  }

以此实现按键控制小灯状态的功能。

四、演示效果

外部中断按键

总结

本篇内容略少,但这也是为后期的内容做铺垫衔接。后面的内容“干货”会更多一些,敬请期待。

又是经过一个充实而忙碌的夜晚,深知文章中仍不免有诸多省略和未及细讲之处。对于那些在阅读过程中仍感意犹未尽、存有疑问的同学,建议大家不妨拓宽视野,多阅读几篇来自不同作者、风格各异的优秀文章。相信通过多角度、多层次的学习,你们定能集百家之长从而对单片机有更加深入和全面的理解。

在此,我的初衷不仅是为初学者提供一份学习路上的指引,也是对自己学习历程的一次回顾与总结。通过分享,我希望能激发更多人对单片机技术的兴趣,共同探索这片充满挑战与机遇的领域。

为了保持内容的连贯性和避免不必要的重复,我计划在未来的博客中,对于本文中已提及但未深入展开的话题,将通过链接的方式引导大家回到本文进行查阅。同时,我也将不断优化和完善文章内容,力求为大家提供更加准确、全面、易于理解的学习资源。

下期预告——关于**OLED屏幕(IIC)**的学习分享。

与此同时我计划将我的微机原理课程设计逐步分享出来

感谢大家的关注与支持!


参考文献引用

【STM32HAL库】外部中断
STM32 CubeMX学习:6. 按键的外部中断

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

藤樂.

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

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

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

打赏作者

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

抵扣说明:

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

余额充值