STM32基于HAL库的中断流水灯

STM32基于HAL库的中断流水灯

实验要求:以 STM32 最小系统核心板(STM32F103C8T6)+面板板+3 只 LED 搭建电路,控制 LED 灯,轮流闪烁,间隔时长 1 秒。用 GPIOA 端某一管脚接一个开关(用杜邦线模拟代替)。采用中断模式编程,当开关接高电平时,LED 流水灯工作;接低电平时,LED 流水灯停止工作。

本次实验所使用的 STM32CubeMX 版本为 6.15.0

1.创建 CubeMX 项目

① 打开 STM32CubeMX 将鼠标移至 File 选择 New Project。

在这里插入图片描述

② 在弹出的窗口中搜索自己要使用的芯片,然后双击选择,之后就会看见芯片出现在界面中。

Tips:对于常用的芯片可以点击旁边的 ⭐ 收藏方便之后更快找到。

在这里插入图片描述

在这里插入图片描述

这样一个基本项目就创建完成了。

2.芯片配置

① 点击左侧侧边栏 System Core 然后再点击 SYS,将里面的 Debug 模式改为 Serial Wire,方便我们之后使用 ST-LINK 或其他方式来进行程序的烧录。

在这里插入图片描述

② 点击左侧 RCC,将里面的 High Speed Clock(HSE)调为 Crystal/Ceramic Resonator 来打开高速晶振时钟。

在这里插入图片描述

③ 接下来选择上方 Clock Configuration 来配置时钟树,将 PLL Source Mux 的输入选择为 HSE,再将 System Clock Mux 的输入选为 PLLCLK 这样我们的时钟源就配置好了。

在这里插入图片描述

④ 接着我们返回一开始的界面即 Pinout & Configuration 界面来配置 GPIO 口。点击你想要使用的 GPIO 口(这里我以 PA5 作为示例)选择 GPIO_Output 即可将其设置为输出模式作为之后用来点灯的 GPIO 口。

在这里插入图片描述

⑤ 点击左侧的 GPIO,再选择我们想要配置的 GPIO 口,然后进行如下操作:

​ a.GPIO output level 改为 High(即输出电平为高电平)。

​ b.GPIO mode 改为 Output Push Pull(即输出模式为推挽输出模式)。

​ c.GPIO Pull-up/Pull-down 改为 Pull-up(即 GPIO 的电平上拉到高电平)。

​ d.Maximum output speed 选为 Low(即最大输出速度为 Low,对于本次实验点灯来说此设置无明显影响)

​ e(可选).User Label 栏后可自定义 IO 口名称方便自己查看(尤其是使用端口较多时),并且可以在后续编程中使用,这里我将 PA5 命名为 LED0。

重复以上操作来配置其他两个 GPIO 口。这里我使用 PA5, PA6, PA7 这三个 GPIO 口作为流水灯的输出。

在这里插入图片描述

⑥ 选择一个 GPIO 口作为开关,这里我使用 PA2 作为示例。点击想要使用的 GPIO 口选择设置为 GPIO_EXTIx 也就是第 x 号外部中断线(x 的数字由端口数字决定)。

在这里插入图片描述

⑦ 点击左侧的 GPIO 选择刚刚设置为 GPIO_EXTIx 的 GPIO 口将其进行一下设置。

​ a.GPIO mode 设置为 External Interrupt Mode with Falling edge trigger detection(即下降沿触发)。

​ b.GPIO Pull-up/Pull-down 改为 Pull-down(即 GPIO 的电平下拉到低电平)。

​ c(可选).User Label 栏后可自定义 IO 口名称方便自己查看,这里我将其命名为 KEY0。

在这里插入图片描述

⑧ 点击左侧 NVIC 即中断控制器,然后勾选开启中断向量 EXTI line2 interrupt。

Tips:由于 EXTI0 到 EXTI4 有自己的中断向量,5-9 共享 EXTI9_5, 而 10-15 共享 EXTI15_10,所以选择不同的 GPIO 口此处所勾选的会有所不同。例如选择的 GPIO 口编号在 5-9 之间此处应勾选 EXTI line [9:5] interrupt。

在这里插入图片描述

⑨ 选择上方 Project Manager, 然后在 Project Name 栏为项目命名(最好确保名字及文件路径只包含英语或下划线‘__’因为 Keil5 不会识别中文),然后将 Toolchain/IDE 一栏改为 MDK-ARM 即使用 Keil5。

在这里插入图片描述

⑩ 点击左侧 Code Generator 勾选上 Generated files 的第一项,然后点击右上角的 GENERATE CODE 来生成代码,最后再点击弹出窗口中的 Open Project 即可打开 Keil5 对代码进行编写了。

Tips1:如果点击 GENERATE CODE 后提醒没有安装或需要更新包,点击下载即可。但下载需要登陆 ST 的账号,没有账号的可以自己创建一个。

Tips2:如果在已经打开 Keil5 对代码进行的情况下,由于更改了 CubeMX 项目中的配置需要再次生成代码不需要点击 Open Project,因为直接回到 Keil5 中时 Keil5 会提醒你文件更新了点击 OK 更新文件即可,如果点击 Open Project 可能会打开多个 Keil5。

在这里插入图片描述

在这里插入图片描述

3.代码实现

① 打开 Keil5 后点击左侧 Application/User/Core 文件夹旁边的 + 号展开,然后选择 main.c 文件,接着再 main.c 中找到 int main(void) 函数(64 行左右)中的 while(1) 这里就是我们编写流水灯主要功能的地方。

在这里插入图片描述

② 接下来我们来编写流水灯的主要代码。注意代码一定要在 /* USER CODE BEGIN WHILE *//* USER CODE END WHILE */ 之间,因为之后如果需要再次使用 STM32CubeMX 生成代码时在只有 /* xxx BEGIN xxx *//* xxx END xxx */ 的之间的代码才会被保留,其余位置的代码均会被删除。流水灯代码实现如下。

Tips:如果在之前的步骤中没有对 GPIO 口进行命名则应对部分代码进行修改,例如:

LED0_GPIO_Port,LED0_Pin 应更改为 GPIOA, GPIO_Pin_5

/* USER CODE BEGIN WHILE */
  HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);
  HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);		//设定初始状态为全灭
  while (1)
  {
	  if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)== GPIO_PIN_SET){
		  while(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)== GPIO_PIN_SET)	//判断按钮是否是高电平
		  {
			  HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_SET);			//LED0亮
			  HAL_Delay(1000);		//间隔1秒
			  HAL_GPIO_WritePin(LED0_GPIO_Port,LED0_Pin,GPIO_PIN_RESET);		//LED0灭
			  
			  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_SET);			//LED1亮
			  HAL_Delay(1000);
			  HAL_GPIO_WritePin(LED1_GPIO_Port,LED1_Pin,GPIO_PIN_RESET);		//LED1灭
			  
			  HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_SET);			//LED2亮
			  HAL_Delay(1000);
			  HAL_GPIO_WritePin(LED2_GPIO_Port,LED2_Pin,GPIO_PIN_RESET);		//LED2灭
		  }
	  }
    /* USER CODE END WHILE */

至此一个正常的流水灯就已经完成了,效果如下。

在这里插入图片描述

③ 然后来为流水灯添加一个开关并使用中断来控制。在左侧 Application/User/Core 文件夹中找到并打开 stm32f1xx_it.c 文件,然后下拉到该文件最底端就能看到中断处理函数 void EXTI2_IRQHandler(void)(其中 EXTI 后面的数字与使用的 GPIO 端口有关),我们就可以在这里编写开关控制的代码了。

在这里插入图片描述

代码实现如下:

  /* USER CODE BEGIN EXTI2_IRQn 0 */
	while(1){
		if(HAL_GPIO_ReadPin(KEY0_GPIO_Port,KEY0_Pin)== GPIO_PIN_SET){	//检测开关是否是高电平
			break;		//退出死循环,继续执行流水灯
		}
	}
  /* USER CODE END EXTI2_IRQn 0 */

至此我们已成功为流水灯添加了中断开关的功能了,其效果是当接通时流水灯正常工作,断开时暂停并保持暂停时的状态,效果如下。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值