STM32 —— 中断1 点灯

STM32 —— 中断1 点灯

实验目的

用 stm32F103 核心板的 GPIOA 端一管脚接一个 LED,GPIOB 端口一引脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED 亮灯;接低电平时,LED 灭灯。

这里我们令 GPIOB_4 为杜邦线的一端的固定引脚,另一端可以选择接在 GPIOA_6 或者 GPIOA_3 上,小灯泡接在 GPIOA_7 引脚上

实验原理

首先我们使用的是最小开发板上的三个引脚作为一种类似于开关的形式,

杜邦线的一端固定接在 GPIOB 的某一个引脚上,另一端有选择:

这里我们令 GPIOA_6 持续输出高电平,GPIOA_3 持续输出低电平,由于我们前面通过流水灯已经得到对应结论,小灯泡是低电平点亮,高电平熄灭,所以:

当杜邦线两端分别接在 GPIOB 和 GPIOA_3 上,小灯泡就被点亮,当杜邦线的两端分别接在 GPIOB 和 GPIOA_6 上小灯泡就熄灭

这里我们使用板载小灯泡用作程序测试,板载的小灯泡位置在引脚 GPIOC_13 上,只需要设置好当前引脚即可控制当前引脚上对应的小灯泡

板载小灯泡的使用

首先,我们要知道板载小灯泡对应的引脚位置,一般在最小系统板上会标出板载小灯泡的位置,本人使用的是基于 STM32F103C8T6 的最小系统板,所以板载灯泡对应的引脚是 PC13 ,需要将 PC13 引脚设置为 GPIO_Output :

image

然后需要设置 SYS ,将 Debug 选线设置为 Serial Wire 即可:

image

后面就可以参考流水灯的方法进行电灯即可

HAL 库方法

CubeMX 项目配置

引脚配置

引脚 功能
PC13 板载小灯泡引脚
PA7 外接小灯泡引脚
PB4 模拟按钮引脚
PA3 持续低电平输出引脚
PA6 持续高电平输出引脚

引脚配置如下:

image

配置 EXIT

我们将 PB4 配置为 GPIO_EXIT ,EXIT 默认为中断输出模式,所以,我们将中断使能,便于使引脚持续中断,可以持续看到实验效果

配置如下:

image

配置 GPIO 引脚输出

按照实验的要求,我们需要将 PA6 配置为持续高电平输出,将 PC14 配置为持续低电平输出,将 PB4 配置为上升沿和下降沿都可以触发,这样就能够真实的模拟出我们要达到的效果

image

代码设计

这里的代码设计很简单,头文件中已经给出了相对应的库函数,我们只需要重写就可以

首先我们需要找到 stm32f1xx_it.c 中的 EXTI4_IRQHandler(void) 这个函数:

image

void EXTI4_IRQHandler(void)

这个函数主要就是用来处理外部中断

如果引脚口为0,1,2,3,4时,外部中断函数为 void EXIT0(1/2/3/4)_IRQHandler(void) 这个函数里面只要是调用了

引脚口为5,6,7,8,9时,外部中断函数为:void EXIT9_5_IRQHandler(void)

引脚口为10,11,12,13,14,15时,外部中断函数为:void EXIT15_10_IRQHandler(void)

官方手册解释如下:

image

这个函数里面只要是调用了 HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4) 函数,获取产生中断的引脚

函数内容如下:

void EXTI4_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI4_IRQn 0 */

  /* USER CODE END EXTI4_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
  /* USER CODE BEGIN EXTI4_IRQn 1 */

  /* USER CODE END EXTI4_IRQn 1 */
}

可以选中 HAL_GPIO_EXTI_IRQHandler 按 F12 或右键点击后再选择如下,就会跳转到其函数:

image

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)

库函数如图:

image

函数内容如下:

void HAL_GPIO_EXTI_IRQHandler(uint16_t GPIO_Pin)
{
  /* EXTI line interrupt detected */
  if (__HAL_GPIO_EXTI_GET_IT(GPIO_Pin) != 0x00u)
  {
    __HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin);
    HAL_GPIO_EXTI_Callback(GPIO_Pin);
  }
}

重写中断函数

本实验只需要重写中断的 callback 函数即可

代码如下:

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  /* Prevent unused argument(s) compilation warning */
	if(GPIO_Pin == GPIO_PIN_4){
		GPIO_PinState pinstate = HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_4);	// 获取指定引脚输入电平
		switch(pinstate){
			case GPIO_PIN_RESET:{
				HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_RESET);
				break;
			}
			case GPIO_PIN_SET:{
				HAL_GPIO_WritePin(GPIOA,GPIO_PIN_7,GPIO_PIN_SET);
				break;
			}
			default:{
				break;
			}
		}
	}
}

获取传入参数的引脚

清除外部中断的位置:__HAL_GPIO_EXTI_CLEAR_IT(GPIO_Pin)

进入回调函数,用户重写该函数: HAL_GPIO_EXTI_Callback(GPIO_Pin)

回到函数 HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);直至跳出函数

注意:HAL库中外部中断是先清中断,再执行想在中断中做的事。

标准库方法

如有需要后续会更新标准库写法

寄存器方法

如有需要后续会更新寄存器写法

运行测试

接线示例

image

image

运行效果

image

波形检测

由于本代码需要进行接线控制,所以无法进行仿真波形测试,如有需要,可以自行通过示波器进行波形测试

错误解决方法

error: At end of source:  #67: expected a "}"

这个报错就是说前面的 { 和后面 } 的数量不等,所以不能匹配,只要对应好数量即可

参考文档

  1. stm32外部中断模式控制灯亮灭

  2. STM32(寄存器)学习笔记——实验五:外部中断

posted @ 2022-10-22 23:44  ppqppl  阅读(183)  评论(0编辑  收藏  举报