软件: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种模式;
- 红色LED以500ms慢闪,蓝色LED熄灭;
- 红色熄灭,蓝色LED以500ms慢闪;
- 先红色LED以150ms连续闪烁两次,然后全部熄灭800ms后蓝色LED以150ms连续闪烁两次,
然后全部熄灭800ms再回到红色LED闪烁; - 全部熄灭。(有时间的可以在此模式加入休眠程序用按键唤醒,以降低待机功耗。)
二、程序流程思维导图
三、编写用户程序代码
新建项目请参考我之前写的一篇博文。
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 */
总结
这里只是设计了一个简单版的“红蓝警示灯”。感兴趣的可以尝试的通过增加一些变量设计一个可编程版本的“红蓝警示灯”。