STM32CubeIDE基础学习-EXTI外部中断实验

STM32CubeIDE基础学习-EXTI外部中断实验



前言

中断概念:让CPU打断正在执行的程序,进而去执行紧急的程序,退出中断后回到原打断中断处继续执行。

前面学习了GPIO作为输入功能的实验,现在来学习使用中断的方式实现GPIO功能的控制,直接在KEY的工程基础上进行添加中断的功能代码就行,其它的功能不用修改。

外部中断实验和KEY按键实验的现象是一样的,只是本实验采用的是中断的方式实现而已,前面按键使用的查询方式,比较耗CPU。

这里说明一下:
前面按键使用的是轮询的方式,本实验将采用中断的方式来实现功能的控制,本实验之所以可以用按键来控制蜂鸣器和LED,是因为刚好按键的引脚和中断线是重合的,所以就很好的借用了按键来触发边沿检测进而触发中断,实质和按键关系不是很大。当没有接按键,用杜邦线把该引脚接3.3V 或 GND也可以实现功能,有兴趣可以测试下。

STM32CubeIDE基础知识学习回顾

实验目的:
学习外部中断功能的使用,实现按键控制BEEP和LED状态翻转功能。


第1章 硬件介绍

本实验使用的开发板主控芯片是STM32F103C8T6,其核心原理图如下:

在这里插入图片描述

时钟来源使用的是外部高速8M晶振作为高速时钟。

KEY_UP按键接到芯片的PA0引脚上,KEY按键接到芯片的PA2引脚上,原理图如下图所示:

在这里插入图片描述

第2章 工程配置

本实验直接采用上一个按键实验的工程作为基础模板,直接拷贝粘贴即可,然后在上面添加EXTI和NVIC的相关功能配置即可,其它不用修改,就不用再新建工程了。

2.1 工程外设配置部分

配置GPIO,鼠标左键点击该引脚,前面按键输入实验设置的功能是输入的,现在是外部中断的实验,那么就需要设置为EXTI的方式了。如下图所示:

在这里插入图片描述

在这里插入图片描述

选择完成后如下图所示:

在这里插入图片描述

这个软件有一个好处就是能实时检测同一个中断线不能多个共存,当你选择了EXTI2后,其它EXTI2的引脚就选不了这个外部中断功能了,比如选了PA2引脚再选择PB2引脚,则会把PA2选择的功能覆盖掉只留下PB2的,这样就说明它们是不能同时使用的,后面就不会存在引脚冲突的问题了。

接下来就可以配置具体端口功能了。

端口功能配置如下:
1、模式配置为上升沿、下降沿和双边沿触发模式。
2、更据硬件原理图来设置输出上拉或下拉。
3、User Label建议定义一个自己喜欢见名知意的名字,方便写程序时查看和方便使用。

模式配置说明如下:

在这里插入图片描述
后面几个事件模式本实验没有用到,这里就不展开描述了。

注意
为了确保能稳定正确读取到按键的触发电平,这里KEY_UP是需要配置下拉输入。
为了确保能稳定正确读取到按键的触发电平,这里KEY是需要配置上拉输入。

配置EXTI0和EXTI2具体的引脚配置如下图所示:

在这里插入图片描述

KEY_UP引脚采取上升沿的触发方式,配置为下拉输入。

在这里插入图片描述

KEY引脚采取下降沿的触发方式,配置为上拉输入。

配置完EXTI了之后,就可以进行配置NVIC了,主要设置中断使能、中断分组、中断优先级等信息。如下图所示:

在这里插入图片描述

在这里插入图片描述

设置后如上图所示:要注意标号2处的抢占优先级选择问题,默认是15的,后面代码需要用到延时消抖,如果选择了默认15的话,优先级是最低的,触发中断后会一直卡死在延时里面而出不来,所以这里需要设置的优先级比外部中断的都要高才行,不然就会让程序出问题的。

一般情况下的程序不建议在中断里面放阻塞函数,比如延时、printf等,避免程序执行出错,而且中断执行需要遵循快进快出的原则,不用过多的嵌套复杂代码。

RCC时钟、调试接口都不用修改,保持默认配置即可。

最终配置的功能如下图所示:

在这里插入图片描述

到此,整个工程需要新增的功能就配置完成了,接下来就可以生成代码工程进行代码编写了。

2.2 生成工程代码部分

可以按快捷键ALT+K,或者点击生成图标按钮生成代码工程。

生成后最终会显示下图这样的代码:

在这里插入图片描述

可以看到继承了前面的外设功能代码,接着就可以在上面添加自己需要实现的中断控制功能的代码了。

第3章 代码编写

进入main函数后如下图所示:

在这里插入图片描述

可以看到有这个stm32f1xx_it.c文件,里面存放了生成中断相关的函数代码,可以双击进去看具体的函数定义。如下图所示:

在这里插入图片描述

可以看到有两个中断服务处理函数,接着就发现两个中断处理服务程序都调用了HAL_GPIO_EXTI_IRQHandler()函数,函数里面的参数是中断所在的引脚号,那么再跳进去HAL_GPIO_EXTI_IRQHandler()函数里面看具体定义,可以看到下面这个函数的定义情况。如下图所示:

在这里插入图片描述

进入之后,可以看到这个中断服务程序先判断中断线的,然后清除中断标志,最后就调用HAL_GPIO_EXTI_Callback()函数。

接着再进去HAL_GPIO_EXTI_Callback()这个函数,发现该函数在库里面是弱定义的,提示需要用户自己重新定义才行。如下图所示:

在这里插入图片描述

接着就可以在这个函数里面编写自己的代码了,可以看到这个函数是库提供的,是一个弱定义的函数,说明如果用户没有定义和该函数一样名字的函数,则执行这里面的代码,有检测到定义则执行用户定义的函数功能。

一般情况下都不会直接在这个函数这里面写功能代码的,需要拷贝这个函数到其它地方或其它文件进行编写,具体位置没有强制要求,但一般习惯拷贝到stm32f1xx_it.c里面其它位置进行功能代码编写。

编写完中断处理代码内容如下图所示:

在这里插入图片描述

代码片示例如下:

/* USER CODE BEGIN 1 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 	HAL_Delay(10);         /* 延时消抖 */
	switch(GPIO_Pin)
	{
		case KEY_UP_Pin :
			if(HAL_GPIO_ReadPin(KEY_UP_GPIO_PORT, KEY_UP_GPIO_PIN) == GPIO_PIN_SET)/* KEY_UP按下 */
			{
				HAL_GPIO_TogglePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN);   /* BEEP翻转 */
				break;
			}

		case KEY_Pin :
			if(HAL_GPIO_ReadPin(KEY_GPIO_PORT, KEY_GPIO_PIN) == GPIO_PIN_RESET)/* KEY按下 */
			{
				HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_GPIO_PIN);     /* LED翻转 */
				break;
			}
	}
}
/* USER CODE END 1 */

中断执行逻辑方式和前面按键查询方式是差不多的,当中断线被触发了之后就执行里面的功能代码。KEY_UP是上升沿触发中断,KEY是下升沿触发中断。

到此,采用中断方式控制BEEP和LED的代码就写完了,编译下载后按下对应的按键就可以看到蜂鸣器和LED翻转情况了。

附加部分
前面学习了按键使用宏定义的方式,那么也可以引入到这里来,可以让代码量看上去少了很多。如下图所示:

在这里插入图片描述

代码片示例如下:

/* USER CODE BEGIN 1 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 	HAL_Delay(10);         /* 延时消抖 */
	switch(GPIO_Pin)
	{
		case KEY_UP_Pin :
			if(KEY_UP == GPIO_PIN_SET)           /* KEY_UP按下 */
			{
				HAL_GPIO_TogglePin(BEEP_GPIO_PORT, BEEP_GPIO_PIN);/* BEEP翻转 */
				break;
			}
		case KEY_Pin :
			if(KEY == GPIO_PIN_RESET)            /* KEY按下 */
			{
				HAL_GPIO_TogglePin(LED_GPIO_PORT, LED_GPIO_PIN);/* LED翻转 */
				break;
			}
	}
}
/* USER CODE END 1 */

要注意,这里使用了相关的外设,则还要把相关头文件引入到这个stm32f1xx_it.c里面才行,不然会报错找不到定义的。如下图所示:

在这里插入图片描述

实现这个外部中断的功能就只需要在这个stm32f1xx_it.c文件里面完成代码编写即可,main函数的while里面以及其它所有的文件都不需要再添加写任何的代码了。

到此,整个中断控制的代码就全部写完了。

第4章 实验现象

编译下载代码后,按开发板的KEY_UP按键,可以听到蜂鸣器的状态发生了变化,当再一次按下按键时,蜂鸣器的状态也会翻转。当按下开发板的KEY按键后,可以看到LED灯的状态翻转了,再一次按下时,LED的状态又发生了翻转。当长按按键不松手,则程序会一直保持该执行的状态,能看到这些现象之后则说明这个代码编写逻辑是没有问题的。


总结

这个外部中断的内容不是特别难理解,代码逻辑和按键实验的差不多,当检测到IO的电平发生变化时,即可触发外部中断,进而执行中断服务函数。重点是理解中断线和回调函数的使用问题。

中断执行流程:
按键按下 > 检测到边沿信号从而触发外部中断线 > 跳转到中断服务程序执行该中断 > 最后进行执行中断回调函数。

注意事项:
1)STM32所有IO都支持外部中断功能,但是不同的端口(PORTA ~ PORTC)相同的PIN(PIN0 ~ PIN15)引脚就不能同时使用外部中断。

2)前面判断中断线时,在case里面用了if判断,这个是用于确认按键按下的,目的是为了更准确的判断该中断是否真正的被触发,如果不要这个if判断也是没有问题的,想要程序执行稳定,建议加上的。

  • 13
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
STM32F4系列的CubeIDE配置外部中断,您可以按照以下步骤进行操作: 1. 打开CubeIDE,并创建一个新的工程,选择适合您的STM32F4芯片型号。 2. 在工程文件树中找到 "Core" 文件夹,展开它并双击打开 "stm32f4xx_it.c" 文件。 3. 在 "stm32f4xx_it.c" 文件中,找到 "void EXTIx_IRQHandler(void)" 函数,其中 x 是您要配置外部中断线对应的数字。例如,如果您要配置外部中断线0,则找到 "void EXTI0_IRQHandler(void)" 函数。 4. 在相应的外部中断处理函数中,您可以编写您的自定义代码来处理外部中断事件。例如,您可以在函数内部添加代码来处理按键按下或触发的其他事件。 5. 在 "stm32f4xx_it.c" 文件中找到 "void EXTIx_IRQHandler(void)" 函数的开头部分,您会看到一些注释和预定义的宏。您可以根据您的需求来配置这些宏。 6. 在配置外部中断之前,您需要先进行GPIO的初始化和配置。您可以在 "main.c" 文件中找到 "MX_GPIO_Init(void)" 函数,并在其中配置外部中断引脚所对应的GPIO。 7. 配置外部中断的触发方式和优先级。您可以在 "main.c" 文件中找到 "MX_NVIC_Init(void)" 函数,并在其中配置外部中断的触发方式和优先级。 8. 最后,编译并下载您的代码到STM32F4芯片中。 请注意,以上步骤仅为一般的配置指南,具体配置方式可能会因您的需求和外部硬件的不同而有所变化。建议您参考ST官方文档和CubeIDE的用户手册来获取更详细的配置信息和示例代码。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值