1.添加了必要的注释和readme文件以提高代码可读性和项目文档化。2.增加了按键按下时LCD屏幕显示功能

This commit is contained in:
2026-01-25 15:42:48 +08:00
parent 373b31adfd
commit 6a861cee4e
30 changed files with 2311 additions and 50645 deletions

View File

@@ -1,95 +1,203 @@
/**
******************************************************************************
* @文件 main.c
* @作者 阜阳师范大学物电学院
* @版本 V0.1
* @日期 2026-01-15
* @简介 DTU 屏幕按键部分的驱动程序
******************************************************************************
**/
/******************************************************************************
* @file main.c
* @brief DTU 主程序 - 屏幕与按键控制
* @details 本文件实现了 DTU 设备的主程序逻辑,包括:
* - 系统初始化(时钟、外设、看门狗等)
* - 按键事件处理与业务逻辑
* - RS485 Modbus 通信处理
* - 定时器中断服务5ms 周期)
* - 系统运行指示灯控制
* - 看门狗喂狗与系统复位保护
* @author 阜阳师范大学物电学院
* @version V0.1
* @date 2026.1.19
* @note 定时器周期5ms
* 系统复位时间:约 5000 秒1000000 × 5ms
* 通信协议Modbus RTU over RS485
******************************************************************************/
#include "main.h"
#define TIMER 5 /* 定时器定时时间 */
#define LED_TOGGLE_TIME 1000 /* 系统运行指示灯闪烁时间,也就是亮的时间*/
/* ============================================================================
* 宏定义
* ============================================================================ */
#define TIMER 5 /**< 定时器周期(毫秒) */
#define LED_TOGGLE_TIME 1000 /**< 系统运行指示灯闪烁周期(毫秒),即 LED 点亮持续时间 */
volatile static uint32_t sysRunTime = 0; /* 系统运行时间计数器 */
volatile static uint8_t LED_ToggleFlag = 0; /* LED闪烁定时标志位 */
static KEY_TYPE keyStatus = KEY_NONE; /* 按键状态指示 */
static uint8_t ConnectFlg = 0; /**< 连接标志0x01=已连接0x00=未连接 */
/* ============================================================================
* 全局变量定义
* ============================================================================ */
volatile static uint32_t sysRunTime = 0; /**< 系统运行时间计数器单位5ms */
volatile static uint8_t LED_ToggleFlag = 0; /**< LED 闪烁定时标志位1=需要翻转) */
static KEY_TYPE keyStatus = KEY_NONE; /**< 按键状态指示(当前按键值) */
static uint8_t ConnectFlg = 0; /**< 连接标志1=已连接0=未连接 */
volatile static uint32_t KEY_RUN_Count = 0; /**< 按键按下时 LCD 屏幕显示计时计数器单位5ms */
/* ============================================================================
* 内部函数实现
* ============================================================================ */
/**
* @brief 按键业务逻辑回调函数
* @param key_type 按键类型
* @brief 按键业务逻辑回调函数
* @param key_type 按键类型KEY_TYPE 枚举值)
* @note 当检测到按键事件时,由按键驱动层调用此函数
* 处理流程:
* 1. 打开背光(任意按键按下都打开背光)
* 2. 显示按键按下指示KeyRun_Disp
* 3. 重置按键显示计时器
* 4. 更新按键状态(供主循环使用)
* @retval 无
*/
static void Key_ProcessCallback(KEY_TYPE key_type)
{
// IntValue_Printf(2, 32, key_type, RESET);
BackLight_ON(); /* 任意按键按下,都打开背光 */
keyStatus = key_type; /* 更新按键状态 */
}
int main(void)
{
HAL_Init(); /* 初始化HAL库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /* 设置时钟, 72Mhz */
delay_init(72); /* 延时初始化 */
LED_Init(); /* LED灯初始化 */
Key_Init(); /* 初始化按键驱动 */
WDog_Init(); /* 看门狗初始化 */
RS485_DMA_init(); /* Rs485初始化 */
LcdInit();
Process_Init(); /* 通信任务初始化 */
NL_LOGO_Printf(); /* 显示存储的LOGO */
gtim_timx_int_init(50-1, 7200-1); /* 定时5毫秒 */
// 注册按键业务逻辑回调函数
Key_RegisterCallback(Key_ProcessCallback); /* 注册按键回调函数 */
while(1)
{
if(ConnectFlg == 1)
{
/* 指示灯闪烁 */
if(LED_ToggleFlag == 1)
{
LED_ToggleFlag = 0;
LED_Toggle(LED_RUN);
}
}
ConnectFlg = RS485_Process(keyStatus, ConnectFlg);
keyStatus = KEY_NONE;
/*系统运行超过一定时间立即复位重启*/
if(sysRunTime > 1000000)
{
HAL_NVIC_SystemReset(); /* 系统立即复位 */
sysRunTime = 0;
}
}
BackLight_ON(); /**< 任意按键按下,都打开背光 */
KeyRun_Disp(1); /**< 有按键按下LCD 显示按键指示 */
KEY_RUN_Count = 0; /**< 重置按键显示计时器 */
keyStatus = key_type; /**< 更新按键状态,供主循环处理 */
}
/**
* @brief 定时器中断服务函数
* @param 无
* @retval 无
* @brief 按键显示自动关闭处理
* @note 在定时器中断中调用,用于自动关闭按键按下后的 LCD 显示指示
* 处理逻辑:
* - KEY_RUN_Count 递增(每 5ms 一次)
* - 当计数达到 15约 75ms关闭按键显示
* - 计数限制在 15防止溢出
* @retval 无
*/
void KeyRun_Disp_Close(void)
{
KEY_RUN_Count++;
if (KEY_RUN_Count >= 15)
{
KEY_RUN_Count = 15; /**< 限制最大计数,防止溢出 */
KeyRun_Disp(0); /**< 关闭按键显示指示 */
}
}
/* ============================================================================
* 主程序入口
* ============================================================================ */
/**
* @brief 主函数
* @note 系统初始化流程:
* 1. HAL 库初始化
* 2. 系统时钟配置72MHz
* 3. 延时函数初始化
* 4. LED 初始化
* 5. 按键驱动初始化
* 6. 看门狗初始化
* 7. RS485 通信初始化
* 8. LCD 初始化
* 9. Modbus 通信任务初始化
* 10. 显示存储的 LOGO
* 11. 定时器初始化5ms 周期)
* 12. 注册按键回调函数
*
* 主循环处理:
* - 连接状态下的 LED 指示灯闪烁
* - RS485 Modbus 通信处理(包含按键上报)
* - 系统运行时间监控与自动复位保护
*
* 定时器中断5ms处理
* - 系统运行时间计数
* - LED 闪烁标志更新
* - 按键检测扫描
* - 看门狗喂狗
* - 背光关闭检测
* - Modbus 轮询计数
* - 按键显示自动关闭
* @retval 无(永不返回)
*/
int main(void)
{
/* ========== 系统初始化 ========== */
HAL_Init(); /**< 初始化 HAL 库 */
sys_stm32_clock_init(RCC_PLL_MUL9); /**< 设置系统时钟72MHz */
delay_init(72); /**< 延时函数初始化(基于 72MHz 时钟) */
/* ========== 外设初始化 ========== */
LED_Init(); /**< LED 灯初始化 */
Key_Init(); /**< 初始化按键驱动 */
WDog_Init(); /**< 看门狗初始化 */
RS485_DMA_init(); /**< RS485 初始化DMA 方式) */
LcdInit(); /**< LCD 初始化 */
/* ========== 通信与显示初始化 ========== */
Process_Init(); /**< Modbus 通信任务初始化 */
NL_LOGO_Printf(); /**< 显示存储的 LOGO从 Flash 读取) */
/* ========== 定时器与回调注册 ========== */
gtim_timx_int_init(50-1, 7200-1); /**< 定时器初始化5ms 周期50×0.1ms7200 分频) */
Key_RegisterCallback(Key_ProcessCallback); /**< 注册按键回调函数 */
/* ========== 主循环 ========== */
while (1)
{
/* LED 指示灯闪烁控制(仅在已连接状态下闪烁) */
if (ConnectFlg == 1)
{
if (LED_ToggleFlag == 1)
{
LED_ToggleFlag = 0; /**< 清除闪烁标志 */
LED_Toggle(LED_RUN); /**< 翻转运行指示灯 */
}
}
/* RS485 Modbus 通信处理(包含按键上报) */
ConnectFlg = RS485_Process(keyStatus, ConnectFlg);
keyStatus = KEY_NONE; /**< 清除按键状态(已处理) */
/* 系统运行时间监控与自动复位保护 */
if (sysRunTime > 1000000) /**< 约 5000 秒1000000 × 5ms */
{
HAL_NVIC_SystemReset(); /**< 系统立即复位(防止长时间运行异常) */
sysRunTime = 0;
}
}
}
/* ============================================================================
* 中断服务函数
* ============================================================================ */
/**
* @brief 定时器中断服务函数5ms 周期)
* @note 在定时器溢出中断中执行以下任务:
* 1. 系统运行时间计数sysRunTime++
* 2. LED 闪烁标志更新(每 200 次中断,即 1 秒)
* 3. 按键检测扫描Button_Ticks
* 4. 看门狗喂狗Clear_Watchdog
* 5. 背光关闭检测BackLight_Close
* 6. Modbus 轮询计数Process_Count
* 7. 按键显示自动关闭KeyRun_Disp_Close
*
* 定时器配置5ms 周期
* 中断标志TIM_FLAG_UPDATE定时器溢出标志
* @retval 无
*/
void GTIM_TIMX_INT_IRQHandler(void)
{
/*直接通过判断中断标志位来处理中断 */
if(__HAL_TIM_GET_FLAG(&g_timx_handle, TIM_FLAG_UPDATE) != RESET)
/* 判断定时器溢出中断标志位 */
if (__HAL_TIM_GET_FLAG(&g_timx_handle, TIM_FLAG_UPDATE) != RESET)
{
sysRunTime++;
if(sysRunTime % (LED_TOGGLE_TIME / 5) == 0)
sysRunTime++; /**< 系统运行时间计数递增 */
/* LED 闪烁标志更新:每 200 次中断1 秒)翻转一次 */
if (sysRunTime % (LED_TOGGLE_TIME / 5) == 0)
{
LED_ToggleFlag = 1;
LED_ToggleFlag = 1; /**< 设置 LED 闪烁标志 */
}
Button_Ticks(); /* 按键检测 */
Clear_Watchdog(); /* 看门狗喂狗 */
BackLight_Close(); /* 背光关闭检测 */
Process_Count(); /* 通信任务处理计数器 */
Button_Ticks(); /**< 按键检测扫描MultiButton 库) */
Clear_Watchdog(); /**< 看门狗喂狗 */
BackLight_Close(); /**< 背光关闭检测 */
Process_Count(); /**< Modbus 通信轮询计数 */
KeyRun_Disp_Close(); /**< LCD 屏幕按键指示自动关闭处理 */
__HAL_TIM_CLEAR_IT(&g_timx_handle, TIM_IT_UPDATE); /**< 清除定时器溢出中断标志 */
}
__HAL_TIM_CLEAR_IT(&g_timx_handle, TIM_IT_UPDATE); /* 清楚定时器溢出中断 */
}