Files
DTU-LCD/Users/main.c

171 lines
7.3 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/******************************************************************************
* @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"
/* ============================================================================
* 全局变量定义
* ============================================================================ */
volatile static uint32_t sysRunTime = 0; /**< 系统运行时间计数器单位5ms */
volatile static KEY_TYPE keyStatus = KEY_NONE; /**< 按键状态指示(当前按键值) */
volatile static KEY_TYPE keyStatusBack = KEY_NONE; /**< 按键状态指示(当前按键值) */
volatile static uint8_t LED_ToggleFlag = 0; /**< LED 闪烁定时标志位1=需要翻转) */
/* ============================================================================
* 内部函数实现
* ============================================================================ */
/**
* @brief 按键业务逻辑回调函数
* @param key_type 按键类型KEY_TYPE 枚举值)
* @note 当检测到按键事件时,由按键驱动层调用此函数
* 处理流程:
* 1. 打开背光(任意按键按下都打开背光)
* 2. 显示按键按下指示KeyRun_Disp
* 3. 重置按键显示计时器
* 4. 更新按键状态(供主循环使用)
* @retval 无
*/
static void Key_ProcessCallback(KEY_TYPE key_type)
{
BackLight_ON(); /**< 任意按键按下,都打开背光 */
keyStatus = key_type; /**< 更新按键状态,供主循环处理 */
}
/* ============================================================================
* 主程序入口
* ============================================================================ */
/**
* @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 通信任务初始化 */
/* ========== 定时器与回调注册 ========== */
gtim_timx_int_init(50-1, 7200-1); /**< 定时器初始化5ms 周期50×0.1ms7200 分频) */
Key_RegisterCallback(Key_ProcessCallback); /**< 注册按键回调函数 */
/* ========== 主循环 ========== */
while (1)
{
if (LED_ToggleFlag == 1)
{
LED_ToggleFlag = 0; /**< 清除闪烁标志 */
// LED_Toggle(15); /**< 翻转运行指示灯 */
}
/* 快速的处理 keyStatus 的状态,避免与中断处理冲突*/
if(keyStatus != KEY_NONE)
{
keyStatusBack = keyStatus;
keyStatus = KEY_NONE;
}
/* RS485 Modbus 通信处理(包含按键上报) */
RS485_Process(keyStatusBack);
keyStatusBack = 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)
{
sysRunTime++; /**< 系统运行时间计数递增 */
/* LED 闪烁标志更新:每 200 次中断1 秒)翻转一次 */
if (sysRunTime % 200 == 0)
{
LED_ToggleFlag = 1; /**< 设置 LED 闪烁标志 */
}
Button_Ticks(); /**< 按键检测扫描MultiButton 库) */
Clear_Watchdog(); /**< 看门狗喂狗 */
BackLight_Close(); /**< 背光关闭检测 */
Process_Count(); /**< Modbus 通信轮询计数 */
__HAL_TIM_CLEAR_IT(&g_timx_handle, TIM_IT_UPDATE); /**< 清除定时器溢出中断标志 */
}
}