本文共 3745 字,大约阅读时间需要 12 分钟。
本项目采用状态机控制方法,通过不同的状态实现功能切换与数据处理。系统主要包含以下状态:
状态0:待机状态
当系统未被激活时,显示“Standby”信息,所有功能均为禁用状态。状态1-3:设置状态
根据不同按键操作(如短按1-3),分别设置时、分、秒的值。每次设置时,系统会自动滚动(如时分秒超过最大值后,会循环回0)。状态4:运行状态
系统开始计时并显示倒计时信息。LED灯会以0.5秒频率闪烁,提示系统运行状态。状态5:暂停状态
当长按键4时,系统暂停当前计时功能,LED灯停止闪烁,所有计时数据保留。系统通过按键操作控制状态切换及功能设置。具体按键功能如下:
倒计时功能基于系统时间和PWM定时器实现,总计时长为3600秒(1小时)。具体实现如下:
count = 3600 * time[0] + 60 * time[1] + time[2];if (uwTick - uwTick_run >= 1000) { uwTick_run = uwTick; count--;}HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1); // 启动PWMtime[0] = count / 3600; // 时time[1] = count % 3600 / 60; // 分time[2] = count % 3600 % 60; // 秒
LCD屏幕用于显示当前状态及计时信息。具体显示内容如下:
显示内容分为四行,第一行显示“No X”(X为存储位置),后三行分别显示时、分、秒的值。
系统支持对某一部分信息进行高亮显示,具体实现如下:
if (state == 1) { LCD_SetBackColor(Green); // 设置高亮显示} else { LCD_SetBackColor(White); // 恢复默认颜色}LCD_DisplayChar(Line4, 320 - (16 * 6), (time[0] / 10) + 0x30); // 显示小时部分LCD_DisplayChar(Line4, 320 - (16 * 7), (time[0] % 10) + 0x30); // 显示分钟部分LCD_SetBackColor(White); // 恢复默认颜色
LED灯用于提示系统运行状态,具体控制逻辑如下:
if (state == 4) { ucLed ^= 0x01; // 0.5秒翻转}LED_Disp(ucLed); // 显示LED状态
按键扫描功能用于检测按键状态变化,具体实现如下:
void Key_Proc(void) { if ((uwTick - uwTick_Key_Set_Point) < 50) return; // 减速函数 uwTick_Key_Set_Point = uwTick; ucKey_Val = Key_Scan(); unKey_Down = ucKey_Val & (ucKey_Old ^ ucKey_Val); // 下降沿为按键值 ucKey_Up = ~ucKey_Val & (ucKey_Old ^ ucKey_Val); // 上升沿为按键值 ucKey_Old = ucKey_Val; if (unKey_Down) { uwTick_Set_Point = uwTick; // 启动计时 } if ((uwTick - uwTick_Set_Point) < 800) { // 短按 switch (ucKey_Up) { // 判断按键值 case 1: // 短按1 break; case 2: // 短按2 break; case 3: // 短按3 break; case 4: // 短按4 break; } } else { // 长按 switch (ucKey_Val) { // 判断按键值 case 2: // 长按2 break; case 3: // 长按3 break; case 4: // 长按4 break; } }}
系统主程序负责初始化硬件并启动各子程序,主函数如下:
int main(void) { HAL_Init(); // 初始化微控制器 SystemClock_Config(); // 配置系统时钟 KEY_LED_Init(); // 初始化按键和LED LCD_Init(); // 初始化LCD LCD_Clear(White); // 初始化显示屏 LCD_SetBackColor(White); // 设置背景颜色 LCD_SetTextColor(Blue); // 设置显示颜色 UART1_Init(); // 初始化UART I2CInit(); // 初始化I2C PWM_OUTPUT_TIM3_Init(); // 初始化PWM输出 while (1) { Key_Proc(); // 处理按键 Led_Proc(); // 处理LED Lcd_Proc(); // 处理LCD }}
系统支持5个存储位置(1-5),每个位置存储3个字节的数据。存储逻辑如下:
iic_24c02_write(time, 3 * (num - 1), 3); // 存储位置由num决定
系统状态转移通过按键操作实现,具体逻辑如下:
void Key_Proc(void) { // ... if (unKey_Down) { uwTick_Set_Point = uwTick; // 启动计时 } if ((uwTick - uwTick_Set_Point) < 800) { // 短按 switch (ucKey_Up) { case 1: // 短按1 break; case 2: // 短按2 break; case 3: // 短按3 break; case 4: // 短按4 break; } } else { // 长按 switch (ucKey_Val) { case 2: // 长按2 break; case 3: // 长按3 break; case 4: // 长按4 break; } }}
系统提供错误处理功能,具体实现如下:
void Error_Handler(void) { __disable_irq(); // 禁用中断 while (1) { // 可以添加自定义错误处理逻辑 }}
本项目通过状态机控制和多任务处理实现了一个功能丰富的计时系统。系统支持短按和长按操作,能够在不同的存储位置中存储和显示计时数据。LCD屏幕提供清晰的用户界面,LED灯用于提示系统运行状态。通过优化代码和硬件配置,确保了系统的高效性和可靠性。
转载地址:http://mygfk.baihongyu.com/