HAL库LED点灯

一.CubeMX建项目

新建File->Project

image-20240520191309585

选择芯片STM32F103C8,并点击Start Project

image-20240520192225330

sys选择

image-20240520192438327

RCC选择

image-20240520192646035

选择端口输出设置

选择需要的端口,点击设置GPIO_OUTPUT,我选择的是,PA4,PB1,PC15
image-20240520193142615

image-20240520193428624

Clock Configuration设置

image-20240520193603540

Project Manager设置

image-20240520194201805

image-20240520194325638

创建完成并用keil打开

image-20240520194901385

image-20240520195748969

二、实验

LED流水灯

在main.c的while(1)循环中输入以下代码:

	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_RESET);
	HAL_Delay(1000);
	HAL_GPIO_WritePin(GPIOA,GPIO_PIN_4,GPIO_PIN_SET);
		
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_RESET);
	HAL_Delay(1000);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_1,GPIO_PIN_SET);
		
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_RESET);
	HAL_Delay(1000);
	HAL_GPIO_WritePin(GPIOC,GPIO_PIN_15,GPIO_PIN_SET);

接线图:

img

效果如下:

hal_led_flow

用GPIO端口完成2只LED灯的周期闪烁

在main.c文件的while(1)循环中写入:

		HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
		HAL_Delay(100);
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_1);
		HAL_Delay(100);

接线图:

image-20240522203858235

效果如下;

hal9_led

中断控制LED闪烁

内容:用GPIO端某一管脚接2个开关(用杜邦线模拟代替)。采用中断模式编程,当2分开关接高电平时,对应的两个LED灯停止工作(即停止周期性闪烁),接低电平时,恢复工作。

我用PA5,PC15口接两个LED,PB1口设置为上升和下降沿都触发中断,基本操作与前面的项目相同,唯一不同的是,用到了中断,所以要配置中断,PB1,设置为GPIO_EXTI1

配置EXTI

image-20240520212900323

image-20240522230828121

image-20240522230859811

​ 在" GPIO “参数配置中设置PB1为上升沿触发,内部既不上拉也不下拉,添加用户标签” WAKEUP "(也可以在配置引脚时修改用户标签)。

PA0的" GPIO mode "设置为下降沿触发,内部既不上拉也不下拉,添加用户标签S2。

PA5和PC15两个 LED 灯设置为推挽输出模式,内部既不上拉也不下拉,分别添加用户标签为LED2和LED3。

image-20240522232529571

打开生成的项目,找到stm32f1xx_it.c

image-20240521162111018

在stm32f1xx_it.c文件中找到所定义的外部中断处理函数,鼠标放在‘HAL_GPIO_EXTI_IRQHandler’上按F12可以看到函数原型,外部的两个中断触发后,首先会调用 GPIO 相应引脚的外部中断处理函数

image-20240522233044706

当中断发生时,调用 HAL _ GPIO _ EXTI _ Callback ()函数,但程序中只给出了一个虚函数,需要用户添加应用程序来实现相关功能。

image-20240522234036515

有__weak修饰表示这个函数是弱函数,它可以被同名的函数覆盖(我们需要在用户文件中,自己再定义一个一模一样的函数,只是我们自己定义的函数,不需要指明是弱函数)

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  if (GPIO_Pin == GPIO_PIN_0)//高电平,停止工作
  {
      state = 1; // 设置暂停标志
  }
   if(GPIO_Pin == GPIO_PIN_1)//低电平时,恢复工作
   {
       state = 0; // 清除暂停标志
   }
}

如果按正常的思路就是,在进入中断函数后,判断中断的触发方式,然后做响应的处理,但是由于下降沿触发中断时,要求我们执行LED灯闪烁,按照这种思路那必然要在中断里面写while循环、延时函数,就会导致中断函数的执行时间过长,一般中断里停留的时间不要过长,快进快出,一般中断只是做个标记,具体执行还是放到主函数去执行,不是放在中断函数里面执行。

主函数里面,也就是while(1)里面做标志位的判断并执行相应操作。于是我在主函数里面定义了一个多文件的全局变量state作为执行led闪烁的标志位(state为1时执行)

关于怎么让多个文件同时使用一个全局变量可参考:

多个文件中如何共用一个全局变量_不同文件定义同名的全局变量-CSDN博客

C语言 多个文件同时使用一个全局变量_c语言多个文件共用一个变量-CSDN博客

或者:

image-20240522190657678

image-20240522190720210

main函数

 while (1)
  {
   if(state==0)
	 {
		HAL_GPIO_TogglePin(GPIOA,GPIO_PIN_5);
		HAL_Delay(100);
		HAL_GPIO_TogglePin(GPIOC,GPIO_PIN_15);
		HAL_Delay(100);
	 }
  }

效果如下:

led_it_blink

因为在STM32CubeMX里面设置的PA5,PC15默认为低电平,所以按照我的接线图,按复位键后,LED默认点亮,我的红线是接的3.3v,当红线刚接触到PB1口的时候(上升沿),state被置为0,开始让LED闪烁,当红线刚接触到PA0口时发现并没有变化,当红线离开PA0口时(下降沿),主程序的LED闪烁被中止。

三、波形分析

内容:在没有示波器条件下,使用Keil的软件仿真逻辑分析仪功能观察LED管脚的时序波形,分析上面作业按键中断时,LED灯的波形变化情况

设置

image-20240523201140700

点击调试,并选择逻辑分析仪

image-20240523200617454

image-20240523200637512

点击setup,并设置观察引脚

image-20240523202346287

点击run运行

可以看到初始状态为低电平,与我在STM32CubeMX中设置是一致的
在这里插入图片描述
当state==0,LED闪烁,PA5和PC15的电位每0.2s变化一次,与代码的电平变化一致
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

总结:使用HAL库进行LED点灯,不仅实现了基本的硬件控制功能,更是在此过程中掌握了高效、灵活的开发方法,为后续进行更复杂项目开发奠定了坚实基础。

参考资料:多个文件中如何共用一个全局变量_不同文件定义同名的全局变量-CSDN博客

C语言 多个文件同时使用一个全局变量_c语言多个文件共用一个变量-CSDN博客

stm32cubeMX使用HAL库点亮LED流水灯,并用Keil仿真运行_keil仿真hal库-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值