3.27_433:实验并验证485发送数据透传至RF433模块,并在外部设备成功接收

- 新增协议识别器状态机,实现指令与透传数据的自动识别
This commit is contained in:
2026-03-27 19:58:20 +08:00
parent 268667e335
commit 0eea5c1424
71 changed files with 6051 additions and 2620 deletions

View File

@ -11,7 +11,7 @@
* 1. 最小切换间隔保护,防止频繁切换损坏继电器
* 2. 状态记录
* 3. 调试日志输出
*
*
* 修订历史:
* v2.0 - 精简为单路继电器控制,移除冗余功能
******************************************************************************
@ -21,49 +21,163 @@
#include "uart2_print.h"
#include "main.h"
/*==============================================================================
* 调试宏定义
*============================================================================*/
/* DEBUG_RELAY: 调试日志开关置1时启用继电器控制过程日志输出 */
#define DEBUG_RELAY 1
#if DEBUG_RELAY
/* 调试日志宏,带模块前缀"[RELAY]"方便过滤日志 */
#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[RELAY] " fmt "\r\n", ##__VA_ARGS__)
#else
#define DEBUG_LOG(fmt, ...)
#endif
/*==============================================================================
* 全局变量定义
*============================================================================*/
/**
* @brief 继电器当前状态
* @note 记录继电器的开关状态
*
* 状态含义:
* - false: 继电器处于断开状态(OFF)
* - true: 继电器处于闭合状态(ON)
*
* 初始化说明:
* 初始化为false表示系统上电后继电器默认断开
*/
static bool current_state = false;
/**
* @brief 上一次切换操作的时间戳
* @note 用于实现继电器最小切换间隔保护
*
* 设计目的:
* 继电器是机械开关,频繁切换会缩短其使用寿命。
* 通过记录上次切换时间,可以强制两次切换之间必须间隔
* 最小时间(RELAY_MIN_INTERVAL),防止频繁操作。
*
* 单位说明:
* 毫秒(ms)与HAL_GetTick()返回值单位一致
*/
static uint32_t last_toggle_tick = 0;
/*==============================================================================
* 公共函数实现
*============================================================================*/
/**
* @brief 继电器模块初始化
* @note 在系统启动时调用,复位继电器到安全初始状态
*
* @param 无
* @return 无
*
* 功能说明:
* 1. 硬件控制引脚设置为低电平,强制确保继电器断开
* 2. 重置状态变量为false
* 3. 重置切换时间戳为0
*
* 初始化安全:
* - 此函数应尽早调用,确保系统启动时继电器处于受控状态
* - 继电器初始状态设为OFF是考虑到故障安全(fail-safe)设计
*/
void Relay_Init(void)
{
/*----------------------------------------------------------
* 硬件层面:将继电器控制引脚设置为低电平
* RL_Control_GPIO_Port和RL_Control_Pin定义在main.h或引脚配置中
*----------------------------------------------------------*/
HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin, GPIO_PIN_RESET);
/*----------------------------------------------------------
* 软件层面初始化继电器状态为OFF
*----------------------------------------------------------*/
current_state = false;
/*----------------------------------------------------------
* 重置切换保护相关计时器
*----------------------------------------------------------*/
last_toggle_tick = 0;
DEBUG_LOG("Init OK, state=OFF");
}
/**
* @brief 设置继电器状态
* @note 核心控制函数,实现继电器开关操作及保护逻辑
*
* @param state: 目标状态false=关闭(OFF)true=打开(ON)(输入)
* @return 无
*
* 功能说明:
* 1. 切换间隔保护检查(防频繁操作)
* 2. 状态变更判断(避免重复操作)
* 3. 硬件GPIO操作
* 4. 状态记录和统计更新
*
* 算法说明 - 切换间隔保护:
* if (current_tick - last_toggle_tick < RELAY_MIN_INTERVAL)
* return; // 切换过于频繁,直接丢弃
*
* 这个检查确保两次继电器操作之间至少间隔RELAY_MIN_INTERVAL毫秒
* 防止程序错误或通信干扰导致继电器被频繁开关。
*
* 注意/异常:
* - 切换间隔太短时静默忽略,防抖处理
* - 状态与当前相同时静默忽略,不重复操作
*/
void Relay_SetState(bool state)
{
/*----------------------------------------------------------
* 获取当前时间,判断与上次操作的时间间隔
*----------------------------------------------------------*/
uint32_t current_tick = HAL_GetTick();
/*----------------------------------------------------------
* 切换间隔保护检查
*----------------------------------------------------------*/
if (current_tick - last_toggle_tick < RELAY_MIN_INTERVAL) {
DEBUG_LOG("Toggle too fast, ignored");
return;
}
/*----------------------------------------------------------
* 状态变更判断:避免重复设置相同状态
*----------------------------------------------------------*/
if (current_state == state) {
DEBUG_LOG("State unchanged: %s", state ? "ON" : "OFF");
return;
}
HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin,
/*----------------------------------------------------------
* 硬件控制设置GPIO引脚电平
*----------------------------------------------------------*/
HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin,
state ? GPIO_PIN_SET : GPIO_PIN_RESET);
/*----------------------------------------------------------
* 更新软状态和记录切换时间
*----------------------------------------------------------*/
current_state = state;
last_toggle_tick = current_tick;
DEBUG_LOG("Relay -> %s", state ? "ON" : "OFF");
}
/**
* @brief 获取继电器当前状态
* @note 返回继电器的开关状态
*
* @param 无
* @return bool: 继电器状态false=关闭(OFF)true=打开(ON)
*
* 使用示例:
* if (Relay_GetState()) {
* // 继电器当前处于闭合状态
* }
*/
bool Relay_GetState(void)
{
return current_state;