STM32项目 “红蓝警示灯” GPIO的应用

本文档介绍了基于STM32CubeMX和MDK5的STM32F103ZET6单片机,设计并实现了一个简单的红蓝警示灯程序。程序通过定时10ms轮询控制LED灯闪烁,设有四种模式,包括红灯慢闪、蓝灯慢闪、红蓝交替闪烁和全灯熄灭。按键功能包括短按模式切换和长按关机。文中还提到了程序的优化建议和详细的代码实现,是单片机控制LED灯应用的一个实例。
摘要由CSDN通过智能技术生成

软件:STM32CubeMX Version 6.2.1
      MDK5 for ARM
硬件:战舰精英V3 STM32F103ZET6



前言

  红蓝警示灯是大街上最常见的一种单片机产物,同时款式功能也是多种多样。虽然款式不同但主要还是分为两种,一种是固定程序款,另一种是可编程款。今天这里就以红蓝两个LED设计第一种简单的固定程序款的“红蓝警示灯”。此程序常用在带警示灯款式的手电筒,之前在古镇从事LED照明程序设计时就帮一客户设计过类似的产品。


一、功能设计

  此项目使用的外设硬件也比较简单,只有按键和LED灯。程序设计思路采用定时10ms轮询的方式,LED灯闪烁主要就是控制延时,单时间线程序。

1.1.输入按键功能

这里我只使用了一个按键进行控制输出模式的切换及关机。
上电后默认工作在模式一(红色慢闪)。
按键功能;
     1;短按按键后切换到下一模式,一直到最后一个模式(关灯),如果再短按又回到模式一。
     2;在任何模式下长按按键切换到关机模式,这里设计体验感差的地方是长按按键后会先执行一次短按功能然后再执行长按关机。在关机模式下也是如此。

  优化方法可以在长按松开时判断短按,如果松开时按键按了小于200ms/500ms则认为是短按。

1.2.输出LED灯的功能及模式

目前设计了4种模式;

  1. 红色LED以500ms慢闪,蓝色LED熄灭;
  2. 红色熄灭,蓝色LED以500ms慢闪;
  3. 先红色LED以150ms连续闪烁两次,然后全部熄灭800ms后蓝色LED以150ms连续闪烁两次,
    然后全部熄灭800ms再回到红色LED闪烁;
  4. 全部熄灭。(有时间的可以在此模式加入休眠程序用按键唤醒,以降低待机功耗。)

二、程序流程思维导图

红蓝警示灯流程图

三、编写用户程序代码

  新建项目请参考我之前写的一篇博文。

STM32CubeMX第一章 GPIO

3.1 增加全部变量

/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
uint8_t  Flash_Mode =0,LED_Step =0;
uint16_t LED_Delay =0;
/* USER CODE END PV */

3.2 主函数

int main(void)
{
  /* USER CODE BEGIN 1 */
  uint8_t key_status=0,long_key=0;

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  /* USER CODE BEGIN 2 */

  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
	/* USER CODE END WHILE */
    /* USER CODE BEGIN 3 */
		HAL_Delay(10);  //延时10ms
/****************** 按键检测 ***********************/
		if(key_status==0 && HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) ==GPIO_PIN_RESET)//检测按键首次按下
		{
			key_status =1;
		}
		else if(key_status==1 && HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) ==GPIO_PIN_RESET)//消抖后再确认真的按下
		{
			key_status =2;
			long_key =0;
			LED_Step =0;
			LED_Delay =0;
			if(Flash_Mode++>=3)
			{
				Flash_Mode =0;
			}
		}
		else if(key_status==2 && HAL_GPIO_ReadPin(GPIOE,GPIO_PIN_2) ==GPIO_PIN_RESET)//短按只执行一次,可添加长按判断
		{
			key_status =2;
			if(long_key++>=150)//长按判断时间为1.5秒
			{
				long_key =150;
				Flash_Mode =3;
			}
		}
		else
		{
			key_status =0;
		}
/****************** LED灯闪烁 ***********************/
		switch(Flash_Mode)
		{
			case 0:Mode1();break;
			case 1:Mode2();break;
			case 2:Mode3();break;
			case 3:Mode4();break;
			//defualt:Mode4();break;
		}

  }
		/* USER CODE END 3 */
}	

3.3 功能模式子函数

/* USER CODE BEGIN 4 */
void Mode1(void)		//单红灯500ms闪烁
{
	if(LED_Delay++>=50)
	{
		LED_Delay =0;
		HAL_GPIO_TogglePin(GPIOB,GPIO_PIN_5);
	}
	HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);
}
void Mode2(void)		//单蓝灯500ms闪烁
{
	if(LED_Delay++>=50)
	{
		LED_Delay =0;
		HAL_GPIO_TogglePin(GPIOE,GPIO_PIN_5);
	}
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
}
void Mode3(void)		//红蓝交替闪烁
{
		switch(LED_Step )
		{
			case 0:	LED_Step++;
				LED_Delay =0;
				HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);    //亮
				HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);        //灭
				break;
			case 1:	if(LED_Delay++>=15)
				{
					LED_Step++;
					LED_Delay =0;
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);   //灭
					HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);   //灭
				}
				break;
			case 2:	if(LED_Delay++>=15)
				{
					LED_Step++;
					LED_Delay =0;
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_RESET);   //亮
					HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);   //灭
				}
				break;
			case 3:	if(LED_Delay++>=15)
				{
					LED_Step++;
					LED_Delay =0;
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);   //灭
					HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);   //灭
				}
				break;
			case 4:	if(LED_Delay++>=80)
				{
					LED_Step++;
					LED_Delay =0;
					HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);   //蓝亮
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);   //红灭
				}
				break;
			case 5:	if(LED_Delay++>=15)
				{
					LED_Step++;
					LED_Delay =0;
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);   //灭
					HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);   //灭
				}
				break;
			case 6:	if(LED_Delay++>=15)
				{
					LED_Step++;
					LED_Delay =0;
					HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_RESET);   //蓝亮
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);   //红灭
				}
				break;
			case 7:	if(LED_Delay++>=15)
				{
					LED_Step++;
					LED_Delay =0;
					HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);   //灭
					HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);   //灭
				}
				break;
			case 8:	if(LED_Delay++>=80)
				{
					LED_Step =0;
					LED_Delay =0;
				}
				break;		
		}
}
void Mode4(void)		//全灯熄灭
{
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_5,GPIO_PIN_SET);
	HAL_GPIO_WritePin(GPIOE,GPIO_PIN_5,GPIO_PIN_SET);
}
/* USER CODE END 4 */

总结

  这里只是设计了一个简单版的“红蓝警示灯”。感兴趣的可以尝试的通过增加一些变量设计一个可编程版本的“红蓝警示灯”。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值