【蓝桥杯嵌入式】四、各种外设驱动(三)NVIC中断程序通用步骤--中断服务程序

        由于内容比较多,为了更详细的说明,我也会花比较多的时间研究。而为了及时更新,我会把有些文章分成几个部分,谢谢大家理解 。

目录

前文链接:【蓝桥杯嵌入式】四、各种外设驱动(三)NVIC中断程序通用步骤——分析与配置-CSDN博客

三、代码编写

1、快速找到中断服务函数的方法:

2、编写中断服务函数

拓展:中断回调函数

1、查找

a、根据文件搜索

b、记住部分名称直接搜索

2、编写中断回调函数



三、代码编写

       先引入led.c和key.c

        将main( )函数中的代码清除。

        只需要写中断服务函数即可。

1、快速找到中断服务函数的方法:

先编译一下,建立文件之间的关联

CubeMX为我们自动生成的中断服务函数都在"stm32g4xx_it.c"文件中。

双击打开这个文件,直接向下滑动到最底部,中断服务函数就在这里:

现在找到了中断服务函数;

比赛时,你可以直接在这里处理中断。但更标准的做法是重写中断回调函数,感兴趣的可以去拓展部分查看。

2、编写中断服务函数

void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(KEY1_Pin);
  /* USER CODE BEGIN EXTI0_IRQn 1 */
	
  /* USER CODE END EXTI0_IRQn 1 */
}

这里有两个用户代码段,HAL_GPIO_EXTI_IRQHandler(KEY1_Pin)函数会清除中断标志位,为了避免无法响应多次连续中断应该先清除标志位,所以在第二个代码段实现功能会更合适。

根据之前的设计,编写代码。(建议自己写一下练练手)

在中断回调函数中编写代码,当KEY2按下时所有LED点亮,KEY1按下时熄灭LED1~4(为了验证正确性,这里延时1s)。KEY3按下后会产生软中断,出发EXTI0中断。

 代码如下:

/**
  * @brief This function handles EXTI line0 interrupt.
  */
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(KEY1_Pin);
  /* USER CODE BEGIN EXTI0_IRQn 1 */
    LED_change(LED5_Pin|LED6_Pin|LED7_Pin|LED8_Pin);
    HAL_Delay(1000);
  /* USER CODE END EXTI0_IRQn 1 */
}

/**
  * @brief This function handles EXTI line1 interrupt.
  */
void EXTI1_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI1_IRQn 0 */
			
  /* USER CODE END EXTI1_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(KEY2_Pin);
  /* USER CODE BEGIN EXTI1_IRQn 1 */
	LED_change(LED_ALL);
  /* USER CODE END EXTI1_IRQn 1 */
}

/**
  * @brief This function handles EXTI line2 interrupt.
  */
void EXTI2_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI2_IRQn 0 */
	
  /* USER CODE END EXTI2_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(KEY3_Pin);
  /* USER CODE BEGIN EXTI2_IRQn 1 */
	__HAL_GPIO_EXTI_GENERATE_SWIT(GPIO_PIN_0);
  /* USER CODE END EXTI2_IRQn 1 */
}

运行结果如下:

四、各种外设驱动(三)NVIC中断程序通用步骤,测试结果

可以发现,按下KEY1后,立即按下KEY2,是没反应的,大约1s后,才会点亮所有灯。说明程序运行正常。

拓展:中断回调函数

1、查找

a、根据文件搜索

可以看到中断服务函数调用了中断通用处理函数;

而中断处理函数会调用中断回调函数;

(就是这样一个俄罗斯套娃,这是为了为了可以让这种框架通用于各种芯片)

然后鼠标放到 HAL_GPIO_EXTI_IRQHandler 函数位置上,右击,然后点击 "Go To Definition ..."

如果,没问题的话,就会跳转到这里:

用同样的方式,右击 HAL_GPIO_EXTI_Callback 函数,跳转到这里:

这就找到了弱回调函数:HAL_GPIO_EXTI_Callback

如果熟练的话,找到这里只需要十几秒钟。

b、记住部分名称直接搜索

优点:快

缺点:要背部分函数名

HAL库中的一般外设的中断函数名都有规律。

一般为:HAL_XXXX_XXXX_Callback或HAL_XXXX_xxxxCallback

所以我们只需要先搜索 HAL_GPIO_EXTI

现在选择 "Find in files",输入搜索内容后,点击Find All

下面就会显示所有出现 HAL_GPIO_EXTI 字段的位置,将它向上拉起,如图:

在一列冒号后面,很容易找到有 "__weak ..."的函数,那就是我们要找的,双击即可跳转到改位置。

2、编写中断回调函数

 直接从 void 开始复制,复制如下内容:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

到main.c 的下图位置处:(在最下面然后朝上一点的位置,这里是实现弱函数的位置)

让它变成这样:

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	
}
/* USER CODE END 4 */

然后实现这个函数就行。

因为是通用回调函数,所以这里就需要做一些判断。

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin==KEY1_Pin)         //0
	{
		
	}
	else if(GPIO_Pin==KEY2_Pin)    //1
	{
		
	}
	else if(GPIO_Pin==KEY3_Pin)    //2
	{
		
	}
}
/* USER CODE END 4 */

根据之前的设计,编写代码。(建议自己写一下练练手)

在中断回调函数中编写代码,当KEY2按下时所有LED点亮,KEY1按下时熄灭LED1~4(为了验证正确性,这里延时1s)。KEY3按下后会产生软中断,出发EXTI0中断。

 代码如下:

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	if(GPIO_Pin==KEY1_Pin)		//1
	{
		LED_change(LED5_Pin|LED6_Pin|LED7_Pin|LED8_Pin);
		HAL_Delay(1000);
	}
	else if(GPIO_Pin==KEY2_Pin)//2
	{
		LED_change(LED_ALL);
	}
	else if(GPIO_Pin==KEY3_Pin)//2
	{
		__HAL_GPIO_EXTI_GENERATE_SWIT(GPIO_PIN_0);
	}
}
/* USER CODE END 4 */

运行结果完全相同。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值