3.27_433:添加UART2调试打印、IO监控、指令解析和继电器控制模块。
能够接收UART2指令控制继电器开关,或向UART2发送四路IO输入状态,并使用轮询方式检测IO状态进行及时反馈。
This commit is contained in:
109
Core/Inc/cmd_parser.h
Normal file
109
Core/Inc/cmd_parser.h
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file cmd_parser.h
|
||||||
|
* @brief ASCII指令解析模块头文件
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.0
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块实现ASCII文本指令的解析和处理
|
||||||
|
* 指令格式: $CMD,param1,param2*CS\r\n
|
||||||
|
* 支持异或校验,FF为调试特权后门
|
||||||
|
* 包含完善的安全防护机制
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __CMD_PARSER_H
|
||||||
|
#define __CMD_PARSER_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define CMD_MAX_LEN 8
|
||||||
|
#define PARAM_MAX_LEN 32
|
||||||
|
#define PARSE_TIMEOUT_MS 1000
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
CMD_CODE_UNKNOWN = 0,
|
||||||
|
CMD_CODE_RL = 1,
|
||||||
|
CMD_CODE_DI = 2,
|
||||||
|
CMD_CODE_ECHO = 3,
|
||||||
|
CMD_CODE_FWD = 4
|
||||||
|
} cmd_code_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char cmd[CMD_MAX_LEN];
|
||||||
|
char param1[PARAM_MAX_LEN];
|
||||||
|
char param2[PARAM_MAX_LEN];
|
||||||
|
uint8_t received_cs;
|
||||||
|
uint8_t calculated_cs;
|
||||||
|
bool valid;
|
||||||
|
bool skip_checksum;
|
||||||
|
} cmd_frame_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化指令解析模块
|
||||||
|
* @note 重置解析状态机,清空缓冲区
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void CmdParser_Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 指令解析任务处理函数
|
||||||
|
* @note 在主循环中调用,处理已接收的完整指令帧
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void CmdParser_Task(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 喂入单字节数据到解析器
|
||||||
|
* @note 通常在UART接收中断中调用
|
||||||
|
* @param byte: 接收到的字节数据
|
||||||
|
* @param current_tick: 当前系统tick(用于超时检测)
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void CmdParser_FeedByte(uint8_t byte, uint32_t current_tick);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查是否有完整的指令帧
|
||||||
|
* @note 用于查询解析状态
|
||||||
|
* @param frame: 输出参数,存储解析结果
|
||||||
|
* @retval true: 有完整帧, false: 无
|
||||||
|
*/
|
||||||
|
bool CmdParser_HasCompleteFrame(cmd_frame_t *frame);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 确认指令已处理
|
||||||
|
* @note 处理完指令后调用,重置解析器
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void CmdParser_Acknowledge(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取解析错误计数
|
||||||
|
* @note 用于调试和诊断
|
||||||
|
* @param 无
|
||||||
|
* @retval 错误计数
|
||||||
|
*/
|
||||||
|
uint32_t CmdParser_GetErrorCount(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取接收到的有效指令计数
|
||||||
|
* @note 用于调试和诊断
|
||||||
|
* @param 无
|
||||||
|
* @retval 有效指令计数
|
||||||
|
*/
|
||||||
|
uint32_t CmdParser_GetValidCount(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
82
Core/Inc/io_monitor.h
Normal file
82
Core/Inc/io_monitor.h
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file io_monitor.h
|
||||||
|
* @brief IO状态监控模块头文件
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.0
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块实现四路数字输入(DI1-DI4)的状态监控
|
||||||
|
* 采用定时扫描+软件去抖方式检测IO状态变化
|
||||||
|
* 状态变化时通过UART2_Print上报
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __IO_MONITOR_H
|
||||||
|
#define __IO_MONITOR_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define IO_CHANNEL_COUNT 4
|
||||||
|
#define IO_SCAN_PERIOD_MS 10
|
||||||
|
#define IO_DEBOUNCE_COUNT 3
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化IO监控模块
|
||||||
|
* @note 初始化各通道状态,读取初始IO电平
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void IO_Monitor_Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief IO监控任务处理函数
|
||||||
|
* @note 在主循环中调用,每10ms扫描一次IO状态
|
||||||
|
* 检测到状态变化时自动上报
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void IO_Monitor_Task(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取指定通道的IO状态
|
||||||
|
* @note 返回经过去抖处理后的稳定状态
|
||||||
|
* @param channel: 通道号(0-3对应DI1-DI4)
|
||||||
|
* @retval 0: LOW, 1: HIGH
|
||||||
|
*/
|
||||||
|
uint8_t IO_Monitor_GetState(uint8_t channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取所有IO通道状态
|
||||||
|
* @note 返回4位状态值,每位对应一个通道
|
||||||
|
* @param 无
|
||||||
|
* @retval 状态值 (bit0=DI1, bit1=DI2, bit2=DI3, bit3=DI4)
|
||||||
|
*/
|
||||||
|
uint8_t IO_Monitor_GetAllStates(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 启用/禁用IO状态变化上报
|
||||||
|
* @note 禁用后状态变化不会触发上报,但状态仍会更新
|
||||||
|
* @param enable: true=启用, false=禁用
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void IO_Monitor_EnableReport(bool enable);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取IO状态变化次数统计
|
||||||
|
* @note 用于调试和诊断
|
||||||
|
* @param channel: 通道号(0-3)
|
||||||
|
* @retval 该通道的状态变化次数
|
||||||
|
*/
|
||||||
|
uint32_t IO_Monitor_GetChangeCount(uint8_t channel);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
117
Core/Inc/protocol.h
Normal file
117
Core/Inc/protocol.h
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
* @file protocol.h
|
||||||
|
* @brief 简化的ASCII文本指令协议
|
||||||
|
*
|
||||||
|
* 协议格式: $SN,CMD,param1,param2*CS\r\n
|
||||||
|
* - SN: 序列号(0-255),用于防丢包和重复
|
||||||
|
* - CMD: 指令名称
|
||||||
|
* - CS: CRC8校验(从$到*之间所有字符的CRC8值)
|
||||||
|
*
|
||||||
|
* 抗干扰/防丢失机制:
|
||||||
|
* 1. CRC8校验 - 比XOR更强的检错能力
|
||||||
|
* 2. 序列号 - 接收方可检测丢包和重复
|
||||||
|
* 3. 应答机制 - 重要指令需要确认
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __PROTOCOL_H
|
||||||
|
#define __PROTOCOL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 协议配置 */
|
||||||
|
#define PROTOCOL_MAX_CMD_LEN 8
|
||||||
|
#define PROTOCOL_MAX_PARAM_LEN 32
|
||||||
|
#define PROTOCOL_MAX_PARAMS 4
|
||||||
|
#define PROTOCOL_FRAME_TIMEOUT 1000 /* 帧超时/ms */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t sn; /* 序列号 */
|
||||||
|
char cmd[PROTOCOL_MAX_CMD_LEN]; /* 指令名 */
|
||||||
|
char params[PROTOCOL_MAX_PARAMS][PROTOCOL_MAX_PARAM_LEN];
|
||||||
|
uint8_t param_count; /* 参数数量 */
|
||||||
|
uint8_t checksum; /* CRC8校验和 */
|
||||||
|
bool valid; /* 解析是否成功 */
|
||||||
|
} protocol_frame_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROTOCOL_OK = 0,
|
||||||
|
PROTOCOL_ERROR_INVALID_FRAME,
|
||||||
|
PROTOCOL_ERROR_CHECKSUM_FAIL,
|
||||||
|
PROTOCOL_ERROR_TIMEOUT,
|
||||||
|
PROTOCOL_ERROR_UNKNOWN_CMD,
|
||||||
|
PROTOCOL_ERROR_PARAM_COUNT,
|
||||||
|
PROTOCOL_ERROR_BUFFER_FULL
|
||||||
|
} protocol_error_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PROTOCOL_CMD_RL, /* 继电器控制: RL,id,ON/OFF */
|
||||||
|
PROTOCOL_CMD_DI, /* 查询IO: DI,id */
|
||||||
|
PROTOCOL_CMD_DIA, /* 查询所有IO: DIA */
|
||||||
|
PROTOCOL_CMD_FWD, /* 数据转发: FWD,port,data */
|
||||||
|
PROTOCOL_CMD_ECHO, /* 心跳: ECHO */
|
||||||
|
PROTOCOL_CMD_ACK, /* 应答: ACK,sn,result */
|
||||||
|
PROTOCOL_CMD_STATUS, /* 状态查询: STATUS */
|
||||||
|
PROTOCOL_CMD_UNKNOWN
|
||||||
|
} protocol_cmd_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
protocol_cmd_t cmd;
|
||||||
|
uint8_t sn;
|
||||||
|
bool need_ack; /* 是否需要应答 */
|
||||||
|
uint32_t send_time; /* 发送时间 */
|
||||||
|
uint8_t retry_count; /* 重试次数 */
|
||||||
|
} protocol_pending_t;
|
||||||
|
|
||||||
|
#define PROTOCOL_MAX_PENDING 4
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
protocol_pending_t pending[PROTOCOL_MAX_PENDING];
|
||||||
|
uint8_t pending_count;
|
||||||
|
uint8_t next_sn;
|
||||||
|
uint8_t last_rx_sn;
|
||||||
|
} protocol_context_t;
|
||||||
|
|
||||||
|
/* 协议初始化 */
|
||||||
|
void protocol_init(void);
|
||||||
|
|
||||||
|
/* 解析收到的指令 */
|
||||||
|
protocol_error_t protocol_parse(const char *data, uint16_t length, protocol_frame_t *frame);
|
||||||
|
|
||||||
|
/* 构造发送帧 */
|
||||||
|
protocol_error_t protocol_build(char *buffer, uint16_t buffer_size, uint16_t *out_length,
|
||||||
|
protocol_cmd_t cmd, uint8_t sn,
|
||||||
|
const char *params[], uint8_t param_count);
|
||||||
|
|
||||||
|
/* 构造应答帧 */
|
||||||
|
protocol_error_t protocol_build_ack(char *buffer, uint16_t buffer_size, uint16_t *out_length,
|
||||||
|
uint8_t sn, bool success, const char *msg);
|
||||||
|
|
||||||
|
/* 发送命令并等待应答 */
|
||||||
|
protocol_error_t protocol_send_with_ack(protocol_cmd_t cmd, const char *params[], uint8_t param_count,
|
||||||
|
uint32_t timeout_ms, uint8_t max_retries);
|
||||||
|
|
||||||
|
/* 协议任务处理(处理超时和重试) */
|
||||||
|
void protocol_task(void);
|
||||||
|
|
||||||
|
/* CRC8计算 */
|
||||||
|
uint8_t protocol_crc8(const uint8_t *data, uint16_t length);
|
||||||
|
|
||||||
|
/* 指令名转枚举 */
|
||||||
|
protocol_cmd_t protocol_cmd_from_string(const char *cmd_str);
|
||||||
|
|
||||||
|
/* 枚举转指令名 */
|
||||||
|
const char* protocol_cmd_to_string(protocol_cmd_t cmd);
|
||||||
|
|
||||||
|
/* 获取上一个错误 */
|
||||||
|
protocol_error_t protocol_get_last_error(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __PROTOCOL_H */
|
||||||
72
Core/Inc/relay_control.h
Normal file
72
Core/Inc/relay_control.h
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file relay_control.h
|
||||||
|
* @brief 继电器控制模块头文件
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.0
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块提供继电器的安全控制接口
|
||||||
|
* 当前硬件配置:PA15连接继电器控制端
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RELAY_CONTROL_H
|
||||||
|
#define __RELAY_CONTROL_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define RELAY_COUNT 1
|
||||||
|
#define RELAY_MIN_INTERVAL 100
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化继电器控制模块
|
||||||
|
* @note 将继电器初始状态设为关闭
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void Relay_Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 设置继电器状态
|
||||||
|
* @note 带最小间隔保护,防止频繁切换损坏继电器
|
||||||
|
* @param relay_id: 继电器编号(1-4),当前硬件只有1
|
||||||
|
* @param state: true=打开, false=关闭
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void Relay_SetState(uint8_t relay_id, bool state);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取继电器当前状态
|
||||||
|
* @note 读取GPIO输出状态
|
||||||
|
* @param relay_id: 继电器编号(1-4)
|
||||||
|
* @retval true=打开, false=关闭
|
||||||
|
*/
|
||||||
|
bool Relay_GetState(uint8_t relay_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 翻转继电器状态
|
||||||
|
* @note 带最小间隔保护
|
||||||
|
* @param relay_id: 继电器编号(1-4)
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void Relay_Toggle(uint8_t relay_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取继电器切换次数
|
||||||
|
* @note 用于调试和诊断
|
||||||
|
* @param 无
|
||||||
|
* @retval 切换次数
|
||||||
|
*/
|
||||||
|
uint32_t Relay_GetToggleCount(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
99
Core/Inc/uart2_print.h
Normal file
99
Core/Inc/uart2_print.h
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file uart2_print.h
|
||||||
|
* @brief UART2调试打印模块头文件
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.0
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块提供基于环形缓冲区的非阻塞调试信息输出功能
|
||||||
|
* 支持printf风格的格式化输出
|
||||||
|
* 支持中断安全调用
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __UART2_PRINT_H
|
||||||
|
#define __UART2_PRINT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define UART2_TX_BUFFER_SIZE 256
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 初始化UART2打印模块
|
||||||
|
* @note 清空发送缓冲区,重置状态标志
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void UART2_Print_Init(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 发送原始数据到UART2
|
||||||
|
* @note 数据写入环形缓冲区,非阻塞返回
|
||||||
|
* @param data: 待发送的数据指针
|
||||||
|
* @param len: 数据长度
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void UART2_Print_Send(const uint8_t *data, uint16_t len);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 发送字符串到UART2
|
||||||
|
* @note 自动计算字符串长度
|
||||||
|
* @param str: 待发送的字符串指针
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void UART2_Print_String(const char *str);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 格式化打印到UART2
|
||||||
|
* @note 支持printf风格的格式化输出
|
||||||
|
* @param fmt: 格式化字符串
|
||||||
|
* @param ...: 可变参数
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void UART2_Print_Printf(const char *fmt, ...);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART2打印任务处理函数
|
||||||
|
* @note 在主循环中调用,处理发送缓冲区中的数据
|
||||||
|
* 每次调用发送一个字节(中断方式)
|
||||||
|
* @param 无
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void UART2_Print_Task(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 检查UART2是否正在发送
|
||||||
|
* @note 用于查询当前发送状态
|
||||||
|
* @param 无
|
||||||
|
* @retval true: 正在发送, false: 空闲
|
||||||
|
*/
|
||||||
|
bool UART2_Print_IsBusy(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 获取发送缓冲区剩余空间
|
||||||
|
* @note 用于检测缓冲区是否即将溢出
|
||||||
|
* @param 无
|
||||||
|
* @retval 剩余空间字节数
|
||||||
|
*/
|
||||||
|
uint16_t UART2_Print_Available(void);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART2发送完成中断回调
|
||||||
|
* @note 由HAL库调用,不应由用户直接调用
|
||||||
|
* @param huart: UART句柄指针
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void UART2_Print_TxCpltCallback(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
378
Core/Src/cmd_parser.c
Normal file
378
Core/Src/cmd_parser.c
Normal file
@ -0,0 +1,378 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file cmd_parser.c
|
||||||
|
* @brief ASCII指令解析模块实现
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.1
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块实现ASCII文本指令的解析和处理
|
||||||
|
* 关键特性:
|
||||||
|
* 1. 状态机解析,健壮可靠
|
||||||
|
* 2. 完善的安全防护(缓冲区边界检查、超时重置、字符过滤)
|
||||||
|
* 3. 异或校验,FF特权后门
|
||||||
|
* 4. 支持RL、DI、ECHO指令
|
||||||
|
*
|
||||||
|
* 修订历史:
|
||||||
|
* v1.1 - 修复审查报告高危-6、中危-7/8
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "cmd_parser.h"
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#include "io_monitor.h"
|
||||||
|
#include "relay_control.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <stdio.h> // snprintf
|
||||||
|
#include <stdlib.h> // atoi
|
||||||
|
|
||||||
|
#define DEBUG_CMD_PARSER 1
|
||||||
|
|
||||||
|
#if DEBUG_CMD_PARSER
|
||||||
|
#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[CMD] " fmt "\r\n", ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_LOG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PARSE_IDLE,
|
||||||
|
PARSE_CMD,
|
||||||
|
PARSE_PARAM1,
|
||||||
|
PARSE_PARAM2,
|
||||||
|
PARSE_CHECKSUM,
|
||||||
|
PARSE_COMPLETE
|
||||||
|
} parse_state_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
parse_state_t state;
|
||||||
|
cmd_frame_t frame;
|
||||||
|
uint8_t field_index;
|
||||||
|
uint8_t checksum_acc;
|
||||||
|
uint8_t cs_buffer[2];
|
||||||
|
uint8_t cs_index;
|
||||||
|
uint32_t last_rx_tick;
|
||||||
|
uint32_t error_count;
|
||||||
|
uint32_t valid_count;
|
||||||
|
} parser_context_t;
|
||||||
|
|
||||||
|
static parser_context_t ctx;
|
||||||
|
|
||||||
|
static void reset_parser(void)
|
||||||
|
{
|
||||||
|
ctx.state = PARSE_IDLE;
|
||||||
|
ctx.field_index = 0;
|
||||||
|
ctx.checksum_acc = 0;
|
||||||
|
ctx.cs_index = 0;
|
||||||
|
memset(&ctx.frame, 0, sizeof(ctx.frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_valid_cmd_char(char c)
|
||||||
|
{
|
||||||
|
return isupper((unsigned char)c) || isdigit((unsigned char)c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_valid_param_char(char c)
|
||||||
|
{
|
||||||
|
return isprint((unsigned char)c) && c != '*' && c != '\r' && c != '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t hex_char_to_val(char c)
|
||||||
|
{
|
||||||
|
if (c >= '0' && c <= '9') return c - '0';
|
||||||
|
if (c >= 'A' && c <= 'F') return c - 'A' + 10;
|
||||||
|
if (c >= 'a' && c <= 'f') return c - 'a' + 10;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t hex_to_byte(char high, char low)
|
||||||
|
{
|
||||||
|
return (hex_char_to_val(high) << 4) | hex_char_to_val(low);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t calc_checksum(const char *data, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t cs = 0;
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
cs ^= (uint8_t)data[i];
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_response_ok(const char *content)
|
||||||
|
{
|
||||||
|
char msg[64];
|
||||||
|
uint8_t cs;
|
||||||
|
|
||||||
|
int len = snprintf(msg, sizeof(msg), "$OK,%s*", content);
|
||||||
|
cs = calc_checksum(msg + 1, len - 1);
|
||||||
|
snprintf(msg + len, sizeof(msg) - len, "%02X\r\n", cs);
|
||||||
|
|
||||||
|
UART2_Print_String(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_response_err(const char *err_code)
|
||||||
|
{
|
||||||
|
char msg[32];
|
||||||
|
uint8_t cs;
|
||||||
|
|
||||||
|
int len = snprintf(msg, sizeof(msg), "$ERR,%s*", err_code);
|
||||||
|
cs = calc_checksum(msg + 1, len - 1);
|
||||||
|
snprintf(msg + len, sizeof(msg) - len, "%02X\r\n", cs);
|
||||||
|
|
||||||
|
UART2_Print_String(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_str_empty(const char *str)
|
||||||
|
{
|
||||||
|
return (str == NULL || str[0] == '\0');
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_str_numeric(const char *str)
|
||||||
|
{
|
||||||
|
if (is_str_empty(str)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
while (*str) {
|
||||||
|
if (!isdigit((unsigned char)*str)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
str++;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void process_cmd_frame(const cmd_frame_t *frame)
|
||||||
|
{
|
||||||
|
DEBUG_LOG("CMD=%s P1=%s P2=%s CS=%02X/%02X %s",
|
||||||
|
frame->cmd, frame->param1, frame->param2,
|
||||||
|
frame->received_cs, frame->calculated_cs,
|
||||||
|
frame->skip_checksum ? "(skip)" : "");
|
||||||
|
|
||||||
|
if (strcmp(frame->cmd, "RL") == 0) {
|
||||||
|
if (!is_str_numeric(frame->param1) || !is_str_numeric(frame->param2)) {
|
||||||
|
send_response_err("PARAM");
|
||||||
|
DEBUG_LOG("Invalid RL params: not numeric");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int relay_id = atoi(frame->param1);
|
||||||
|
int state = atoi(frame->param2);
|
||||||
|
|
||||||
|
if (relay_id >= 1 && relay_id <= 4 && (state == 0 || state == 1)) {
|
||||||
|
Relay_SetState(relay_id, state ? true : false);
|
||||||
|
|
||||||
|
char resp[32];
|
||||||
|
snprintf(resp, sizeof(resp), "RL,%d,%d", relay_id, state);
|
||||||
|
send_response_ok(resp);
|
||||||
|
|
||||||
|
DEBUG_LOG("Relay %d -> %s", relay_id, state ? "ON" : "OFF");
|
||||||
|
} else {
|
||||||
|
send_response_err("PARAM");
|
||||||
|
DEBUG_LOG("Invalid RL params: id=%d state=%d", relay_id, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(frame->cmd, "DI") == 0) {
|
||||||
|
if (is_str_empty(frame->param1) || strcmp(frame->param1, "0") == 0) {
|
||||||
|
uint8_t states = IO_Monitor_GetAllStates();
|
||||||
|
char resp[32];
|
||||||
|
snprintf(resp, sizeof(resp), "DI,%d%d%d%d",
|
||||||
|
(states >> 0) & 1, (states >> 1) & 1,
|
||||||
|
(states >> 2) & 1, (states >> 3) & 1);
|
||||||
|
send_response_ok(resp);
|
||||||
|
DEBUG_LOG("DI all states: 0x%02X", states);
|
||||||
|
}
|
||||||
|
else if (is_str_numeric(frame->param1)) {
|
||||||
|
int channel = atoi(frame->param1);
|
||||||
|
if (channel >= 1 && channel <= 4) {
|
||||||
|
uint8_t state = IO_Monitor_GetState(channel - 1);
|
||||||
|
char resp[32];
|
||||||
|
snprintf(resp, sizeof(resp), "DI,%d,%d", channel, state);
|
||||||
|
send_response_ok(resp);
|
||||||
|
DEBUG_LOG("DI%d = %d", channel, state);
|
||||||
|
} else {
|
||||||
|
send_response_err("PARAM");
|
||||||
|
DEBUG_LOG("Invalid DI channel: %d", channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
send_response_err("PARAM");
|
||||||
|
DEBUG_LOG("Invalid DI param: not numeric");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (strcmp(frame->cmd, "ECHO") == 0) {
|
||||||
|
send_response_ok("ECHO");
|
||||||
|
DEBUG_LOG("ECHO response sent");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
send_response_err("CMD");
|
||||||
|
DEBUG_LOG("Unknown command: %s", frame->cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdParser_Init(void)
|
||||||
|
{
|
||||||
|
memset(&ctx, 0, sizeof(ctx));
|
||||||
|
ctx.state = PARSE_IDLE;
|
||||||
|
|
||||||
|
DEBUG_LOG("Init OK");
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdParser_FeedByte(uint8_t byte, uint32_t current_tick)
|
||||||
|
{
|
||||||
|
if (ctx.state != PARSE_IDLE && ctx.state != PARSE_COMPLETE) {
|
||||||
|
if (current_tick - ctx.last_rx_tick >= PARSE_TIMEOUT_MS) {
|
||||||
|
ctx.error_count++;
|
||||||
|
DEBUG_LOG("Timeout, reset parser");
|
||||||
|
reset_parser();
|
||||||
|
if (byte == '$') {
|
||||||
|
ctx.state = PARSE_CMD;
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.last_rx_tick = current_tick;
|
||||||
|
|
||||||
|
switch (ctx.state) {
|
||||||
|
case PARSE_IDLE:
|
||||||
|
if (byte == '$') {
|
||||||
|
reset_parser();
|
||||||
|
ctx.state = PARSE_CMD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_CMD:
|
||||||
|
if (byte == ',') {
|
||||||
|
ctx.frame.cmd[ctx.field_index] = '\0';
|
||||||
|
ctx.state = PARSE_PARAM1;
|
||||||
|
ctx.field_index = 0;
|
||||||
|
} else if (byte == '*') {
|
||||||
|
ctx.frame.cmd[ctx.field_index] = '\0';
|
||||||
|
ctx.state = PARSE_CHECKSUM;
|
||||||
|
ctx.field_index = 0;
|
||||||
|
ctx.cs_index = 0;
|
||||||
|
} else if (is_valid_cmd_char(byte)) {
|
||||||
|
if (ctx.field_index < CMD_MAX_LEN - 1) {
|
||||||
|
ctx.frame.cmd[ctx.field_index++] = byte;
|
||||||
|
ctx.checksum_acc ^= byte;
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_PARAM1:
|
||||||
|
if (byte == ',') {
|
||||||
|
ctx.frame.param1[ctx.field_index] = '\0';
|
||||||
|
ctx.state = PARSE_PARAM2;
|
||||||
|
ctx.field_index = 0;
|
||||||
|
} else if (byte == '*') {
|
||||||
|
ctx.frame.param1[ctx.field_index] = '\0';
|
||||||
|
ctx.state = PARSE_CHECKSUM;
|
||||||
|
ctx.field_index = 0;
|
||||||
|
ctx.cs_index = 0;
|
||||||
|
} else if (is_valid_param_char(byte)) {
|
||||||
|
if (ctx.field_index < PARAM_MAX_LEN - 1) {
|
||||||
|
ctx.frame.param1[ctx.field_index++] = byte;
|
||||||
|
ctx.checksum_acc ^= byte;
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_PARAM2:
|
||||||
|
if (byte == '*') {
|
||||||
|
ctx.frame.param2[ctx.field_index] = '\0';
|
||||||
|
ctx.state = PARSE_CHECKSUM;
|
||||||
|
ctx.field_index = 0;
|
||||||
|
ctx.cs_index = 0;
|
||||||
|
} else if (is_valid_param_char(byte)) {
|
||||||
|
if (ctx.field_index < PARAM_MAX_LEN - 1) {
|
||||||
|
ctx.frame.param2[ctx.field_index++] = byte;
|
||||||
|
ctx.checksum_acc ^= byte;
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_CHECKSUM:
|
||||||
|
if (byte == '\n') {
|
||||||
|
ctx.frame.received_cs = hex_to_byte(ctx.cs_buffer[0], ctx.cs_buffer[1]);
|
||||||
|
ctx.frame.calculated_cs = ctx.checksum_acc;
|
||||||
|
ctx.frame.skip_checksum = (ctx.frame.received_cs == 0xFF);
|
||||||
|
|
||||||
|
if (ctx.frame.skip_checksum ||
|
||||||
|
ctx.frame.received_cs == ctx.frame.calculated_cs) {
|
||||||
|
ctx.frame.valid = true;
|
||||||
|
ctx.state = PARSE_COMPLETE;
|
||||||
|
ctx.valid_count++;
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
DEBUG_LOG("Checksum error: recv=%02X calc=%02X",
|
||||||
|
ctx.frame.received_cs, ctx.frame.calculated_cs);
|
||||||
|
send_response_err("CS");
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else if (byte != '\r') {
|
||||||
|
if (ctx.cs_index < 2) {
|
||||||
|
ctx.cs_buffer[ctx.cs_index++] = byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_COMPLETE:
|
||||||
|
reset_parser();
|
||||||
|
if (byte == '$') {
|
||||||
|
ctx.state = PARSE_CMD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdParser_Task(void)
|
||||||
|
{
|
||||||
|
if (ctx.state == PARSE_COMPLETE && ctx.frame.valid) {
|
||||||
|
process_cmd_frame(&ctx.frame);
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CmdParser_HasCompleteFrame(cmd_frame_t *frame)
|
||||||
|
{
|
||||||
|
if (ctx.state == PARSE_COMPLETE && ctx.frame.valid) {
|
||||||
|
if (frame) {
|
||||||
|
memcpy(frame, &ctx.frame, sizeof(cmd_frame_t));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdParser_Acknowledge(void)
|
||||||
|
{
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CmdParser_GetErrorCount(void)
|
||||||
|
{
|
||||||
|
return ctx.error_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t CmdParser_GetValidCount(void)
|
||||||
|
{
|
||||||
|
return ctx.valid_count;
|
||||||
|
}
|
||||||
158
Core/Src/io_monitor.c
Normal file
158
Core/Src/io_monitor.c
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file io_monitor.c
|
||||||
|
* @brief IO状态监控模块实现
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.1
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块实现四路数字输入的状态监控
|
||||||
|
* 关键特性:
|
||||||
|
* 1. 10ms定时扫描,平衡响应速度和CPU占用
|
||||||
|
* 2. 软件去抖,连续3次相同状态才确认变化
|
||||||
|
* 3. 状态变化时自动上报ASCII格式消息
|
||||||
|
*
|
||||||
|
* 修订历史:
|
||||||
|
* v1.1 - 修复审查报告中危-5:去抖计数器初始化优化
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "io_monitor.h"
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#include "main.h"
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#define DEBUG_IO_MONITOR 1
|
||||||
|
|
||||||
|
#if DEBUG_IO_MONITOR
|
||||||
|
#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[IO] " fmt "\r\n", ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_LOG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint16_t pin;
|
||||||
|
uint8_t current_state;
|
||||||
|
uint8_t debounce_counter;
|
||||||
|
uint8_t last_raw_state;
|
||||||
|
uint32_t change_count;
|
||||||
|
} io_channel_t;
|
||||||
|
|
||||||
|
static io_channel_t di_channels[IO_CHANNEL_COUNT] = {
|
||||||
|
{GPIOB, GPIO_PIN_4, 0, 0, 0, 0},
|
||||||
|
{GPIOB, GPIO_PIN_5, 0, 0, 0, 0},
|
||||||
|
{GPIOB, GPIO_PIN_6, 0, 0, 0, 0},
|
||||||
|
{GPIOB, GPIO_PIN_7, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t last_scan_tick = 0;
|
||||||
|
static bool report_enabled = true;
|
||||||
|
|
||||||
|
static uint8_t calc_checksum(const char *data, uint8_t len)
|
||||||
|
{
|
||||||
|
uint8_t cs = 0;
|
||||||
|
for (uint8_t i = 0; i < len; i++) {
|
||||||
|
cs ^= (uint8_t)data[i];
|
||||||
|
}
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void send_di_event(uint8_t channel, uint8_t state)
|
||||||
|
{
|
||||||
|
char msg[32];
|
||||||
|
uint8_t cs;
|
||||||
|
|
||||||
|
int len = snprintf(msg, sizeof(msg), "$DI_EVENT,%d,%d*", channel + 1, state);
|
||||||
|
|
||||||
|
cs = calc_checksum(msg + 1, len - 1);
|
||||||
|
|
||||||
|
snprintf(msg + len, sizeof(msg) - len, "%02X\r\n", cs);
|
||||||
|
|
||||||
|
UART2_Print_String(msg);
|
||||||
|
|
||||||
|
DEBUG_LOG("CH%d -> %s", channel + 1, state ? "HIGH" : "LOW");
|
||||||
|
}
|
||||||
|
|
||||||
|
void IO_Monitor_Init(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < IO_CHANNEL_COUNT; i++) {
|
||||||
|
io_channel_t *ch = &di_channels[i];
|
||||||
|
|
||||||
|
ch->current_state = HAL_GPIO_ReadPin(ch->port, ch->pin) ? 1 : 0;
|
||||||
|
ch->last_raw_state = ch->current_state;
|
||||||
|
ch->debounce_counter = 1;
|
||||||
|
ch->change_count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_scan_tick = 0;
|
||||||
|
report_enabled = true;
|
||||||
|
|
||||||
|
DEBUG_LOG("Init OK, initial states: 0x%02X", IO_Monitor_GetAllStates());
|
||||||
|
}
|
||||||
|
|
||||||
|
void IO_Monitor_Task(void)
|
||||||
|
{
|
||||||
|
uint32_t current_tick = HAL_GetTick();
|
||||||
|
|
||||||
|
if (current_tick - last_scan_tick < IO_SCAN_PERIOD_MS) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_scan_tick = current_tick;
|
||||||
|
|
||||||
|
for (int i = 0; i < IO_CHANNEL_COUNT; i++) {
|
||||||
|
io_channel_t *ch = &di_channels[i];
|
||||||
|
|
||||||
|
uint8_t raw_state = HAL_GPIO_ReadPin(ch->port, ch->pin) ? 1 : 0;
|
||||||
|
|
||||||
|
if (raw_state != ch->last_raw_state) {
|
||||||
|
ch->debounce_counter = 0;
|
||||||
|
ch->last_raw_state = raw_state;
|
||||||
|
} else {
|
||||||
|
if (ch->debounce_counter < IO_DEBOUNCE_COUNT) {
|
||||||
|
ch->debounce_counter++;
|
||||||
|
} else if (ch->current_state != raw_state) {
|
||||||
|
ch->current_state = raw_state;
|
||||||
|
ch->change_count++;
|
||||||
|
|
||||||
|
if (report_enabled) {
|
||||||
|
send_di_event(i, raw_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t IO_Monitor_GetState(uint8_t channel)
|
||||||
|
{
|
||||||
|
if (channel >= IO_CHANNEL_COUNT) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return di_channels[channel].current_state;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t IO_Monitor_GetAllStates(void)
|
||||||
|
{
|
||||||
|
uint8_t states = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < IO_CHANNEL_COUNT; i++) {
|
||||||
|
if (di_channels[i].current_state) {
|
||||||
|
states |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return states;
|
||||||
|
}
|
||||||
|
|
||||||
|
void IO_Monitor_EnableReport(bool enable)
|
||||||
|
{
|
||||||
|
report_enabled = enable;
|
||||||
|
DEBUG_LOG("Report %s", enable ? "enabled" : "disabled");
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t IO_Monitor_GetChangeCount(uint8_t channel)
|
||||||
|
{
|
||||||
|
if (channel >= IO_CHANNEL_COUNT) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return di_channels[channel].change_count;
|
||||||
|
}
|
||||||
@ -28,6 +28,12 @@
|
|||||||
#include "rf433_config.h"
|
#include "rf433_config.h"
|
||||||
#include "rf433_hal.h"
|
#include "rf433_hal.h"
|
||||||
|
|
||||||
|
/* 应用层模块头文件 */
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#include "io_monitor.h"
|
||||||
|
#include "cmd_parser.h"
|
||||||
|
#include "relay_control.h"
|
||||||
|
|
||||||
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
#include "rf433_tx_app.h"
|
#include "rf433_tx_app.h"
|
||||||
#endif
|
#endif
|
||||||
@ -55,7 +61,7 @@
|
|||||||
/* Private variables ---------------------------------------------------------*/
|
/* Private variables ---------------------------------------------------------*/
|
||||||
|
|
||||||
/* USER CODE BEGIN PV */
|
/* USER CODE BEGIN PV */
|
||||||
|
static uint8_t uart2_rx_byte = 0;
|
||||||
/* USER CODE END PV */
|
/* USER CODE END PV */
|
||||||
|
|
||||||
/* Private function prototypes -----------------------------------------------*/
|
/* Private function prototypes -----------------------------------------------*/
|
||||||
@ -100,11 +106,20 @@ int main(void)
|
|||||||
MX_USART3_UART_Init();
|
MX_USART3_UART_Init();
|
||||||
/* USER CODE BEGIN 2 */
|
/* USER CODE BEGIN 2 */
|
||||||
|
|
||||||
/* 初始化RF433模块 - 使用默认配置 */
|
/* 初始化应用层模块 */
|
||||||
rf433_init(NULL);
|
UART2_Print_Init();
|
||||||
|
IO_Monitor_Init();
|
||||||
|
CmdParser_Init();
|
||||||
|
Relay_Init();
|
||||||
|
|
||||||
/* 启动UART接收 - 使用rf433_hal中的临时变量 */
|
/* 启动UART2接收中断 */
|
||||||
HAL_UART_Receive_IT(&huart1, &rf433_uart_rx_tmp, 1);
|
HAL_UART_Receive_IT(&huart2, &uart2_rx_byte, 1);
|
||||||
|
|
||||||
|
/* 初始化RF433模块 - 使用默认配置 */
|
||||||
|
rf433_init(NULL);
|
||||||
|
|
||||||
|
/* 启动UART1接收 - 使用rf433_hal中的临时变量 */
|
||||||
|
HAL_UART_Receive_IT(&huart1, &rf433_uart_rx_tmp, 1);
|
||||||
|
|
||||||
/* 根据配置模式初始化TX/RX应用层 */
|
/* 根据配置模式初始化TX/RX应用层 */
|
||||||
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
@ -119,7 +134,13 @@ int main(void)
|
|||||||
rf433_rx_app_start();
|
rf433_rx_app_start();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* USER CODE END 2 */
|
/* 打印启动信息 */
|
||||||
|
printf("\r\n========================================\r\n");
|
||||||
|
printf("E32-433TBH-SC Application Started\r\n");
|
||||||
|
printf("System Clock: %d MHz\r\n", SystemCoreClock / 1000000);
|
||||||
|
printf("========================================\r\n");
|
||||||
|
|
||||||
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Infinite loop */
|
/* Infinite loop */
|
||||||
/* USER CODE BEGIN WHILE */
|
/* USER CODE BEGIN WHILE */
|
||||||
@ -129,6 +150,11 @@ int main(void)
|
|||||||
|
|
||||||
/* USER CODE BEGIN 3 */
|
/* USER CODE BEGIN 3 */
|
||||||
|
|
||||||
|
/* 应用层任务处理 */
|
||||||
|
UART2_Print_Task();
|
||||||
|
IO_Monitor_Task();
|
||||||
|
CmdParser_Task();
|
||||||
|
|
||||||
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
/* TX任务 */
|
/* TX任务 */
|
||||||
rf433_tx_app_task();
|
rf433_tx_app_task();
|
||||||
@ -139,8 +165,6 @@ int main(void)
|
|||||||
rf433_rx_app_task();
|
rf433_rx_app_task();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* 短延时,避免CPU占用过高 */
|
|
||||||
HAL_Delay(1);
|
|
||||||
}
|
}
|
||||||
/* USER CODE END 3 */
|
/* USER CODE END 3 */
|
||||||
}
|
}
|
||||||
@ -186,6 +210,43 @@ void SystemClock_Config(void)
|
|||||||
|
|
||||||
/* USER CODE BEGIN 4 */
|
/* USER CODE BEGIN 4 */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART接收完成中断回调函数
|
||||||
|
* @note 处理UART1(RF433)和UART2(调试口)的接收数据
|
||||||
|
* @param huart: UART句柄指针
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||||
|
{
|
||||||
|
if (huart->Instance == USART1)
|
||||||
|
{
|
||||||
|
/* 调用RF433模块的UART接收回调 */
|
||||||
|
rf433_hal_uart_rxcplt_callback();
|
||||||
|
}
|
||||||
|
else if (huart->Instance == USART2)
|
||||||
|
{
|
||||||
|
/* 喂入指令解析器 */
|
||||||
|
CmdParser_FeedByte(uart2_rx_byte, HAL_GetTick());
|
||||||
|
/* 重新启动接收 */
|
||||||
|
HAL_UART_Receive_IT(&huart2, &uart2_rx_byte, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief UART发送完成中断回调函数
|
||||||
|
* @note 处理UART2发送完成,触发下一次发送
|
||||||
|
* @param huart: UART句柄指针
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||||
|
{
|
||||||
|
if (huart->Instance == USART2)
|
||||||
|
{
|
||||||
|
/* 调用UART2打印模块的发送完成回调 */
|
||||||
|
UART2_Print_TxCpltCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* USER CODE END 4 */
|
/* USER CODE END 4 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
102
Core/Src/relay_control.c
Normal file
102
Core/Src/relay_control.c
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file relay_control.c
|
||||||
|
* @brief 继电器控制模块实现
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.1
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块实现继电器的安全控制
|
||||||
|
* 关键特性:
|
||||||
|
* 1. 最小切换间隔保护,防止频繁切换损坏继电器
|
||||||
|
* 2. 状态记录,支持诊断
|
||||||
|
* 3. 调试日志输出
|
||||||
|
*
|
||||||
|
* 修订历史:
|
||||||
|
* v1.1 - 修复审查报告中危-9/10:对齐RELAY_COUNT与参数校验逻辑
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "relay_control.h"
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
#define DEBUG_RELAY 1
|
||||||
|
|
||||||
|
#if DEBUG_RELAY
|
||||||
|
#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[RELAY] " fmt "\r\n", ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_LOG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAX_RELAY_ID 4
|
||||||
|
|
||||||
|
static bool current_states[MAX_RELAY_ID] = {false, false, false, false};
|
||||||
|
static uint32_t last_toggle_tick = 0;
|
||||||
|
static uint32_t toggle_count = 0;
|
||||||
|
|
||||||
|
void Relay_Init(void)
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin, GPIO_PIN_RESET);
|
||||||
|
|
||||||
|
for (int i = 0; i < MAX_RELAY_ID; i++) {
|
||||||
|
current_states[i] = false;
|
||||||
|
}
|
||||||
|
last_toggle_tick = 0;
|
||||||
|
toggle_count = 0;
|
||||||
|
|
||||||
|
DEBUG_LOG("Init OK, state=OFF");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Relay_SetState(uint8_t relay_id, bool state)
|
||||||
|
{
|
||||||
|
if (relay_id < 1 || relay_id > MAX_RELAY_ID) {
|
||||||
|
DEBUG_LOG("Invalid relay ID: %d", relay_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t current_tick = HAL_GetTick();
|
||||||
|
if (current_tick - last_toggle_tick < RELAY_MIN_INTERVAL) {
|
||||||
|
DEBUG_LOG("Toggle too fast, ignored");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t idx = relay_id - 1;
|
||||||
|
|
||||||
|
if (current_states[idx] == state) {
|
||||||
|
DEBUG_LOG("State unchanged: %s", state ? "ON" : "OFF");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (relay_id == 1) {
|
||||||
|
HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin,
|
||||||
|
state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
current_states[idx] = state;
|
||||||
|
last_toggle_tick = current_tick;
|
||||||
|
toggle_count++;
|
||||||
|
|
||||||
|
DEBUG_LOG("Relay %d -> %s (count=%lu)", relay_id, state ? "ON" : "OFF", toggle_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Relay_GetState(uint8_t relay_id)
|
||||||
|
{
|
||||||
|
if (relay_id < 1 || relay_id > MAX_RELAY_ID) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return current_states[relay_id - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
void Relay_Toggle(uint8_t relay_id)
|
||||||
|
{
|
||||||
|
if (relay_id < 1 || relay_id > MAX_RELAY_ID) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Relay_SetState(relay_id, !current_states[relay_id - 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t Relay_GetToggleCount(void)
|
||||||
|
{
|
||||||
|
return toggle_count;
|
||||||
|
}
|
||||||
@ -14,7 +14,13 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#define DEBUG_CMD_PARSER 1
|
||||||
|
#if DEBUG_CMD_PARSER
|
||||||
|
#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[CMD] " fmt "\r\n", ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_LOG(fmt, ...)
|
||||||
|
#endif
|
||||||
/* ============================================================================
|
/* ============================================================================
|
||||||
* 私有变量
|
* 私有变量
|
||||||
* ============================================================================ */
|
* ============================================================================ */
|
||||||
|
|||||||
224
Core/Src/uart2_print.c
Normal file
224
Core/Src/uart2_print.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file uart2_print.c
|
||||||
|
* @brief UART2调试打印模块实现
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.1
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本模块实现基于环形缓冲区的非阻塞调试信息输出
|
||||||
|
* 关键特性:
|
||||||
|
* 1. 环形缓冲区避免数据丢失
|
||||||
|
* 2. 中断安全,支持ISR中调用
|
||||||
|
* 3. 非阻塞发送,不影响实时性
|
||||||
|
*
|
||||||
|
* 修订历史:
|
||||||
|
* v1.1 - 修复审查报告高危-1/2/3,中危-4
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#include "usart.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define DEBUG_PRINT_ENABLED 1
|
||||||
|
|
||||||
|
#if DEBUG_PRINT_ENABLED
|
||||||
|
#define DEBUG_LOG(fmt, ...) UART2_Print_Printf("[UART2] " fmt "\r\n", ##__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define DEBUG_LOG(fmt, ...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t buffer[UART2_TX_BUFFER_SIZE];
|
||||||
|
volatile uint16_t head;
|
||||||
|
volatile uint16_t tail;
|
||||||
|
volatile uint16_t count;
|
||||||
|
volatile bool is_sending;
|
||||||
|
volatile uint16_t overflow_count;
|
||||||
|
} ring_buffer_t;
|
||||||
|
|
||||||
|
static ring_buffer_t tx_ring = {0};
|
||||||
|
|
||||||
|
void UART2_Print_Init(void)
|
||||||
|
{
|
||||||
|
tx_ring.head = 0;
|
||||||
|
tx_ring.tail = 0;
|
||||||
|
tx_ring.count = 0;
|
||||||
|
tx_ring.is_sending = false;
|
||||||
|
tx_ring.overflow_count = 0;
|
||||||
|
|
||||||
|
DEBUG_LOG("Init OK, buffer size: %d", UART2_TX_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_Send(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
if (len == 0 || data == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t written = 0;
|
||||||
|
bool needs_kickoff = false;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
if (tx_ring.count >= UART2_TX_BUFFER_SIZE) {
|
||||||
|
tx_ring.overflow_count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_ring.buffer[tx_ring.head] = data[i];
|
||||||
|
tx_ring.head = (tx_ring.head + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
tx_ring.count++;
|
||||||
|
written++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written > 0 && !tx_ring.is_sending) {
|
||||||
|
tx_ring.is_sending = true;
|
||||||
|
needs_kickoff = true;
|
||||||
|
}
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
if (needs_kickoff) {
|
||||||
|
uint8_t byte;
|
||||||
|
__disable_irq();
|
||||||
|
byte = tx_ring.buffer[tx_ring.tail];
|
||||||
|
__enable_irq();
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &byte, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_String(const char *str)
|
||||||
|
{
|
||||||
|
if (str == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
UART2_Print_Send((const uint8_t *)str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_Printf(const char *fmt, ...)
|
||||||
|
{
|
||||||
|
if (fmt == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char buffer[128];
|
||||||
|
va_list args;
|
||||||
|
|
||||||
|
va_start(args, fmt);
|
||||||
|
int len = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (len >= 0) {
|
||||||
|
if (len >= (int)sizeof(buffer)) {
|
||||||
|
len = sizeof(buffer) - 1;
|
||||||
|
}
|
||||||
|
UART2_Print_Send((const uint8_t *)buffer, len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_Task(void)
|
||||||
|
{
|
||||||
|
uint8_t byte;
|
||||||
|
uint16_t current_tail;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
if (tx_ring.is_sending || tx_ring.count == 0) {
|
||||||
|
__enable_irq();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_tail = tx_ring.tail;
|
||||||
|
tx_ring.tail = (tx_ring.tail + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
tx_ring.count--;
|
||||||
|
tx_ring.is_sending = true;
|
||||||
|
byte = tx_ring.buffer[current_tail];
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_TxCpltCallback(void)
|
||||||
|
{
|
||||||
|
uint8_t byte;
|
||||||
|
uint16_t current_tail;
|
||||||
|
bool has_more = false;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
tx_ring.is_sending = false;
|
||||||
|
|
||||||
|
if (tx_ring.count > 0) {
|
||||||
|
current_tail = tx_ring.tail;
|
||||||
|
tx_ring.tail = (tx_ring.tail + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
tx_ring.count--;
|
||||||
|
tx_ring.is_sending = true;
|
||||||
|
byte = tx_ring.buffer[current_tail];
|
||||||
|
has_more = true;
|
||||||
|
}
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
if (has_more) {
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &byte, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool UART2_Print_IsBusy(void)
|
||||||
|
{
|
||||||
|
bool busy;
|
||||||
|
__disable_irq();
|
||||||
|
busy = tx_ring.is_sending || (tx_ring.count > 0);
|
||||||
|
__enable_irq();
|
||||||
|
return busy;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t UART2_Print_Available(void)
|
||||||
|
{
|
||||||
|
uint16_t available;
|
||||||
|
__disable_irq();
|
||||||
|
available = UART2_TX_BUFFER_SIZE - tx_ring.count;
|
||||||
|
__enable_irq();
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t UART2_Print_GetOverflowCount(void)
|
||||||
|
{
|
||||||
|
return tx_ring.overflow_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief printf重定向函数 (Keil MDK)
|
||||||
|
* @note 重定向标准库printf到UART2
|
||||||
|
* @param ch: 待发送字符
|
||||||
|
* @param f: 文件指针(未使用)
|
||||||
|
* @retval 发送的字符
|
||||||
|
*/
|
||||||
|
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||||
|
int fputc(int ch, FILE *f)
|
||||||
|
{
|
||||||
|
(void)f;
|
||||||
|
UART2_Print_Send((uint8_t *)&ch, 1);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief printf重定向函数 (GCC)
|
||||||
|
* @note 重定向标准库printf到UART2
|
||||||
|
* @param ch: 待发送字符
|
||||||
|
* @retval 发送的字符
|
||||||
|
*/
|
||||||
|
#if defined(__GNUC__)
|
||||||
|
int __io_putchar(int ch)
|
||||||
|
{
|
||||||
|
UART2_Print_Send((uint8_t *)&ch, 1);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _write(int file, char *ptr, int len)
|
||||||
|
{
|
||||||
|
(void)file;
|
||||||
|
UART2_Print_Send((uint8_t *)ptr, len);
|
||||||
|
return len;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
@ -279,30 +279,28 @@ void HAL_UART_MspDeInit(UART_HandleTypeDef* uartHandle)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* USER CODE BEGIN 1 */
|
/* USER CODE BEGIN 1 */
|
||||||
void uart1_reconfig( uint32_t rate )
|
/**
|
||||||
|
* @brief UART1波特率重配置函数
|
||||||
|
* @note 用于RF433模块波特率动态调整
|
||||||
|
* @param rate: 目标波特率
|
||||||
|
* @retval 无
|
||||||
|
*/
|
||||||
|
void uart1_reconfig(uint32_t rate)
|
||||||
{
|
{
|
||||||
/* 原串口1的初始化 */
|
huart1.Instance = USART1;
|
||||||
huart1.Instance = USART1;
|
huart1.Init.BaudRate = rate;
|
||||||
huart1.Init.BaudRate = rate;
|
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
||||||
huart1.Init.WordLength = UART_WORDLENGTH_8B;
|
huart1.Init.StopBits = UART_STOPBITS_1;
|
||||||
huart1.Init.StopBits = UART_STOPBITS_1;
|
huart1.Init.Parity = UART_PARITY_NONE;
|
||||||
huart1.Init.Parity = UART_PARITY_NONE;
|
huart1.Init.Mode = UART_MODE_TX_RX;
|
||||||
huart1.Init.Mode = UART_MODE_TX_RX;
|
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
||||||
huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
|
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
||||||
huart1.Init.OverSampling = UART_OVERSAMPLING_16;
|
if (HAL_UART_Init(&huart1) != HAL_OK)
|
||||||
if (HAL_UART_Init(&huart1) != HAL_OK)
|
{
|
||||||
{
|
Error_Handler();
|
||||||
Error_Handler();
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
/* UART回调函数已移至main.c统一管理 */
|
||||||
{
|
|
||||||
if (huart->Instance == USART1)
|
|
||||||
{
|
|
||||||
/* 调用RF433模块的UART接收回调 */
|
|
||||||
rf433_hal_uart_rxcplt_callback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* USER CODE END 1 */
|
/* USER CODE END 1 */
|
||||||
|
|||||||
@ -28,7 +28,7 @@ extern "C" {
|
|||||||
#define RF433_MODE_BOTH 3
|
#define RF433_MODE_BOTH 3
|
||||||
|
|
||||||
#ifndef RF433_MODE
|
#ifndef RF433_MODE
|
||||||
#define RF433_MODE RF433_MODE_RX
|
#define RF433_MODE RF433_MODE_TX
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* ============================================================================
|
/* ============================================================================
|
||||||
|
|||||||
@ -9,6 +9,7 @@
|
|||||||
#include "rf433.h"
|
#include "rf433.h"
|
||||||
#include "rf433_hal.h"
|
#include "rf433_hal.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h> // printf
|
||||||
#include "stm32f1xx_hal.h"
|
#include "stm32f1xx_hal.h"
|
||||||
|
|
||||||
/* ============================================================================
|
/* ============================================================================
|
||||||
@ -362,7 +363,7 @@ rf433_error_t rf433_transmit(uint8_t *buffer, uint16_t length)
|
|||||||
{
|
{
|
||||||
return RF433_ERROR_TIMEOUT;
|
return RF433_ERROR_TIMEOUT;
|
||||||
}
|
}
|
||||||
|
printf("Sent: %s", (char*)buffer); // DEBUG_LOG未定义,使用printf替代
|
||||||
return RF433_OK;
|
return RF433_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@ -159,16 +159,16 @@
|
|||||||
<Type>0</Type>
|
<Type>0</Type>
|
||||||
<LineNumber>188</LineNumber>
|
<LineNumber>188</LineNumber>
|
||||||
<EnabledFlag>1</EnabledFlag>
|
<EnabledFlag>1</EnabledFlag>
|
||||||
<Address>134227242</Address>
|
<Address>0</Address>
|
||||||
<ByteObject>0</ByteObject>
|
<ByteObject>0</ByteObject>
|
||||||
<HtxType>0</HtxType>
|
<HtxType>0</HtxType>
|
||||||
<ManyObjects>0</ManyObjects>
|
<ManyObjects>0</ManyObjects>
|
||||||
<SizeOfObject>0</SizeOfObject>
|
<SizeOfObject>0</SizeOfObject>
|
||||||
<BreakByAccess>0</BreakByAccess>
|
<BreakByAccess>0</BreakByAccess>
|
||||||
<BreakIfRCount>1</BreakIfRCount>
|
<BreakIfRCount>0</BreakIfRCount>
|
||||||
<Filename>..\Core\Src\rf433_tx_app.c</Filename>
|
<Filename>..\Core\Src\rf433_tx_app.c</Filename>
|
||||||
<ExecCommand></ExecCommand>
|
<ExecCommand></ExecCommand>
|
||||||
<Expression>\\project\../Core/Src/rf433_tx_app.c\188</Expression>
|
<Expression></Expression>
|
||||||
</Bp>
|
</Bp>
|
||||||
</Breakpoint>
|
</Breakpoint>
|
||||||
<Tracepoint>
|
<Tracepoint>
|
||||||
@ -357,6 +357,54 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<bShared>0</bShared>
|
<bShared>0</bShared>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<GroupNumber>2</GroupNumber>
|
||||||
|
<FileNumber>11</FileNumber>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<tvExp>0</tvExp>
|
||||||
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
<bDave2>0</bDave2>
|
||||||
|
<PathWithFileName>..\Core\Src\cmd_parser.c</PathWithFileName>
|
||||||
|
<FilenameWithoutPath>cmd_parser.c</FilenameWithoutPath>
|
||||||
|
<RteFlg>0</RteFlg>
|
||||||
|
<bShared>0</bShared>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<GroupNumber>2</GroupNumber>
|
||||||
|
<FileNumber>12</FileNumber>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<tvExp>0</tvExp>
|
||||||
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
<bDave2>0</bDave2>
|
||||||
|
<PathWithFileName>..\Core\Src\io_monitor.c</PathWithFileName>
|
||||||
|
<FilenameWithoutPath>io_monitor.c</FilenameWithoutPath>
|
||||||
|
<RteFlg>0</RteFlg>
|
||||||
|
<bShared>0</bShared>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<GroupNumber>2</GroupNumber>
|
||||||
|
<FileNumber>13</FileNumber>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<tvExp>0</tvExp>
|
||||||
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
<bDave2>0</bDave2>
|
||||||
|
<PathWithFileName>..\Core\Src\relay_control.c</PathWithFileName>
|
||||||
|
<FilenameWithoutPath>relay_control.c</FilenameWithoutPath>
|
||||||
|
<RteFlg>0</RteFlg>
|
||||||
|
<bShared>0</bShared>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<GroupNumber>2</GroupNumber>
|
||||||
|
<FileNumber>14</FileNumber>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<tvExp>0</tvExp>
|
||||||
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
<bDave2>0</bDave2>
|
||||||
|
<PathWithFileName>..\Core\Src\uart2_print.c</PathWithFileName>
|
||||||
|
<FilenameWithoutPath>uart2_print.c</FilenameWithoutPath>
|
||||||
|
<RteFlg>0</RteFlg>
|
||||||
|
<bShared>0</bShared>
|
||||||
|
</File>
|
||||||
</Group>
|
</Group>
|
||||||
|
|
||||||
<Group>
|
<Group>
|
||||||
@ -367,7 +415,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>11</FileNumber>
|
<FileNumber>15</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -379,7 +427,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>12</FileNumber>
|
<FileNumber>16</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -391,7 +439,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>13</FileNumber>
|
<FileNumber>17</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -403,7 +451,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>14</FileNumber>
|
<FileNumber>18</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -415,7 +463,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>15</FileNumber>
|
<FileNumber>19</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -427,7 +475,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>16</FileNumber>
|
<FileNumber>20</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -439,7 +487,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>17</FileNumber>
|
<FileNumber>21</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -451,7 +499,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>18</FileNumber>
|
<FileNumber>22</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -463,7 +511,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>19</FileNumber>
|
<FileNumber>23</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -475,7 +523,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>20</FileNumber>
|
<FileNumber>24</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -487,7 +535,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>21</FileNumber>
|
<FileNumber>25</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -499,7 +547,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>22</FileNumber>
|
<FileNumber>26</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -511,7 +559,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>23</FileNumber>
|
<FileNumber>27</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -523,7 +571,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>24</FileNumber>
|
<FileNumber>28</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -535,7 +583,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>3</GroupNumber>
|
<GroupNumber>3</GroupNumber>
|
||||||
<FileNumber>25</FileNumber>
|
<FileNumber>29</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -555,7 +603,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>4</GroupNumber>
|
<GroupNumber>4</GroupNumber>
|
||||||
<FileNumber>26</FileNumber>
|
<FileNumber>30</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -575,7 +623,7 @@
|
|||||||
<RteFlg>0</RteFlg>
|
<RteFlg>0</RteFlg>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>5</GroupNumber>
|
<GroupNumber>5</GroupNumber>
|
||||||
<FileNumber>27</FileNumber>
|
<FileNumber>31</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -587,7 +635,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>5</GroupNumber>
|
<GroupNumber>5</GroupNumber>
|
||||||
<FileNumber>28</FileNumber>
|
<FileNumber>32</FileNumber>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -599,7 +647,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>5</GroupNumber>
|
<GroupNumber>5</GroupNumber>
|
||||||
<FileNumber>29</FileNumber>
|
<FileNumber>33</FileNumber>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -611,7 +659,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>5</GroupNumber>
|
<GroupNumber>5</GroupNumber>
|
||||||
<FileNumber>30</FileNumber>
|
<FileNumber>34</FileNumber>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
@ -623,7 +671,7 @@
|
|||||||
</File>
|
</File>
|
||||||
<File>
|
<File>
|
||||||
<GroupNumber>5</GroupNumber>
|
<GroupNumber>5</GroupNumber>
|
||||||
<FileNumber>31</FileNumber>
|
<FileNumber>35</FileNumber>
|
||||||
<FileType>5</FileType>
|
<FileType>5</FileType>
|
||||||
<tvExp>0</tvExp>
|
<tvExp>0</tvExp>
|
||||||
<tvExpOptDlg>0</tvExpOptDlg>
|
<tvExpOptDlg>0</tvExpOptDlg>
|
||||||
|
|||||||
@ -490,6 +490,26 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>../Core/Src/stm32f1xx_hal_msp.c</FilePath>
|
<FilePath>../Core/Src/stm32f1xx_hal_msp.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>cmd_parser.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Core\Src\cmd_parser.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>io_monitor.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Core\Src\io_monitor.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>relay_control.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Core\Src\relay_control.c</FilePath>
|
||||||
|
</File>
|
||||||
|
<File>
|
||||||
|
<FileName>uart2_print.c</FileName>
|
||||||
|
<FileType>1</FileType>
|
||||||
|
<FilePath>..\Core\Src\uart2_print.c</FilePath>
|
||||||
|
</File>
|
||||||
</Files>
|
</Files>
|
||||||
</Group>
|
</Group>
|
||||||
<Group>
|
<Group>
|
||||||
|
|||||||
BIN
MDK-ARM/project/cmd_parser.crf
Normal file
BIN
MDK-ARM/project/cmd_parser.crf
Normal file
Binary file not shown.
12
MDK-ARM/project/cmd_parser.d
Normal file
12
MDK-ARM/project/cmd_parser.d
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
project\cmd_parser.o: ..\Core\Src\cmd_parser.c
|
||||||
|
project\cmd_parser.o: ../Core/Inc/cmd_parser.h
|
||||||
|
project\cmd_parser.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
||||||
|
project\cmd_parser.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
||||||
|
project\cmd_parser.o: ../Core/Inc/uart2_print.h
|
||||||
|
project\cmd_parser.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdarg.h
|
||||||
|
project\cmd_parser.o: ../Core/Inc/io_monitor.h
|
||||||
|
project\cmd_parser.o: ../Core/Inc/relay_control.h
|
||||||
|
project\cmd_parser.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
|
||||||
|
project\cmd_parser.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\ctype.h
|
||||||
|
project\cmd_parser.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
|
||||||
|
project\cmd_parser.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdlib.h
|
||||||
BIN
MDK-ARM/project/cmd_parser.o
Normal file
BIN
MDK-ARM/project/cmd_parser.o
Normal file
Binary file not shown.
Binary file not shown.
BIN
MDK-ARM/project/io_monitor.crf
Normal file
BIN
MDK-ARM/project/io_monitor.crf
Normal file
Binary file not shown.
35
MDK-ARM/project/io_monitor.d
Normal file
35
MDK-ARM/project/io_monitor.d
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
project\io_monitor.o: ..\Core\Src\io_monitor.c
|
||||||
|
project\io_monitor.o: ../Core/Inc/io_monitor.h
|
||||||
|
project\io_monitor.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
||||||
|
project\io_monitor.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
||||||
|
project\io_monitor.o: ../Core/Inc/uart2_print.h
|
||||||
|
project\io_monitor.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdarg.h
|
||||||
|
project\io_monitor.o: ../Core/Inc/main.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\io_monitor.o: ../Core/Inc/stm32f1xx_hal_conf.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
|
||||||
|
project\io_monitor.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
|
||||||
|
project\io_monitor.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
|
||||||
|
project\io_monitor.o: ../Drivers/CMSIS/Include/core_cm3.h
|
||||||
|
project\io_monitor.o: ../Drivers/CMSIS/Include/cmsis_version.h
|
||||||
|
project\io_monitor.o: ../Drivers/CMSIS/Include/cmsis_compiler.h
|
||||||
|
project\io_monitor.o: ../Drivers/CMSIS/Include/cmsis_armcc.h
|
||||||
|
project\io_monitor.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
|
||||||
|
project\io_monitor.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stddef.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
|
||||||
|
project\io_monitor.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
|
||||||
|
project\io_monitor.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
|
||||||
|
project\io_monitor.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
|
||||||
BIN
MDK-ARM/project/io_monitor.o
Normal file
BIN
MDK-ARM/project/io_monitor.o
Normal file
Binary file not shown.
Binary file not shown.
@ -35,4 +35,9 @@ project\main.o: ../Core/Inc/gpio.h
|
|||||||
project\main.o: ../Driver_RF433/Inc/rf433.h
|
project\main.o: ../Driver_RF433/Inc/rf433.h
|
||||||
project\main.o: ../Driver_RF433/Inc/rf433_config.h
|
project\main.o: ../Driver_RF433/Inc/rf433_config.h
|
||||||
project\main.o: ../Driver_RF433/Inc/rf433_hal.h
|
project\main.o: ../Driver_RF433/Inc/rf433_hal.h
|
||||||
project\main.o: ../Core/Inc/rf433_rx_app.h
|
project\main.o: ../Core/Inc/uart2_print.h
|
||||||
|
project\main.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdarg.h
|
||||||
|
project\main.o: ../Core/Inc/io_monitor.h
|
||||||
|
project\main.o: ../Core/Inc/cmd_parser.h
|
||||||
|
project\main.o: ../Core/Inc/relay_control.h
|
||||||
|
project\main.o: ../Core/Inc/rf433_tx_app.h
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -22,53 +22,57 @@ Dialog DLL: TCM.DLL V1.56.6.0
|
|||||||
|
|
||||||
<h2>Project:</h2>
|
<h2>Project:</h2>
|
||||||
C:\workfile\E32-433\software\E32-433TBH-SC\MDK-ARM\project.uvprojx
|
C:\workfile\E32-433\software\E32-433TBH-SC\MDK-ARM\project.uvprojx
|
||||||
Project File Date: 03/25/2026
|
Project File Date: 03/26/2026
|
||||||
|
|
||||||
<h2>Output:</h2>
|
<h2>Output:</h2>
|
||||||
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
|
*** Using Compiler 'V5.06 update 7 (build 960)', folder: 'C:\Keil_v5\ARM\ARMCC\Bin'
|
||||||
Rebuild target 'project'
|
Rebuild target 'project'
|
||||||
compiling rf433_tx_app.c...
|
|
||||||
assembling startup_stm32f103xb.s...
|
assembling startup_stm32f103xb.s...
|
||||||
compiling spi.c...
|
|
||||||
compiling systick.c...
|
|
||||||
compiling main.c...
|
|
||||||
compiling stm32f1xx_it.c...
|
|
||||||
compiling rf433_rx_app.c...
|
compiling rf433_rx_app.c...
|
||||||
..\Core\Src\rf433_rx_app.c(23): warning: #188-D: enumerated type mixed with another type
|
compiling main.c...
|
||||||
static rf433_rx_app_t g_rx_app = {0};
|
compiling spi.c...
|
||||||
..\Core\Src\rf433_rx_app.c: 1 warning, 0 errors
|
|
||||||
compiling usart.c...
|
|
||||||
compiling gpio.c...
|
compiling gpio.c...
|
||||||
|
compiling cmd_parser.c...
|
||||||
|
compiling systick.c...
|
||||||
|
compiling stm32f1xx_it.c...
|
||||||
|
compiling usart.c...
|
||||||
|
compiling rf433_tx_app.c...
|
||||||
|
..\Core\Src\rf433_tx_app.c(28): warning: #188-D: enumerated type mixed with another type
|
||||||
|
static rf433_tx_app_t g_tx_app = {0};
|
||||||
|
..\Core\Src\rf433_tx_app.c: 1 warning, 0 errors
|
||||||
compiling stm32f1xx_hal_gpio_ex.c...
|
compiling stm32f1xx_hal_gpio_ex.c...
|
||||||
compiling stm32f1xx_hal.c...
|
compiling relay_control.c...
|
||||||
compiling stm32f1xx_hal_spi.c...
|
|
||||||
compiling stm32f1xx_hal_rcc.c...
|
|
||||||
compiling stm32f1xx_hal_msp.c...
|
compiling stm32f1xx_hal_msp.c...
|
||||||
compiling stm32f1xx_hal_rcc_ex.c...
|
compiling io_monitor.c...
|
||||||
compiling stm32f1xx_hal_gpio.c...
|
compiling stm32f1xx_hal.c...
|
||||||
compiling stm32f1xx_hal_flash.c...
|
compiling uart2_print.c...
|
||||||
compiling stm32f1xx_hal_tim.c...
|
compiling stm32f1xx_hal_spi.c...
|
||||||
compiling stm32f1xx_hal_pwr.c...
|
compiling stm32f1xx_hal_pwr.c...
|
||||||
compiling stm32f1xx_hal_cortex.c...
|
compiling stm32f1xx_hal_cortex.c...
|
||||||
|
compiling stm32f1xx_hal_gpio.c...
|
||||||
|
compiling stm32f1xx_hal_rcc.c...
|
||||||
|
compiling stm32f1xx_hal_flash.c...
|
||||||
|
compiling stm32f1xx_hal_rcc_ex.c...
|
||||||
compiling stm32f1xx_hal_dma.c...
|
compiling stm32f1xx_hal_dma.c...
|
||||||
compiling stm32f1xx_hal_exti.c...
|
compiling stm32f1xx_hal_tim.c...
|
||||||
compiling stm32f1xx_hal_flash_ex.c...
|
compiling stm32f1xx_hal_flash_ex.c...
|
||||||
compiling stm32f1xx_hal_tim_ex.c...
|
|
||||||
compiling system_stm32f1xx.c...
|
|
||||||
compiling rf433.c...
|
compiling rf433.c...
|
||||||
..\Driver_RF433\Src\rf433.c(208): warning: #188-D: enumerated type mixed with another type
|
..\Driver_RF433\Src\rf433.c(209): warning: #188-D: enumerated type mixed with another type
|
||||||
ret = rf433_set_config(&rf433_current_config);
|
ret = rf433_set_config(&rf433_current_config);
|
||||||
..\Driver_RF433\Src\rf433.c(212): warning: #188-D: enumerated type mixed with another type
|
..\Driver_RF433\Src\rf433.c(213): warning: #188-D: enumerated type mixed with another type
|
||||||
return ret;
|
return ret;
|
||||||
..\Driver_RF433\Src\rf433.c(98): warning: #177-D: function "rf433_send_request_command" was declared but never referenced
|
..\Driver_RF433\Src\rf433.c(99): warning: #177-D: function "rf433_send_request_command" was declared but never referenced
|
||||||
static void rf433_send_request_command(rf433_request_cmd_t cmd)
|
static void rf433_send_request_command(rf433_request_cmd_t cmd)
|
||||||
..\Driver_RF433\Src\rf433.c(131): warning: #177-D: function "rf433_response_command_check" was declared but never referenced
|
..\Driver_RF433\Src\rf433.c(132): warning: #177-D: function "rf433_response_command_check" was declared but never referenced
|
||||||
static bool rf433_response_command_check(rf433_request_cmd_t cmd, uint8_t *buffer, uint8_t length)
|
static bool rf433_response_command_check(rf433_request_cmd_t cmd, uint8_t *buffer, uint8_t length)
|
||||||
..\Driver_RF433\Src\rf433.c: 4 warnings, 0 errors
|
..\Driver_RF433\Src\rf433.c: 4 warnings, 0 errors
|
||||||
compiling rf433_hal.c...
|
compiling stm32f1xx_hal_exti.c...
|
||||||
|
compiling system_stm32f1xx.c...
|
||||||
|
compiling stm32f1xx_hal_tim_ex.c...
|
||||||
compiling stm32f1xx_hal_uart.c...
|
compiling stm32f1xx_hal_uart.c...
|
||||||
|
compiling rf433_hal.c...
|
||||||
linking...
|
linking...
|
||||||
Program Size: Code=10204 RO-data=408 RW-data=64 ZI-data=3416
|
Program Size: Code=16622 RO-data=478 RW-data=152 ZI-data=3768
|
||||||
FromELF: creating hex file...
|
FromELF: creating hex file...
|
||||||
"project\project.axf" - 0 Error(s), 5 Warning(s).
|
"project\project.axf" - 0 Error(s), 5 Warning(s).
|
||||||
|
|
||||||
@ -94,7 +98,7 @@ Package Vendor: Keil
|
|||||||
|
|
||||||
* Component: ARM::CMSIS:CORE@6.1.1
|
* Component: ARM::CMSIS:CORE@6.1.1
|
||||||
Include file: CMSIS/Core/Include/tz_context.h
|
Include file: CMSIS/Core/Include/tz_context.h
|
||||||
Build Time Elapsed: 00:00:12
|
Build Time Elapsed: 00:00:20
|
||||||
</pre>
|
</pre>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -9,6 +9,10 @@
|
|||||||
"project\usart.o"
|
"project\usart.o"
|
||||||
"project\stm32f1xx_it.o"
|
"project\stm32f1xx_it.o"
|
||||||
"project\stm32f1xx_hal_msp.o"
|
"project\stm32f1xx_hal_msp.o"
|
||||||
|
"project\cmd_parser.o"
|
||||||
|
"project\io_monitor.o"
|
||||||
|
"project\relay_control.o"
|
||||||
|
"project\uart2_print.o"
|
||||||
"project\stm32f1xx_hal_gpio_ex.o"
|
"project\stm32f1xx_hal_gpio_ex.o"
|
||||||
"project\stm32f1xx_hal_spi.o"
|
"project\stm32f1xx_hal_spi.o"
|
||||||
"project\stm32f1xx_hal.o"
|
"project\stm32f1xx_hal.o"
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -32,8 +32,10 @@ I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
|||||||
I (../Drivers/CMSIS/Include/core_cm3.h)(0x69AAA0BA)
|
I (../Drivers/CMSIS/Include/core_cm3.h)(0x69AAA0BA)
|
||||||
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
||||||
I (../Drivers/CMSIS/Include/cmsis_version.h)(0x69AAA0BA)
|
I (../Drivers/CMSIS/Include/cmsis_version.h)(0x69AAA0BA)
|
||||||
I (../Drivers/CMSIS/Include/cmsis_compiler.h)(0x69AAA0BA)
|
I (../Drivers/CMSIS/Include/cmsis_compiler.h)(0x69AAA0BA)
|
||||||
I (../Drivers/CMSIS/Include/cmsis_armcc.h)(0x69AAA0BA)
|
I (../Drivers/CMSIS/Include/cmsis_armcc.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h)(0x69AAA0CD)
|
||||||
I (C:\Keil_v5\ARM\ARMCC\include\stddef.h)(0x5F63877C)
|
I (C:\Keil_v5\ARM\ARMCC\include\stddef.h)(0x5F63877C)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h)(0x69AAA0CD)
|
||||||
@ -66,9 +68,9 @@ I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
|||||||
-I.\RTE\_project
|
-I.\RTE\_project
|
||||||
|
|
||||||
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
||||||
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
|
||||||
I (C:\Keil_v5\ARM\ARMCC\include\stdbool.h)(0x5F63877C)
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include
|
||||||
I (../Core/Inc/main.h)(0x69C35425)
|
|
||||||
-D__UVISION_VERSION="543" -DSTM32F10X_MD -D_RTE_ -DUSE_HAL_DRIVER -DSTM32F103xB
|
-D__UVISION_VERSION="543" -DSTM32F10X_MD -D_RTE_ -DUSE_HAL_DRIVER -DSTM32F103xB
|
||||||
|
|
||||||
-o project\rf433_tx_app.o --omf_browse project\rf433_tx_app.crf --depend project\rf433_tx_app.d)
|
-o project\rf433_tx_app.o --omf_browse project\rf433_tx_app.crf --depend project\rf433_tx_app.d)
|
||||||
@ -102,9 +104,14 @@ I (../Core/Inc/spi.h)(0x69C35422)
|
|||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h)(0x69AAA0CD)
|
||||||
-IC:\Users\xtell\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
||||||
-D__UVISION_VERSION="543" -DSTM32F10X_MD -D_RTE_ -DUSE_HAL_DRIVER -DSTM32F103xB
|
I (C:\Keil_v5\ARM\ARMCC\include\stdio.h)(0x5F63877C)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\string.h)(0x5F63878A)
|
||||||
|
I (../Core/Inc/uart2_print.h)(0x69C50FF9)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdarg.h)(0x5F63877C)
|
||||||
|
F (../Core/Src/main.c)(0x69C50991)(--c99 -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/u8g2Lib/inc -I ../Middlewares/MultMenu/application -I ../Middlewares/MultMenu/disp -I ../Middlewares/MultMenu/menu -I ../Driver_RF433 -I ../Driver_RF433/Inc -I ../Driver_RF433/Src
|
||||||
|
|
||||||
-I.\RTE\_project
|
-I.\RTE\_project
|
||||||
|
|
||||||
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
||||||
@ -167,7 +174,7 @@ I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
|||||||
|
|
||||||
-o project\gpio.o --omf_browse project\gpio.crf --depend project\gpio.d)
|
-o project\gpio.o --omf_browse project\gpio.crf --depend project\gpio.d)
|
||||||
I (../Core/Inc/gpio.h)(0x665D64E1)
|
I (../Core/Inc/gpio.h)(0x665D64E1)
|
||||||
I (../Core/Inc/main.h)(0x69C35425)
|
I (../Core/Inc/main.h)(0x69C35425)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h)(0x69AAA0CD)
|
||||||
I (../Core/Inc/stm32f1xx_hal_conf.h)(0x69C35424)
|
I (../Core/Inc/stm32f1xx_hal_conf.h)(0x69C35424)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h)(0x69AAA0CD)
|
||||||
@ -260,6 +267,119 @@ I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
|||||||
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
||||||
I (../Drivers/CMSIS/Include/cmsis_version.h)(0x69AAA0BA)
|
I (../Drivers/CMSIS/Include/cmsis_version.h)(0x69AAA0BA)
|
||||||
I (../Drivers/CMSIS/Include/cmsis_compiler.h)(0x69AAA0BA)
|
I (../Drivers/CMSIS/Include/cmsis_compiler.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Include/cmsis_armcc.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h)(0x69AAA0CD)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stddef.h)(0x5F63877C)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdbool.h)(0x5F63877C)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdio.h)(0x5F63877C)
|
||||||
|
I (../Driver_RF433/Inc/rf433_hal.h)(0x69C2716B)
|
||||||
|
F (../Core/Src/stm32f1xx_it.c)(0x69C35423)(--c99 -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/u8g2Lib/inc -I ../Middlewares/MultMenu/application -I ../Middlewares/MultMenu/disp -I ../Middlewares/MultMenu/menu -I ../Driver_RF433 -I ../Driver_RF433/Inc -I ../Driver_RF433/Src
|
||||||
|
|
||||||
|
-I.\RTE\_project
|
||||||
|
|
||||||
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
||||||
|
|
||||||
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include
|
||||||
|
|
||||||
|
-D__UVISION_VERSION="543" -DSTM32F10X_MD -D_RTE_ -DUSE_HAL_DRIVER -DSTM32F103xB
|
||||||
|
|
||||||
|
-o project\stm32f1xx_it.o --omf_browse project\stm32f1xx_it.crf --depend project\stm32f1xx_it.d)
|
||||||
|
I (../Core/Inc/main.h)(0x69C35425)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h)(0x69AAA0CD)
|
||||||
|
I (../Core/Inc/stm32f1xx_hal_conf.h)(0x69C35424)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/CMSIS/Include/core_cm3.h)(0x69AAA0BA)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
||||||
|
I (../Drivers/CMSIS/Include/cmsis_version.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Include/cmsis_compiler.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Include/cmsis_armcc.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h)(0x69AAA0CD)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stddef.h)(0x5F63877C)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdbool.h)(0x5F63877C)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdio.h)(0x5F63877C)
|
||||||
|
I (../Core/Inc/stm32f1xx_it.h)(0x69C35423)
|
||||||
|
F (../Core/Src/stm32f1xx_hal_msp.c)(0x665D64E3)(--c99 -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/u8g2Lib/inc -I ../Middlewares/MultMenu/application -I ../Middlewares/MultMenu/disp -I ../Middlewares/MultMenu/menu -I ../Driver_RF433 -I ../Driver_RF433/Inc -I ../Driver_RF433/Src
|
||||||
|
|
||||||
|
-I.\RTE\_project
|
||||||
|
|
||||||
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
||||||
|
|
||||||
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include
|
||||||
|
|
||||||
|
-D__UVISION_VERSION="543" -DSTM32F10X_MD -D_RTE_ -DUSE_HAL_DRIVER -DSTM32F103xB
|
||||||
|
|
||||||
|
-o project\stm32f1xx_hal_msp.o --omf_browse project\stm32f1xx_hal_msp.crf --depend project\stm32f1xx_hal_msp.d)
|
||||||
|
I (../Core/Inc/main.h)(0x69C35425)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h)(0x69AAA0CD)
|
||||||
|
I (../Core/Inc/stm32f1xx_hal_conf.h)(0x69C35424)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/CMSIS/Include/core_cm3.h)(0x69AAA0BA)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
||||||
|
I (../Drivers/CMSIS/Include/cmsis_version.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Include/cmsis_compiler.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Include/cmsis_armcc.h)(0x69AAA0BA)
|
||||||
|
I (../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h)(0x69AAA0CD)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stddef.h)(0x5F63877C)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdbool.h)(0x5F63877C)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdio.h)(0x5F63877C)
|
||||||
|
F (..\Core\Src\cmd_parser.c)(0x69C518F0)(--c99 -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/u8g2Lib/inc -I ../Middlewares/MultMenu/application -I ../Middlewares/MultMenu/disp -I ../Middlewares/MultMenu/menu -I ../Driver_RF433 -I ../Driver_RF433/Inc -I ../Driver_RF433/Src
|
||||||
|
|
||||||
|
-I.\RTE\_project
|
||||||
|
|
||||||
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
||||||
|
|
||||||
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include
|
||||||
|
|
||||||
|
-D__UVISION_VERSION="543" -DSTM32F10X_MD -D_RTE_ -DUSE_HAL_DRIVER -DSTM32F103xB
|
||||||
|
|
||||||
|
-o project\cmd_parser.o --omf_browse project\cmd_parser.crf --depend project\cmd_parser.d)
|
||||||
|
I (../Core/Inc/cmd_parser.h)(0x69C50FF7)
|
||||||
|
I (C:\Keil_v5\ARM\ARMCC\include\stdint.h)(0x5F63877C)
|
||||||
I (C:\Keil_v5\ARM\ARMCC\include\stdbool.h)(0x5F63877C)
|
I (C:\Keil_v5\ARM\ARMCC\include\stdbool.h)(0x5F63877C)
|
||||||
I (../Core/Inc/uart2_print.h)(0x69C50FF9)
|
I (../Core/Inc/uart2_print.h)(0x69C50FF9)
|
||||||
I (C:\Keil_v5\ARM\ARMCC\include\stdarg.h)(0x5F63877C)
|
I (C:\Keil_v5\ARM\ARMCC\include\stdarg.h)(0x5F63877C)
|
||||||
@ -692,13 +812,14 @@ I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h)(0x69AAA0CD)
|
|||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h)(0x69AAA0CD)
|
||||||
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h)(0x69AAA0CD)
|
||||||
F (../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c)(0x69AAA0CD)(--c99 -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/u8g2Lib/inc -I ../Middlewares/MultMenu/application -I ../Middlewares/MultMenu/disp -I ../Middlewares/MultMenu/menu -I ../Driver_RF433 -I ../Driver_RF433/Inc -I ../Driver_RF433/Src
|
F (../Drivers/STM32F1xx_HAL_Driver/Src/stm32f1xx_hal_pwr.c)(0x69AAA0CD)(--c99 -c --cpu Cortex-M3 -D__MICROLIB -g -O0 --apcs=interwork --split_sections -I ../Core/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc -I ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy -I ../Drivers/CMSIS/Device/ST/STM32F1xx/Include -I ../Drivers/CMSIS/Include -I ../Middlewares/u8g2Lib/inc -I ../Middlewares/MultMenu/application -I ../Middlewares/MultMenu/disp -I ../Middlewares/MultMenu/menu -I ../Driver_RF433 -I ../Driver_RF433/Inc -I ../Driver_RF433/Src
|
||||||
|
|
||||||
-I.\RTE\_project
|
-I.\RTE\_project
|
||||||
|
|
||||||
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\ARM\CMSIS\6.2.0\CMSIS\Core\Include
|
||||||
|
|
||||||
-IC:\Users\xtell\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include
|
-IC:\Users\xtell\AppData\Local\Arm\Packs\Keil\STM32F1xx_DFP\2.4.1\Device\Include
|
||||||
@ -758,5 +879,5 @@ I (C:\Keil_v5\ARM\ARMCC\include\stdio.h)(0x5F63877C)
|
|||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h)(0x69AAA0CD)
|
||||||
I (C:\Keil_v5\ARM\ARMCC\include\stddef.h)(0x5F63877C)
|
I (C:\Keil_v5\ARM\ARMCC\include\stddef.h)(0x5F63877C)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h)(0x69AAA0CD)
|
||||||
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h)(0x69AAA0CD)
|
I (../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h)(0x69AAA0CD)
|
||||||
|
|||||||
BIN
MDK-ARM/project/relay_control.crf
Normal file
BIN
MDK-ARM/project/relay_control.crf
Normal file
Binary file not shown.
34
MDK-ARM/project/relay_control.d
Normal file
34
MDK-ARM/project/relay_control.d
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
project\relay_control.o: ..\Core\Src\relay_control.c
|
||||||
|
project\relay_control.o: ../Core/Inc/relay_control.h
|
||||||
|
project\relay_control.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
||||||
|
project\relay_control.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
||||||
|
project\relay_control.o: ../Core/Inc/uart2_print.h
|
||||||
|
project\relay_control.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdarg.h
|
||||||
|
project\relay_control.o: ../Core/Inc/main.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\relay_control.o: ../Core/Inc/stm32f1xx_hal_conf.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
|
||||||
|
project\relay_control.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
|
||||||
|
project\relay_control.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
|
||||||
|
project\relay_control.o: ../Drivers/CMSIS/Include/core_cm3.h
|
||||||
|
project\relay_control.o: ../Drivers/CMSIS/Include/cmsis_version.h
|
||||||
|
project\relay_control.o: ../Drivers/CMSIS/Include/cmsis_compiler.h
|
||||||
|
project\relay_control.o: ../Drivers/CMSIS/Include/cmsis_armcc.h
|
||||||
|
project\relay_control.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
|
||||||
|
project\relay_control.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stddef.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
|
||||||
|
project\relay_control.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
|
||||||
|
project\relay_control.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
|
||||||
BIN
MDK-ARM/project/relay_control.o
Normal file
BIN
MDK-ARM/project/relay_control.o
Normal file
Binary file not shown.
Binary file not shown.
@ -5,6 +5,7 @@ project\rf433.o: ../Driver_RF433/Inc/rf433_hal.h
|
|||||||
project\rf433.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
project\rf433.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
||||||
project\rf433.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
project\rf433.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
||||||
project\rf433.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
|
project\rf433.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
|
||||||
|
project\rf433.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
|
||||||
project\rf433.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
project\rf433.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
project\rf433.o: ../Core/Inc/stm32f1xx_hal_conf.h
|
project\rf433.o: ../Core/Inc/stm32f1xx_hal_conf.h
|
||||||
project\rf433.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
|
project\rf433.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,36 +1,2 @@
|
|||||||
project\rf433_rx_app.o: ..\Core\Src\rf433_rx_app.c
|
project\rf433_rx_app.o: ..\Core\Src\rf433_rx_app.c
|
||||||
project\rf433_rx_app.o: ../Driver_RF433/Inc/rf433_config.h
|
project\rf433_rx_app.o: ../Driver_RF433/Inc/rf433_config.h
|
||||||
project\rf433_rx_app.o: ../Core/Inc/rf433_rx_app.h
|
|
||||||
project\rf433_rx_app.o: ../Driver_RF433/Inc/rf433.h
|
|
||||||
project\rf433_rx_app.o: ../Driver_RF433/Inc/rf433_hal.h
|
|
||||||
project\rf433_rx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
|
||||||
project\rf433_rx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
|
||||||
project\rf433_rx_app.o: ../Core/Inc/main.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
|
||||||
project\rf433_rx_app.o: ../Core/Inc/stm32f1xx_hal_conf.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/CMSIS/Include/core_cm3.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/CMSIS/Include/cmsis_version.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/CMSIS/Include/cmsis_compiler.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/CMSIS/Include/cmsis_armcc.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
|
|
||||||
project\rf433_rx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stddef.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
|
|
||||||
project\rf433_rx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
|
|
||||||
project\rf433_rx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
|
|
||||||
project\rf433_rx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
|
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@ -1,2 +1,38 @@
|
|||||||
project\rf433_tx_app.o: ..\Core\Src\rf433_tx_app.c
|
project\rf433_tx_app.o: ..\Core\Src\rf433_tx_app.c
|
||||||
project\rf433_tx_app.o: ../Driver_RF433/Inc/rf433_config.h
|
project\rf433_tx_app.o: ../Driver_RF433/Inc/rf433_config.h
|
||||||
|
project\rf433_tx_app.o: ../Core/Inc/rf433_tx_app.h
|
||||||
|
project\rf433_tx_app.o: ../Driver_RF433/Inc/rf433.h
|
||||||
|
project\rf433_tx_app.o: ../Driver_RF433/Inc/rf433_hal.h
|
||||||
|
project\rf433_tx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
||||||
|
project\rf433_tx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
||||||
|
project\rf433_tx_app.o: ../Core/Inc/main.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\rf433_tx_app.o: ../Core/Inc/stm32f1xx_hal_conf.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/CMSIS/Include/core_cm3.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/CMSIS/Include/cmsis_version.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/CMSIS/Include/cmsis_compiler.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/CMSIS/Include/cmsis_armcc.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
|
||||||
|
project\rf433_tx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stddef.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
|
||||||
|
project\rf433_tx_app.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
|
||||||
|
project\rf433_tx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
|
||||||
|
project\rf433_tx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
|
||||||
|
project\rf433_tx_app.o: ../Core/Inc/uart2_print.h
|
||||||
|
project\rf433_tx_app.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdarg.h
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
BIN
MDK-ARM/project/uart2_print.crf
Normal file
BIN
MDK-ARM/project/uart2_print.crf
Normal file
Binary file not shown.
35
MDK-ARM/project/uart2_print.d
Normal file
35
MDK-ARM/project/uart2_print.d
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
project\uart2_print.o: ..\Core\Src\uart2_print.c
|
||||||
|
project\uart2_print.o: ../Core/Inc/uart2_print.h
|
||||||
|
project\uart2_print.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdint.h
|
||||||
|
project\uart2_print.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdarg.h
|
||||||
|
project\uart2_print.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdbool.h
|
||||||
|
project\uart2_print.o: ../Core/Inc/usart.h
|
||||||
|
project\uart2_print.o: ../Core/Inc/main.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\uart2_print.o: ../Core/Inc/stm32f1xx_hal_conf.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_def.h
|
||||||
|
project\uart2_print.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f1xx.h
|
||||||
|
project\uart2_print.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/stm32f103xb.h
|
||||||
|
project\uart2_print.o: ../Drivers/CMSIS/Include/core_cm3.h
|
||||||
|
project\uart2_print.o: ../Drivers/CMSIS/Include/cmsis_version.h
|
||||||
|
project\uart2_print.o: ../Drivers/CMSIS/Include/cmsis_compiler.h
|
||||||
|
project\uart2_print.o: ../Drivers/CMSIS/Include/cmsis_armcc.h
|
||||||
|
project\uart2_print.o: ../Drivers/CMSIS/Device/ST/STM32F1xx/Include/system_stm32f1xx.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/Legacy/stm32_hal_legacy.h
|
||||||
|
project\uart2_print.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stddef.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_rcc_ex.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_gpio_ex.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_exti.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_dma_ex.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_cortex.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_flash_ex.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_pwr.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_spi.h
|
||||||
|
project\uart2_print.o: ../Drivers/STM32F1xx_HAL_Driver/Inc/stm32f1xx_hal_uart.h
|
||||||
|
project\uart2_print.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\stdio.h
|
||||||
|
project\uart2_print.o: C:\Keil_v5\ARM\ARMCC\Bin\..\include\string.h
|
||||||
BIN
MDK-ARM/project/uart2_print.o
Normal file
BIN
MDK-ARM/project/uart2_print.o
Normal file
Binary file not shown.
Binary file not shown.
Binary file not shown.
490
code_review_report.md
Normal file
490
code_review_report.md
Normal file
@ -0,0 +1,490 @@
|
|||||||
|
# STM32F103 应用层代码深度审查报告
|
||||||
|
|
||||||
|
## 1. 审查概述
|
||||||
|
|
||||||
|
**审查范围**:
|
||||||
|
- `uart2_print.c/.h` - UART2调试打印模块(环形缓冲区+中断发送)
|
||||||
|
- `io_monitor.c/.h` - 四路DI状态监控与去抖模块
|
||||||
|
- `cmd_parser.c/.h` - ASCII指令解析状态机
|
||||||
|
- `relay_control.c/.h` - 继电器控制模块
|
||||||
|
|
||||||
|
**审查方法**:静态代码分析 + 嵌入式系统安全规范检查
|
||||||
|
|
||||||
|
**主要发现**:
|
||||||
|
- 🔴 **高危问题**:4个(中断安全、缓冲区竞态、状态机边界)
|
||||||
|
- 🟡 **中危问题**:5个(参数校验、逻辑缺陷)
|
||||||
|
- 🟢 **低危/建议**:4个(代码健壮性)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. 详细问题清单
|
||||||
|
|
||||||
|
### 2.1 uart2_print 模块(最严重)
|
||||||
|
|
||||||
|
#### 🔴 **[高危-1] UART2_Print_Send 中 is_sending 检查存在竞态条件**
|
||||||
|
|
||||||
|
**代码位置**:`uart2_print.c` 第73-74行
|
||||||
|
|
||||||
|
```c
|
||||||
|
void UART2_Print_Send(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
// ... 写入缓冲区(已保护)...
|
||||||
|
__enable_irq(); // ← 第71行:保护区结束
|
||||||
|
|
||||||
|
if (written > 0 && !tx_ring.is_sending) { // ← 第73行:非原子检查!
|
||||||
|
UART2_Print_Task(); // ← 第74行
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险分析**:
|
||||||
|
- **触发条件**:中断正好在 `__enable_irq()` 之后、`UART2_Print_Task()` 调用之前发生
|
||||||
|
- **触发场景**:
|
||||||
|
1. 线程A调用 `UART2_Print_Send`,数据已写入缓冲区
|
||||||
|
2. `is_sending = false`,进入 if 块
|
||||||
|
3. 中断触发,`HAL_UART_TxCpltCallback` 执行,设置 `is_sending = true`,调用 `UART2_Print_Task` 发送一字节
|
||||||
|
4. `UART2_Print_Task` 再次设置 `is_sending = true`
|
||||||
|
5. 线程A继续执行,调用 `UART2_Print_Task()`(但此时 `is_sending = true`,直接返回)
|
||||||
|
6. **结果**:新写入的字节不会被发送,直到后续再次有数据写入
|
||||||
|
|
||||||
|
**后果**:调试信息丢失,尤其在高频日志输出时部分数据"静默消失"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 🔴 **[高危-2] UART2_Print_Task 完全缺乏中断保护**
|
||||||
|
|
||||||
|
**代码位置**:`uart2_print.c` 第107-122行
|
||||||
|
|
||||||
|
```c
|
||||||
|
void UART2_Print_Task(void)
|
||||||
|
{
|
||||||
|
if (tx_ring.is_sending) { // ← 非原子读取
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx_ring.tail == tx_ring.head) { // ← 非原子读取
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t byte = tx_ring.buffer[tx_ring.tail]; // ← 读取数据
|
||||||
|
tx_ring.tail = (tx_ring.tail + 1) % UART2_TX_BUFFER_SIZE; // ← 更新索引(无保护)
|
||||||
|
tx_ring.is_sending = true; // ← 非原子写入
|
||||||
|
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &byte, 1);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险分析**:
|
||||||
|
- **触发条件**:`UART2_Print_Task` 在主循环中被调用,同时 UART TX 中断发生
|
||||||
|
- **触发场景**:
|
||||||
|
1. 主循环调用 `UART2_Print_Task`,通过所有检查
|
||||||
|
2. 读取 `byte = buffer[tail]`,`tail` 已更新,但 `is_sending` 尚未置位
|
||||||
|
3. UART TX 完成中断触发,`HAL_UART_TxCpltCallback` 执行
|
||||||
|
4. 回调检查 `tail != head`(已变化),调用 `UART2_Print_Task`
|
||||||
|
5. 同一字节被重复发送
|
||||||
|
|
||||||
|
**后果**:数据重复发送,接收方收到重复字符;严重时可能导致协议解析错误
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 🔴 **[高危-3] 环形缓冲区容量计算错误 - 差一错误 (Off-by-one)**
|
||||||
|
|
||||||
|
**代码位置**:
|
||||||
|
- `uart2_print.c` 第142-148行 - `Available` 函数
|
||||||
|
- `uart2_print.h` 第26行 - 缓冲区大小定义
|
||||||
|
|
||||||
|
```c
|
||||||
|
uint16_t UART2_Print_Available(void)
|
||||||
|
{
|
||||||
|
uint16_t used;
|
||||||
|
|
||||||
|
if (tx_ring.head >= tx_ring.tail) {
|
||||||
|
used = tx_ring.head - tx_ring.tail;
|
||||||
|
} else {
|
||||||
|
used = UART2_TX_BUFFER_SIZE - tx_ring.tail + tx_ring.head;
|
||||||
|
}
|
||||||
|
|
||||||
|
return UART2_TX_BUFFER_SIZE - used - 1; // ← 这里减1了!
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**:当 `head = tail` 时,`used = 0`,返回 `256 - 0 - 1 = 255`。但环形缓冲区的空状态和满状态都是 `head == tail`,无法区分!
|
||||||
|
|
||||||
|
**正确做法**:存储一个 `count` 变量,或使用 `head` 和 `tail` 之间的固定一个空位来区分满/空状态。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 🟡 **[中危-4] UART2_Print_Printf 返回值处理缺陷**
|
||||||
|
|
||||||
|
**代码位置**:`uart2_print.c` 第96-104行
|
||||||
|
|
||||||
|
```c
|
||||||
|
int len = vsnprintf(buffer, sizeof(buffer), fmt, args);
|
||||||
|
va_end(args);
|
||||||
|
|
||||||
|
if (len > 0) { // ← 问题在这里
|
||||||
|
if (len >= (int)sizeof(buffer)) {
|
||||||
|
len = sizeof(buffer) - 1;
|
||||||
|
}
|
||||||
|
UART2_Print_Send((const uint8_t *)buffer, len);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**:`vsnprintf` 返回值 `> 0` 表示需要写入的字符数(不包括 null)。但如果格式化结果为空字符串(返回0),则不会发送。虽然这通常不是问题,但逻辑上应使用 `len >= 0` 或 `len != -1`。
|
||||||
|
|
||||||
|
**风险**:低 - 基本不会触发,但不够健壮
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.2 io_monitor 模块
|
||||||
|
|
||||||
|
#### 🟡 **[中危-5] 去抖初始化可能遗漏第一帧变化检测**
|
||||||
|
|
||||||
|
**代码位置**:`io_monitor.c` 第74-89行
|
||||||
|
|
||||||
|
```c
|
||||||
|
void IO_Monitor_Init(void)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < IO_CHANNEL_COUNT; i++) {
|
||||||
|
io_channel_t *ch = &di_channels[i];
|
||||||
|
|
||||||
|
ch->current_state = HAL_GPIO_ReadPin(ch->port, ch->pin) ? 1 : 0;
|
||||||
|
ch->last_raw_state = ch->current_state;
|
||||||
|
ch->debounce_counter = IO_DEBOUNCE_COUNT; // ← 初始化为3
|
||||||
|
ch->change_count = 0;
|
||||||
|
}
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**风险分析**:
|
||||||
|
- `debounce_counter = IO_DEBOUNCE_COUNT (3)`
|
||||||
|
- 在第一次 `IO_Monitor_Task` 调用时,如果 `raw_state != last_raw_state`
|
||||||
|
- `debounce_counter` 被设为 0
|
||||||
|
- 需要再检测到连续 3 次相同状态才会确认变化
|
||||||
|
- **问题**:初始化时如果IO状态刚好处于变化沿附近,可能导致第一次变化事件被延迟最多 30ms(3×10ms)才上报
|
||||||
|
|
||||||
|
**风险**:低 - 仅影响初始化后第一次变化检测的响应速度
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 🟢 **[建议-1] send_di_event 可被中断安全调用但存在嵌套风险**
|
||||||
|
|
||||||
|
**代码位置**:`io_monitor.c` 第58-72行
|
||||||
|
|
||||||
|
`send_di_event` 调用 `UART2_Print_String`,而 `UART2_Print_String` 调用 `UART2_Print_Send`,后者使用 `__disable_irq()`。
|
||||||
|
|
||||||
|
**潜在问题**:如果 `IO_Monitor_Task` 在中断中调用,而此时 UART 发送中断发生,可能导致死锁(虽然STM32F103不太可能发生,因为UART中断优先级通常较高)。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.3 cmd_parser 模块
|
||||||
|
|
||||||
|
#### 🔴 **[高危-6] 状态机边界条件处理不完善 - 逗号/星号丢失**
|
||||||
|
|
||||||
|
**代码位置**:`cmd_parser.c` 第231-272行
|
||||||
|
|
||||||
|
```c
|
||||||
|
case PARSE_PARAM1:
|
||||||
|
if (byte == ',') {
|
||||||
|
ctx.frame.param1[ctx.field_index] = '\0';
|
||||||
|
ctx.state = PARSE_PARAM2;
|
||||||
|
ctx.field_index = 0;
|
||||||
|
} else if (byte == '*') {
|
||||||
|
// ... 类似处理 ...
|
||||||
|
} else if (is_valid_param_char(byte)) {
|
||||||
|
if (ctx.field_index < PARAM_MAX_LEN - 1) { // ← 检查的是 field_index
|
||||||
|
ctx.frame.param1[ctx.field_index++] = byte;
|
||||||
|
// ...
|
||||||
|
} else {
|
||||||
|
ctx.error_count++;
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题分析**:
|
||||||
|
- `PARAM_MAX_LEN = 32`,数组大小确实是 32 字节
|
||||||
|
- 但检查条件是 `ctx.field_index < PARAM_MAX_LEN - 1` (即 < 31)
|
||||||
|
- **当 `field_index = 31` 时**,下一个字符如果是逗号或星号:
|
||||||
|
- 不是有效参数字符,进入 else 分支
|
||||||
|
- `error_count++` 并重置解析器
|
||||||
|
- **触发条件**:发送格式为 `$DI,ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789*XX\r\n`(31个字符的参数)
|
||||||
|
|
||||||
|
**风险**:长度接近31的参数帧会被错误拒绝,虽然这种长参数在实际应用中罕见。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 🟡 **[中危-7] 超时检测逻辑存在边界情况**
|
||||||
|
|
||||||
|
**代码位置**:`cmd_parser.c` 第189-197行
|
||||||
|
|
||||||
|
```c
|
||||||
|
void CmdParser_FeedByte(uint8_t byte, uint32_t current_tick)
|
||||||
|
{
|
||||||
|
if (ctx.state != PARSE_IDLE) {
|
||||||
|
if (current_tick - ctx.last_rx_tick > PARSE_TIMEOUT_MS) { // ← 严格大于
|
||||||
|
ctx.error_count++;
|
||||||
|
DEBUG_LOG("Timeout, reset parser");
|
||||||
|
reset_parser();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ctx.last_rx_tick = current_tick; // ← 每个字节都更新
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**:
|
||||||
|
- 如果正好在 `timeout_ms + 1` 时刻收到字节,减去 `last_rx_tick` 等于 `timeout_ms + 1`,会被判定为超时
|
||||||
|
- 然后 `reset_parser()` 被调用,`last_rx_tick` 不会被更新为当前时刻
|
||||||
|
- 如果下一个字节在 `timeout_ms` 内到来,超时计数可能不准确
|
||||||
|
|
||||||
|
**风险**:低 - 仅在精确的时序边界触发
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 🟡 **[中危-8] DI指令参数校验不完善**
|
||||||
|
|
||||||
|
**代码位置**:`cmd_parser.c` 第145-167行
|
||||||
|
|
||||||
|
```c
|
||||||
|
else if (strcmp(frame->cmd, "DI") == 0) {
|
||||||
|
int channel = atoi(frame->param1); // ← atoi 空字符串返回0
|
||||||
|
|
||||||
|
if (channel == 0) {
|
||||||
|
// 返回所有状态
|
||||||
|
}
|
||||||
|
else if (channel >= 1 && channel <= 4) {
|
||||||
|
// 返回指定通道状态
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
send_response_err("PARAM");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**:
|
||||||
|
- `$DI,*` 会被解析为 `channel = 0`(空字符串传给 atoi)
|
||||||
|
- `$DI,0*` 也是 `channel = 0`
|
||||||
|
- 两种格式语义不同,但处理相同
|
||||||
|
|
||||||
|
**风险**:低 - 功能上可能符合预期,但语义不够清晰
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 2.4 relay_control 模块
|
||||||
|
|
||||||
|
#### 🟡 **[中危-9] 继电器ID检查与硬件配置不匹配**
|
||||||
|
|
||||||
|
**代码位置**:
|
||||||
|
- `relay_control.c` 第43-69行
|
||||||
|
- `relay_control.h` 第24行
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define RELAY_COUNT 1 // ← 硬件只有一个继电器
|
||||||
|
#define RELAY_MIN_INTERVAL 100 // ← 但允许ID 1-4
|
||||||
|
|
||||||
|
void Relay_SetState(uint8_t relay_id, bool state)
|
||||||
|
{
|
||||||
|
if (relay_id < 1 || relay_id > RELAY_COUNT) { // ← 检查 > 1 会失败
|
||||||
|
DEBUG_LOG("Invalid relay ID: %d", relay_id);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**:
|
||||||
|
- `RELAY_COUNT = 1`,但允许的 relay_id 范围是 1-4
|
||||||
|
- 如果调用 `Relay_SetState(2, true)`,会被错误拒绝
|
||||||
|
- 与 `cmd_parser.c` 中允许 1-4 的校验逻辑不一致
|
||||||
|
|
||||||
|
**风险**:如果将来扩展到4个继电器但忘记更新 `RELAY_COUNT`,会导致只有第1个继电器工作
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
#### 🟡 **[中危-10] current_state 只支持单个继电器**
|
||||||
|
|
||||||
|
**代码位置**:`relay_control.c` 第29行
|
||||||
|
|
||||||
|
```c
|
||||||
|
static bool current_state = false; // ← 只有一个状态变量
|
||||||
|
```
|
||||||
|
|
||||||
|
**问题**:如果将来扩展到多继电器,`current_state` 无法区分各继电器状态。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. 关键案例详解
|
||||||
|
|
||||||
|
### 📌 案例一(最具代表性):UART2 环形缓冲区竞态条件
|
||||||
|
|
||||||
|
**修改前**(uart2_print.c 第50-76行):
|
||||||
|
|
||||||
|
```c
|
||||||
|
void UART2_Print_Send(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
if (len == 0 || data == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t written = 0;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
uint16_t next = (tx_ring.head + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
|
||||||
|
if (next == tx_ring.tail) {
|
||||||
|
tx_ring.overflow_count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_ring.buffer[tx_ring.head] = data[i];
|
||||||
|
tx_ring.head = next;
|
||||||
|
written++;
|
||||||
|
}
|
||||||
|
__enable_irq(); // ← 保护区结束
|
||||||
|
|
||||||
|
if (written > 0 && !tx_ring.is_sending) { // ← 竞态窗口!
|
||||||
|
UART2_Print_Task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**修改后(推荐方案)**:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void UART2_Print_Send(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
if (len == 0 || data == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t written = 0;
|
||||||
|
bool needs_kickoff = false;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
uint16_t next = (tx_ring.head + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
|
||||||
|
if (next == tx_ring.tail) {
|
||||||
|
tx_ring.overflow_count++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
tx_ring.buffer[tx_ring.head] = data[i];
|
||||||
|
tx_ring.head = next;
|
||||||
|
written++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (written > 0 && !tx_ring.is_sending) {
|
||||||
|
tx_ring.is_sending = true; // ← 在保护区内设置,避免竞态
|
||||||
|
needs_kickoff = true;
|
||||||
|
}
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
if (needs_kickoff) {
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &tx_ring.buffer[tx_ring.tail], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**消除的隐患**:
|
||||||
|
- 将 `is_sending` 标志的设置纳入临界区
|
||||||
|
- 避免了中断和主循环之间的状态检查竞态
|
||||||
|
- 数据发送的"启动"操作完全在主循环侧,中断回调只负责推进 `tail`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### 📌 案例二:UART2_Print_Task 中断保护
|
||||||
|
|
||||||
|
**修改前**(uart2_print.c 第107-122行):
|
||||||
|
|
||||||
|
```c
|
||||||
|
void UART2_Print_Task(void)
|
||||||
|
{
|
||||||
|
if (tx_ring.is_sending) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tx_ring.tail == tx_ring.head) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t byte = tx_ring.buffer[tx_ring.tail];
|
||||||
|
tx_ring.tail = (tx_ring.tail + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
tx_ring.is_sending = true;
|
||||||
|
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &byte, 1);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**修改后**:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void UART2_Print_Task(void)
|
||||||
|
{
|
||||||
|
uint8_t byte;
|
||||||
|
uint16_t current_tail;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
if (tx_ring.is_sending || tx_ring.tail == tx_ring.head) {
|
||||||
|
__enable_irq();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_tail = tx_ring.tail;
|
||||||
|
tx_ring.tail = (tx_ring.tail + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
tx_ring.is_sending = true;
|
||||||
|
byte = tx_ring.buffer[current_tail];
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &byte, 1);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**消除的隐患**:
|
||||||
|
- `tail` 的读取和更新在同一个临界区内完成
|
||||||
|
- 避免了中断回调读取到"部分更新"状态的 `tail` 值
|
||||||
|
- `is_sending` 的设置和 `byte` 的读取分离,确保中断回调不会重复触发发送
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. 总结与建议
|
||||||
|
|
||||||
|
### 整体代码质量评估
|
||||||
|
|
||||||
|
| 维度 | 评分 | 说明 |
|
||||||
|
|------|------|------|
|
||||||
|
| 功能完整性 | ⭐⭐⭐⭐ | 基本功能完整,指令解析逻辑清晰 |
|
||||||
|
| 中断安全 | ⭐⭐ | **存在严重竞态条件,必须修复** |
|
||||||
|
| 边界检查 | ⭐⭐⭐ | 大部分边界有检查,但存在遗漏 |
|
||||||
|
| 可维护性 | ⭐⭐⭐⭐ | 代码结构清晰,注释完善 |
|
||||||
|
| 防御性编程 | ⭐⭐⭐ | 有基本防护,但关键路径需加强 |
|
||||||
|
|
||||||
|
### 必须立即修复的问题(高优先级)
|
||||||
|
|
||||||
|
1. **[高危-1] uart2_print.c `UART2_Print_Send` 竞态条件** - 直接影响数据可靠性和调试能力
|
||||||
|
2. **[高危-2] uart2_print.c `UART2_Print_Task` 缺乏中断保护** - 可能导致数据重复
|
||||||
|
3. **[高危-3] uart2_print.c 环形缓冲区容量计算** - 差一错误影响缓冲区利用率
|
||||||
|
4. **[高危-6] cmd_parser.c 状态机边界处理** - 可能拒绝合法长参数帧
|
||||||
|
|
||||||
|
### 建议后续优化的问题
|
||||||
|
|
||||||
|
5. **[中危-4] UART2_Print_Printf 返回值处理** - 改为 `len >= 0`
|
||||||
|
6. **[中危-5] io_monitor 去抖初始化** - 考虑从 1 而非 DEBOUNCE_COUNT 开始
|
||||||
|
7. **[中危-9] relay_control RELAY_COUNT 宏定义** - 与实际校验逻辑对齐
|
||||||
|
8. **[建议-1] 考虑使用 CMSIS_OS2 或 FreeRTOS** - 如果系统复杂度增加
|
||||||
|
|
||||||
|
### 最重要的3-5条改进建议
|
||||||
|
|
||||||
|
1. **为环形缓冲区操作引入完整的临界区保护**:所有涉及 `head`、`tail`、`is_sending` 的读写操作必须放在同一个 `__disable_irq()/__enable_irq()` 保护块内。
|
||||||
|
|
||||||
|
2. **重新设计环形缓冲区满/空判断机制**:使用显式的 `count` 变量或"保留一位"策略来区分 `head == tail` 的两种语义。
|
||||||
|
|
||||||
|
3. **为 `cmd_parser.c` 的 `vsnprintf` 缓冲区添加保护**:校验和计算应使用固定长度,避免因消息格式变化导致截断。
|
||||||
|
|
||||||
|
4. **增加运行时诊断接口**:如 `UART2_Print_GetOverflowCount()` 已有,建议为各模块添加更多诊断计数器,帮助现场定位问题。
|
||||||
|
|
||||||
|
5. **考虑使用 RTOS 的队列/信号量机制**:如果项目复杂度增加,当前这种裸机共享资源方案的可维护性会下降。
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*审查完成。关键问题已在代码注释中标注,建议优先修复高危问题后再进行功能验证测试。*
|
||||||
994
docs/application_development_plan.md
Normal file
994
docs/application_development_plan.md
Normal file
@ -0,0 +1,994 @@
|
|||||||
|
# E32-433TBH-SC 应用层软件开发计划
|
||||||
|
|
||||||
|
## 项目概述
|
||||||
|
|
||||||
|
| 项目属性 | 描述 |
|
||||||
|
| --------- | -------------------------------- |
|
||||||
|
| **目标MCU** | STM32F103C8T6 (Cortex-M3, 72MHz) |
|
||||||
|
| **开发环境** | Keil MDK-ARM V5.32 |
|
||||||
|
| **架构模式** | 裸机轮询 + 中断驱动 |
|
||||||
|
| **当前状态** | HAL层就绪,基础通信验证通过 |
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 一、整体架构设计
|
||||||
|
|
||||||
|
### 1.1 硬件资源映射
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────┐
|
||||||
|
│ 硬件连接关系 │
|
||||||
|
├─────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ UART1 (PA9/PA10) ◄────► RF433无线模块 (9600bps) │
|
||||||
|
│ │
|
||||||
|
│ UART2 (PA2/PA3) ◄────► 调试串口/上位机 (115200bps) │
|
||||||
|
│ │
|
||||||
|
│ UART3 (PB10/PB11) ◄────► 预留串口 (9600bps) │
|
||||||
|
│ │
|
||||||
|
│ MCU_DI1 (PB4) ◄────► 数字输入1 │
|
||||||
|
│ MCU_DI2 (PB5) ◄────► 数字输入2 │
|
||||||
|
│ MCU_DI3 (PB6) ◄────► 数字输入3 │
|
||||||
|
│ MCU_DI4 (PB7) ◄────► 数字输入4 │
|
||||||
|
│ │
|
||||||
|
│ RL_Control (PA15) ◄────► 继电器控制输出 │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.2 软件分层架构
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ 应用层 (Application) │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌────────────┐ │
|
||||||
|
│ │ UART2_Print │ │ 指令解析器 │ │ IO状态监控 │ │ 继电器控制 │ │
|
||||||
|
│ │ (调试输出) │ │ (ASCII指令) │ │ (DI1-4) │ │ (RL_Control)│ │
|
||||||
|
│ └──────────────┘ └──────────────┘ └──────────────┘ └────────────┘ │
|
||||||
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ 服务层 (Service) │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||||
|
│ │ RingBuffer │ │ CmdParser │ │ Debounce │ │
|
||||||
|
│ │ (环形缓冲区) │ │ (指令解析) │ │ (软件去抖) │ │
|
||||||
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||||
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ 驱动层 (Driver) │
|
||||||
|
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
|
||||||
|
│ │ UART Driver │ │ GPIO Driver │ │ RF433 Driver │ │
|
||||||
|
│ │ (usart.c) │ │ (gpio.c) │ │ (rf433.c) │ │
|
||||||
|
│ └──────────────┘ └──────────────┘ └──────────────┘ │
|
||||||
|
├─────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ 硬件抽象层 (HAL - STM32) │
|
||||||
|
│ STM32F1xx_HAL_Driver / CMSIS │
|
||||||
|
└─────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.3 核心模块交互关系
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────┐
|
||||||
|
│ UART2_Print │
|
||||||
|
│ (调试输出) │
|
||||||
|
└────────▲────────┘
|
||||||
|
│ 日志/响应输出
|
||||||
|
│
|
||||||
|
┌──────────────┐ ┌────────┴────────┐ ┌──────────────┐
|
||||||
|
│ UART1 │◄──►│ 指令解析器 │◄──►│ UART2 │
|
||||||
|
│ (RF433) │ │ (CmdParser) │ │ (调试/上位机) │
|
||||||
|
└──────────────┘ └────────┬────────┘ └──────────────┘
|
||||||
|
│
|
||||||
|
┌──────────────┼──────────────┐
|
||||||
|
│ │ │
|
||||||
|
▼ ▼ ▼
|
||||||
|
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||||
|
│ IO状态监控 │ │ 继电器控制 │ │ RF433通信 │
|
||||||
|
│ (DI1-4) │ │ (RL_Control)│ │ (透传模式) │
|
||||||
|
└─────────────┘ └─────────────┘ └─────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 1.4 任务调度模型
|
||||||
|
|
||||||
|
基于现有裸机架构,采用**时间片轮询**模型:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
system_init();
|
||||||
|
|
||||||
|
while(1)
|
||||||
|
{
|
||||||
|
UART2_Print_Task(); // 发送缓冲区处理
|
||||||
|
IO_Monitor_Task(); // IO扫描与去抖
|
||||||
|
CmdParser_Task(); // 指令解析处理
|
||||||
|
|
||||||
|
__WFI(); // 等待中断,降低功耗
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**调度周期设计**:
|
||||||
|
|
||||||
|
| 任务 | 执行周期 | 说明 |
|
||||||
|
| ----------------- | ---- | ----------------- |
|
||||||
|
| `UART2_Print_Task` | 1ms | 发送缓冲区数据处理 |
|
||||||
|
| `IO_Monitor_Task` | 10ms | IO扫描与去抖,足够采样间隔 |
|
||||||
|
| `CmdParser_Task` | 每轮 | 指令解析,响应无需微秒级 |
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 二、模块详细设计
|
||||||
|
|
||||||
|
### 2.1 UART2_Print 模块
|
||||||
|
|
||||||
|
#### 2.1.1 模块职责
|
||||||
|
|
||||||
|
- 提供调试信息输出接口
|
||||||
|
- 支持 `printf` 风格的格式化输出
|
||||||
|
- 支持中断安全调用(通过环形缓冲区)
|
||||||
|
|
||||||
|
#### 2.1.2 头文件设计 (`uart2_print.h`)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifndef __UART2_PRINT_H
|
||||||
|
#define __UART2_PRINT_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define UART2_TX_BUFFER_SIZE 256
|
||||||
|
|
||||||
|
void UART2_Print_Init(void);
|
||||||
|
void UART2_Print_Send(const uint8_t *data, uint16_t len);
|
||||||
|
void UART2_Print_String(const char *str);
|
||||||
|
void UART2_Print_Printf(const char *fmt, ...);
|
||||||
|
void UART2_Print_Task(void);
|
||||||
|
bool UART2_Print_IsBusy(void);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.1.3 环形缓冲区实现
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#include "usart.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t buffer[UART2_TX_BUFFER_SIZE];
|
||||||
|
volatile uint16_t head;
|
||||||
|
volatile uint16_t tail;
|
||||||
|
volatile bool is_sending;
|
||||||
|
} ring_buffer_t;
|
||||||
|
|
||||||
|
static ring_buffer_t tx_ring = {0};
|
||||||
|
|
||||||
|
void UART2_Print_Init(void)
|
||||||
|
{
|
||||||
|
tx_ring.head = 0;
|
||||||
|
tx_ring.tail = 0;
|
||||||
|
tx_ring.is_sending = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_Send(const uint8_t *data, uint16_t len)
|
||||||
|
{
|
||||||
|
if (len == 0) return;
|
||||||
|
|
||||||
|
__disable_irq();
|
||||||
|
for (uint16_t i = 0; i < len; i++) {
|
||||||
|
uint16_t next = (tx_ring.head + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
if (next == tx_ring.tail) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tx_ring.buffer[tx_ring.head] = data[i];
|
||||||
|
tx_ring.head = next;
|
||||||
|
}
|
||||||
|
__enable_irq();
|
||||||
|
|
||||||
|
if (!tx_ring.is_sending) {
|
||||||
|
UART2_Print_Task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_String(const char *str)
|
||||||
|
{
|
||||||
|
UART2_Print_Send((const uint8_t *)str, strlen(str));
|
||||||
|
}
|
||||||
|
|
||||||
|
void UART2_Print_Task(void)
|
||||||
|
{
|
||||||
|
if (tx_ring.is_sending || tx_ring.tail == tx_ring.head) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t byte = tx_ring.buffer[tx_ring.tail];
|
||||||
|
tx_ring.tail = (tx_ring.tail + 1) % UART2_TX_BUFFER_SIZE;
|
||||||
|
tx_ring.is_sending = true;
|
||||||
|
|
||||||
|
HAL_UART_Transmit_IT(&huart2, &byte, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||||
|
{
|
||||||
|
if (huart->Instance == USART2) {
|
||||||
|
tx_ring.is_sending = false;
|
||||||
|
if (tx_ring.tail != tx_ring.head) {
|
||||||
|
UART2_Print_Task();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.1.4 printf 重定向
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#if defined(__CC_ARM) || defined(__ARMCC_VERSION)
|
||||||
|
int fputc(int ch, FILE *f)
|
||||||
|
{
|
||||||
|
UART2_Print_Send((uint8_t *)&ch, 1);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 2.2 ASCII文本指令协议
|
||||||
|
|
||||||
|
#### 2.2.1 指令格式设计
|
||||||
|
|
||||||
|
**设计原则**:
|
||||||
|
- 人类可读,方便调试
|
||||||
|
- 格式简单,易于解析
|
||||||
|
- 兼容常见串口调试工具
|
||||||
|
- **调试友好**:校验和FF为特权后门,跳过校验
|
||||||
|
|
||||||
|
**指令格式**:
|
||||||
|
|
||||||
|
```
|
||||||
|
$CMD,param1,param2*CS\r\n
|
||||||
|
|
||||||
|
$ - 帧起始符
|
||||||
|
CMD - 指令名称(2-4字符)
|
||||||
|
, - 参数分隔符
|
||||||
|
param - 参数(可选)
|
||||||
|
* - 校验和起始符
|
||||||
|
CS - 校验和(2位十六进制,从$到*之间所有字符的异或值)
|
||||||
|
特权后门: CS=FF 时强制跳过校验,用于人工调试
|
||||||
|
\r\n - 帧结束符
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2.2 指令定义
|
||||||
|
|
||||||
|
| 指令 | 参数1 | 参数2 | 功能说明 | 示例 |
|
||||||
|
| ----- | ------------ | --------- | -------------- | ----------------------- |
|
||||||
|
| `RL` | 继电器号(1) | 0/1 | 继电器控制 | `$RL,1,1*FF\r\n` |
|
||||||
|
| `DI` | 通道号(0-4) | (无) | 查询IO状态 | `$DI,1*FF\r\n` |
|
||||||
|
| `FWD` | 目标端口(1) | 数据 | 数据转发 | `$FWD,1,Hello*FF\r\n` |
|
||||||
|
| `ECHO`| (无) | (无) | 心跳测试 | `$ECHO*FF\r\n` |
|
||||||
|
|
||||||
|
**参数说明**:
|
||||||
|
- `RL` 指令:参数2为 `0`=关闭,`1`=打开
|
||||||
|
- `DI` 指令:参数1为 `0`=查询所有,`1-4`=查询指定通道
|
||||||
|
|
||||||
|
#### 2.2.3 完整指令示例
|
||||||
|
|
||||||
|
**示例1:控制继电器1打开**
|
||||||
|
|
||||||
|
```
|
||||||
|
指令: $RL,1,1*FF\r\n
|
||||||
|
|
||||||
|
解析:
|
||||||
|
- RL: 继电器控制指令
|
||||||
|
- 参数1=1: 继电器编号1
|
||||||
|
- 参数2=1: 打开
|
||||||
|
- CS=FF: 跳过校验(调试模式)
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例2:控制继电器1关闭**
|
||||||
|
|
||||||
|
```
|
||||||
|
指令: $RL,1,0*FF\r\n
|
||||||
|
|
||||||
|
解析:
|
||||||
|
- 参数2=0: 关闭
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例3:查询DI1状态**
|
||||||
|
|
||||||
|
```
|
||||||
|
指令: $DI,1*FF\r\n
|
||||||
|
|
||||||
|
响应: $OK,DI,1,1*XX\r\n (DI1=HIGH)
|
||||||
|
或: $OK,DI,1,0*XX\r\n (DI1=LOW)
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例4:查询所有DI状态**
|
||||||
|
|
||||||
|
```
|
||||||
|
指令: $DI,0*FF\r\n
|
||||||
|
|
||||||
|
响应: $OK,DI,1010*XX\r\n (DI1=1, DI2=0, DI3=1, DI4=0)
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例5:转发数据到RF433**
|
||||||
|
|
||||||
|
```
|
||||||
|
指令: $FWD,1,Hello RF433*FF\r\n
|
||||||
|
|
||||||
|
说明: 将"Hello RF433"转发到UART1(RF433模块)
|
||||||
|
```
|
||||||
|
|
||||||
|
**示例6:带校验和的正式指令**
|
||||||
|
|
||||||
|
```
|
||||||
|
指令: $RL,1,1*4C\r\n
|
||||||
|
|
||||||
|
校验和计算: '$' ^ 'R' ^ 'L' ^ ',' ^ '1' ^ ',' ^ '1'
|
||||||
|
= 0x24 ^ 0x52 ^ 0x4C ^ 0x2C ^ 0x31 ^ 0x2C ^ 0x31
|
||||||
|
= 0x4C
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2.4 响应格式
|
||||||
|
|
||||||
|
**成功响应**:
|
||||||
|
|
||||||
|
```
|
||||||
|
$OK,RL,1,1*XX\r\n (继电器1已打开)
|
||||||
|
$OK,DI,1,1*XX\r\n (DI1当前为HIGH)
|
||||||
|
$OK,DI,1010*XX\r\n (所有DI状态)
|
||||||
|
```
|
||||||
|
|
||||||
|
**失败响应**:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ERR,CMD*XX\r\n (未知指令)
|
||||||
|
$ERR,CS*XX\r\n (校验和错误)
|
||||||
|
$ERR,PARAM*XX\r\n (参数错误)
|
||||||
|
```
|
||||||
|
|
||||||
|
**IO状态上报(主动上报)**:
|
||||||
|
|
||||||
|
```
|
||||||
|
$DI_EVENT,1,1*XX\r\n (DI1变为HIGH)
|
||||||
|
$DI_EVENT,3,0*XX\r\n (DI3变为LOW)
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.2.5 安全防护设计
|
||||||
|
|
||||||
|
**防护目标**:防止畸形数据导致单片机死机(HardFault)
|
||||||
|
|
||||||
|
**防护措施**:
|
||||||
|
|
||||||
|
| 风险场景 | 防护措施 | 实现方式 |
|
||||||
|
| -------- | -------- | -------- |
|
||||||
|
| 缓冲区溢出 | 边界检查 | 写入前检查索引是否越界 |
|
||||||
|
| 超长数据帧 | 超时重置 | 长时间未收到完整帧则重置状态机 |
|
||||||
|
| 非法字符 | 字符过滤 | 只接受合法ASCII字符 |
|
||||||
|
| 内存越界 | 固定长度 | 使用固定大小缓冲区,拒绝超长数据 |
|
||||||
|
|
||||||
|
#### 2.2.6 指令解析器实现(带安全防护)
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define CMD_BUFFER_SIZE 64
|
||||||
|
#define CMD_MAX_LEN 8
|
||||||
|
#define PARAM_MAX_LEN 32
|
||||||
|
#define PARSE_TIMEOUT_MS 1000
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
PARSE_IDLE,
|
||||||
|
PARSE_CMD,
|
||||||
|
PARSE_PARAM1,
|
||||||
|
PARSE_PARAM2,
|
||||||
|
PARSE_CHECKSUM,
|
||||||
|
PARSE_COMPLETE
|
||||||
|
} parse_state_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char cmd[CMD_MAX_LEN];
|
||||||
|
char param1[PARAM_MAX_LEN];
|
||||||
|
char param2[PARAM_MAX_LEN];
|
||||||
|
uint8_t received_cs;
|
||||||
|
uint8_t calculated_cs;
|
||||||
|
bool valid;
|
||||||
|
bool skip_checksum;
|
||||||
|
} cmd_frame_t;
|
||||||
|
|
||||||
|
static parse_state_t parse_state = PARSE_IDLE;
|
||||||
|
static cmd_frame_t current_frame;
|
||||||
|
static uint8_t field_index = 0;
|
||||||
|
static uint8_t checksum_acc = 0;
|
||||||
|
static uint32_t last_rx_tick = 0;
|
||||||
|
|
||||||
|
static void reset_parser(void)
|
||||||
|
{
|
||||||
|
parse_state = PARSE_IDLE;
|
||||||
|
field_index = 0;
|
||||||
|
checksum_acc = 0;
|
||||||
|
memset(¤t_frame, 0, sizeof(current_frame));
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_valid_cmd_char(char c)
|
||||||
|
{
|
||||||
|
return isupper(c) || isdigit(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool is_valid_param_char(char c)
|
||||||
|
{
|
||||||
|
return isprint(c) && c != '*' && c != '\r' && c != '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t hex_to_byte(char high, char low)
|
||||||
|
{
|
||||||
|
uint8_t val = 0;
|
||||||
|
|
||||||
|
if (high >= '0' && high <= '9') val = (high - '0') << 4;
|
||||||
|
else if (high >= 'A' && high <= 'F') val = (high - 'A' + 10) << 4;
|
||||||
|
else if (high >= 'a' && high <= 'f') val = (high - 'a' + 10) << 4;
|
||||||
|
|
||||||
|
if (low >= '0' && low <= '9') val |= (low - '0');
|
||||||
|
else if (low >= 'A' && low <= 'F') val |= (low - 'A' + 10);
|
||||||
|
else if (low >= 'a' && low <= 'f') val |= (low - 'a' + 10);
|
||||||
|
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdParser_FeedByte(uint8_t byte, uint32_t current_tick)
|
||||||
|
{
|
||||||
|
if (parse_state != PARSE_IDLE) {
|
||||||
|
if (current_tick - last_rx_tick > PARSE_TIMEOUT_MS) {
|
||||||
|
reset_parser();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
last_rx_tick = current_tick;
|
||||||
|
|
||||||
|
switch (parse_state) {
|
||||||
|
case PARSE_IDLE:
|
||||||
|
if (byte == '$') {
|
||||||
|
reset_parser();
|
||||||
|
parse_state = PARSE_CMD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_CMD:
|
||||||
|
if (byte == ',') {
|
||||||
|
current_frame.cmd[field_index] = '\0';
|
||||||
|
parse_state = PARSE_PARAM1;
|
||||||
|
field_index = 0;
|
||||||
|
} else if (byte == '*') {
|
||||||
|
current_frame.cmd[field_index] = '\0';
|
||||||
|
parse_state = PARSE_CHECKSUM;
|
||||||
|
field_index = 0;
|
||||||
|
} else if (is_valid_cmd_char(byte)) {
|
||||||
|
if (field_index < CMD_MAX_LEN - 1) {
|
||||||
|
current_frame.cmd[field_index++] = byte;
|
||||||
|
checksum_acc ^= byte;
|
||||||
|
} else {
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_PARAM1:
|
||||||
|
if (byte == ',') {
|
||||||
|
current_frame.param1[field_index] = '\0';
|
||||||
|
parse_state = PARSE_PARAM2;
|
||||||
|
field_index = 0;
|
||||||
|
} else if (byte == '*') {
|
||||||
|
current_frame.param1[field_index] = '\0';
|
||||||
|
parse_state = PARSE_CHECKSUM;
|
||||||
|
field_index = 0;
|
||||||
|
} else if (is_valid_param_char(byte)) {
|
||||||
|
if (field_index < PARAM_MAX_LEN - 1) {
|
||||||
|
current_frame.param1[field_index++] = byte;
|
||||||
|
checksum_acc ^= byte;
|
||||||
|
} else {
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_PARAM2:
|
||||||
|
if (byte == '*') {
|
||||||
|
current_frame.param2[field_index] = '\0';
|
||||||
|
parse_state = PARSE_CHECKSUM;
|
||||||
|
field_index = 0;
|
||||||
|
} else if (is_valid_param_char(byte)) {
|
||||||
|
if (field_index < PARAM_MAX_LEN - 1) {
|
||||||
|
current_frame.param2[field_index++] = byte;
|
||||||
|
checksum_acc ^= byte;
|
||||||
|
} else {
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_CHECKSUM:
|
||||||
|
if (byte == '\n') {
|
||||||
|
current_frame.received_cs = hex_to_byte(
|
||||||
|
current_frame.cmd[0],
|
||||||
|
current_frame.cmd[1]
|
||||||
|
);
|
||||||
|
current_frame.calculated_cs = checksum_acc;
|
||||||
|
current_frame.skip_checksum = (current_frame.received_cs == 0xFF);
|
||||||
|
|
||||||
|
if (current_frame.skip_checksum ||
|
||||||
|
current_frame.received_cs == current_frame.calculated_cs) {
|
||||||
|
current_frame.valid = true;
|
||||||
|
parse_state = PARSE_COMPLETE;
|
||||||
|
} else {
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
} else if (byte != '\r') {
|
||||||
|
if (field_index < 2) {
|
||||||
|
current_frame.cmd[field_index++] = byte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARSE_COMPLETE:
|
||||||
|
reset_parser();
|
||||||
|
if (byte == '$') {
|
||||||
|
parse_state = PARSE_CMD;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CmdParser_HasCompleteFrame(cmd_frame_t *frame)
|
||||||
|
{
|
||||||
|
if (parse_state == PARSE_COMPLETE && current_frame.valid) {
|
||||||
|
if (frame) {
|
||||||
|
memcpy(frame, ¤t_frame, sizeof(cmd_frame_t));
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CmdParser_Acknowledge(void)
|
||||||
|
{
|
||||||
|
reset_parser();
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**安全防护要点说明**:
|
||||||
|
|
||||||
|
1. **缓冲区边界检查**:每次写入前检查 `field_index < MAX_LEN`
|
||||||
|
2. **超时重置**:超过1秒未收到完整帧,自动重置状态机
|
||||||
|
3. **字符过滤**:只接受合法字符,非法字符触发重置
|
||||||
|
4. **固定长度缓冲区**:不使用动态内存分配,避免内存碎片
|
||||||
|
5. **校验和特权**:`CS=FF` 时跳过校验,方便人工调试
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 2.3 IO状态监控模块
|
||||||
|
|
||||||
|
#### 2.3.1 检测方式
|
||||||
|
|
||||||
|
**推荐方案:定时扫描 + 软件去抖**
|
||||||
|
|
||||||
|
| 方案 | 优点 | 缺点 | 适用场景 |
|
||||||
|
| ---- | --------- | --------------- | ------ |
|
||||||
|
| 外部中断 | 响应快 | 需要额外中断资源,硬件去抖复杂 | 低频事件 |
|
||||||
|
| 定时扫描 | 简单可靠,统一管理 | 有扫描延迟 | 多路IO监控 |
|
||||||
|
|
||||||
|
#### 2.3.2 软件去抖实现
|
||||||
|
|
||||||
|
```c
|
||||||
|
#define DEBOUNCE_COUNT 3
|
||||||
|
#define IO_CHANNEL_COUNT 4
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GPIO_TypeDef *port;
|
||||||
|
uint16_t pin;
|
||||||
|
uint8_t current_state;
|
||||||
|
uint8_t debounce_counter;
|
||||||
|
uint8_t last_raw_state;
|
||||||
|
} io_channel_t;
|
||||||
|
|
||||||
|
static io_channel_t di_channels[IO_CHANNEL_COUNT] = {
|
||||||
|
{GPIOB, GPIO_PIN_4, 0, 0, 0},
|
||||||
|
{GPIOB, GPIO_PIN_5, 0, 0, 0},
|
||||||
|
{GPIOB, GPIO_PIN_6, 0, 0, 0},
|
||||||
|
{GPIOB, GPIO_PIN_7, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint32_t last_scan_tick = 0;
|
||||||
|
|
||||||
|
void IO_Monitor_Task(void)
|
||||||
|
{
|
||||||
|
if (HAL_GetTick() - last_scan_tick < 10) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
last_scan_tick = HAL_GetTick();
|
||||||
|
|
||||||
|
for (int i = 0; i < IO_CHANNEL_COUNT; i++) {
|
||||||
|
io_channel_t *ch = &di_channels[i];
|
||||||
|
|
||||||
|
uint8_t raw_state = HAL_GPIO_ReadPin(ch->port, ch->pin) ? 1 : 0;
|
||||||
|
|
||||||
|
if (raw_state != ch->last_raw_state) {
|
||||||
|
ch->debounce_counter = 0;
|
||||||
|
ch->last_raw_state = raw_state;
|
||||||
|
} else {
|
||||||
|
if (ch->debounce_counter < DEBOUNCE_COUNT) {
|
||||||
|
ch->debounce_counter++;
|
||||||
|
} else if (ch->current_state != raw_state) {
|
||||||
|
ch->current_state = raw_state;
|
||||||
|
IO_StateChangeHandler(i, raw_state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IO_StateChangeHandler(uint8_t channel, uint8_t state)
|
||||||
|
{
|
||||||
|
UART2_Print_Printf("$DI_EVENT,%d,%d*XX\r\n",
|
||||||
|
channel + 1,
|
||||||
|
state);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t IO_Monitor_GetAllStates(void)
|
||||||
|
{
|
||||||
|
uint8_t states = 0;
|
||||||
|
for (int i = 0; i < IO_CHANNEL_COUNT; i++) {
|
||||||
|
if (di_channels[i].current_state) {
|
||||||
|
states |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return states;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.3.3 IO监控模块接口
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifndef __IO_MONITOR_H
|
||||||
|
#define __IO_MONITOR_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void IO_Monitor_Init(void);
|
||||||
|
void IO_Monitor_Task(void);
|
||||||
|
uint8_t IO_Monitor_GetState(uint8_t channel);
|
||||||
|
uint8_t IO_Monitor_GetAllStates(void);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 2.4 继电器控制模块
|
||||||
|
|
||||||
|
#### 2.4.1 模块接口
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifndef __RELAY_CONTROL_H
|
||||||
|
#define __RELAY_CONTROL_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
void Relay_Init(void);
|
||||||
|
void Relay_SetState(uint8_t relay_id, bool state);
|
||||||
|
bool Relay_GetState(uint8_t relay_id);
|
||||||
|
void Relay_Toggle(uint8_t relay_id);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2.4.2 实现代码
|
||||||
|
|
||||||
|
```c
|
||||||
|
#include "relay_control.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
void Relay_Init(void)
|
||||||
|
{
|
||||||
|
HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin, GPIO_PIN_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Relay_SetState(uint8_t relay_id, bool state)
|
||||||
|
{
|
||||||
|
if (relay_id == 1) {
|
||||||
|
HAL_GPIO_WritePin(RL_Control_GPIO_Port, RL_Control_Pin,
|
||||||
|
state ? GPIO_PIN_SET : GPIO_PIN_RESET);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Relay_GetState(uint8_t relay_id)
|
||||||
|
{
|
||||||
|
if (relay_id == 1) {
|
||||||
|
return HAL_GPIO_ReadPin(RL_Control_GPIO_Port, RL_Control_Pin) ? true : false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Relay_Toggle(uint8_t relay_id)
|
||||||
|
{
|
||||||
|
if (relay_id == 1) {
|
||||||
|
HAL_GPIO_TogglePin(RL_Control_GPIO_Port, RL_Control_Pin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 三、关键数据结构与接口
|
||||||
|
|
||||||
|
### 3.1 简化的数据结构
|
||||||
|
|
||||||
|
```c
|
||||||
|
#ifndef __APP_TYPES_H
|
||||||
|
#define __APP_TYPES_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#define IO_CHANNEL_COUNT 4
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
UART_PORT_1 = 1,
|
||||||
|
UART_PORT_2 = 2,
|
||||||
|
UART_PORT_3 = 3
|
||||||
|
} uart_port_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char cmd[8];
|
||||||
|
char param1[16];
|
||||||
|
char param2[32];
|
||||||
|
uart_port_t source;
|
||||||
|
bool valid;
|
||||||
|
} cmd_frame_t;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3.2 设计说明
|
||||||
|
|
||||||
|
| 数据结构 | 用途 | 设计理由 |
|
||||||
|
| -------- | ---- | -------- |
|
||||||
|
| `uart_port_t` | 标识串口 | 简单枚举,UART1=RF433,UART2=调试口,UART3=预留 |
|
||||||
|
| `cmd_frame_t` | 存储解析后的指令 | 固定长度字符数组,避免动态内存分配 |
|
||||||
|
|
||||||
|
**为什么不需要复杂的数据结构?**
|
||||||
|
|
||||||
|
1. **ASCII指令格式**:人类可读,直接用字符串处理即可
|
||||||
|
2. **裸机轮询架构**:不需要消息队列,直接在主循环处理
|
||||||
|
3. **单一职责**:每个模块功能单一,不需要复杂的抽象
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 四、实施路线图
|
||||||
|
|
||||||
|
### 4.1 分阶段开发计划
|
||||||
|
|
||||||
|
```
|
||||||
|
┌─────────────────────────────────────────────────────────────────────────┐
|
||||||
|
│ 开发阶段时间线 │
|
||||||
|
├─────────────────────────────────────────────────────────────────────────┤
|
||||||
|
│ │
|
||||||
|
│ 第一阶段 (基础框架) 第二阶段 (核心功能) 第三阶段 (扩展) │
|
||||||
|
│ ├─ UART2_Print ├─ ASCII指令解析 ├─ RF433透传 │
|
||||||
|
│ ├─ IO监控模块 ├─ 继电器控制 ├─ UART3扩展 │
|
||||||
|
│ └─ 基础日志输出 └─ 指令响应 └─ 配置存储 │
|
||||||
|
│ │
|
||||||
|
│ 验证点: 验证点: 验证点: │
|
||||||
|
│ · 串口输出正常 · 指令响应正确 · 无线通信正常 │
|
||||||
|
│ · IO状态上报 · 继电器动作 · 长时间稳定性 │
|
||||||
|
│ │
|
||||||
|
└─────────────────────────────────────────────────────────────────────────┘
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4.2 第一阶段:基础框架搭建
|
||||||
|
|
||||||
|
**目标**:实现调试输出能力和IO状态监控
|
||||||
|
|
||||||
|
**任务清单**:
|
||||||
|
|
||||||
|
| 序号 | 任务 | 预计工作量 | 依赖 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 1.1 | 实现 `UART2_Print` 模块 | 1.5h | 无 |
|
||||||
|
| 1.2 | 实现 `printf` 重定向 | 0.5h | 1.1 |
|
||||||
|
| 1.3 | 实现 `IO_Monitor` 模块 | 1.5h | 无 |
|
||||||
|
| 1.4 | 集成到 `main.c` 主循环 | 0.5h | 1.1, 1.3 |
|
||||||
|
| 1.5 | 编写测试代码验证 | 0.5h | 1.4 |
|
||||||
|
|
||||||
|
**验证方法**:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void phase1_test(void)
|
||||||
|
{
|
||||||
|
UART2_Print_Init();
|
||||||
|
IO_Monitor_Init();
|
||||||
|
|
||||||
|
printf("Phase 1 Test Start\r\n");
|
||||||
|
printf("System Clock: %d MHz\r\n", SystemCoreClock / 1000000);
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
IO_Monitor_Task();
|
||||||
|
UART2_Print_Task();
|
||||||
|
|
||||||
|
static uint32_t last_tick = 0;
|
||||||
|
if (HAL_GetTick() - last_tick > 5000) {
|
||||||
|
last_tick = HAL_GetTick();
|
||||||
|
uint8_t states = IO_Monitor_GetAllStates();
|
||||||
|
printf("DI States: 0x%02X\r\n", states);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**验收标准**:
|
||||||
|
|
||||||
|
- [ ] UART2能正常输出调试信息
|
||||||
|
- [ ] `printf` 函数可用
|
||||||
|
- [ ] DI1-DI4状态变化能实时上报
|
||||||
|
- [ ] 软件去抖功能正常
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 4.3 第二阶段:指令解析与继电器控制
|
||||||
|
|
||||||
|
**目标**:实现ASCII指令解析和继电器控制
|
||||||
|
|
||||||
|
**任务清单**:
|
||||||
|
|
||||||
|
| 序号 | 任务 | 预计工作量 | 依赖 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 2.1 | 实现ASCII指令解析器 | 2h | 第一阶段 |
|
||||||
|
| 2.2 | 实现继电器控制模块 | 0.5h | 无 |
|
||||||
|
| 2.3 | 实现指令响应机制 | 1h | 2.1, 2.2 |
|
||||||
|
| 2.4 | UART2接收中断集成 | 0.5h | 2.1 |
|
||||||
|
| 2.5 | 端到端测试 | 0.5h | 2.4 |
|
||||||
|
|
||||||
|
**验证方法**:
|
||||||
|
|
||||||
|
```c
|
||||||
|
void phase2_test(void)
|
||||||
|
{
|
||||||
|
UART2_Print_Init();
|
||||||
|
IO_Monitor_Init();
|
||||||
|
CmdParser_Init();
|
||||||
|
Relay_Init();
|
||||||
|
|
||||||
|
printf("Phase 2 Test Start\r\n");
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
IO_Monitor_Task();
|
||||||
|
UART2_Print_Task();
|
||||||
|
CmdParser_Task();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 手动测试:通过串口发送指令
|
||||||
|
// 打开继电器1: $RL,1,1*FF\r\n
|
||||||
|
// 关闭继电器1: $RL,1,0*FF\r\n
|
||||||
|
// 查询DI1状态: $DI,1*FF\r\n
|
||||||
|
// 查询所有DI: $DI,0*FF\r\n
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**验收标准**:
|
||||||
|
|
||||||
|
- [ ] 能正确解析ASCII指令
|
||||||
|
- [ ] 校验和验证正常
|
||||||
|
- [ ] 继电器能按指令开关
|
||||||
|
- [ ] 指令执行后有响应输出
|
||||||
|
- [ ] 错误指令能被识别并返回错误信息
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 4.4 第三阶段:RF433透传与扩展
|
||||||
|
|
||||||
|
**目标**:实现RF433无线透传功能
|
||||||
|
|
||||||
|
**任务清单**:
|
||||||
|
|
||||||
|
| 序号 | 任务 | 预计工作量 | 依赖 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| 3.1 | 实现FWD转发指令处理 | 1h | 第二阶段 |
|
||||||
|
| 3.2 | 集成RF433模块驱动 | 1h | 3.1 |
|
||||||
|
| 3.3 | 实现双向透传 | 1h | 3.2 |
|
||||||
|
| 3.4 | 压力测试与优化 | 1h | 3.3 |
|
||||||
|
|
||||||
|
**验证方法**:
|
||||||
|
|
||||||
|
```c
|
||||||
|
// 测试场景:
|
||||||
|
// 1. UART2发送: $FWD,1,Hello RF433*FF\r\n
|
||||||
|
// 验证UART1(RF433)是否收到 "Hello RF433"
|
||||||
|
//
|
||||||
|
// 2. RF433接收数据后,自动转发到UART2
|
||||||
|
// 验证UART2是否收到RF433的数据
|
||||||
|
```
|
||||||
|
|
||||||
|
**验收标准**:
|
||||||
|
|
||||||
|
- [ ] UART2→RF433转发正常
|
||||||
|
- [ ] RF433→UART2转发正常
|
||||||
|
- [ ] 连续转发100次无丢包
|
||||||
|
- [ ] 长时间运行稳定(>30分钟)
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 4.5 文件组织
|
||||||
|
|
||||||
|
```
|
||||||
|
Core/
|
||||||
|
├── Inc/
|
||||||
|
│ ├── uart2_print.h # 调试打印模块
|
||||||
|
│ ├── io_monitor.h # IO监控模块
|
||||||
|
│ ├── cmd_parser.h # 指令解析模块
|
||||||
|
│ ├── relay_control.h # 继电器控制模块
|
||||||
|
│ └── app_types.h # 公共类型定义
|
||||||
|
├── Src/
|
||||||
|
│ ├── main.c # 主程序(修改)
|
||||||
|
│ ├── uart2_print.c # 调试打印实现
|
||||||
|
│ ├── io_monitor.c # IO监控实现
|
||||||
|
│ ├── cmd_parser.c # 指令解析实现
|
||||||
|
│ └── relay_control.c # 继电器控制实现
|
||||||
|
```
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
### 4.6 风险与缓解措施
|
||||||
|
|
||||||
|
| 风险 | 影响 | 缓解措施 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 环形缓冲区溢出 | 数据丢失 | 增加缓冲区大小,添加溢出检测 |
|
||||||
|
| 指令解析错误 | 功能异常 | 完善状态机,添加超时重置机制 |
|
||||||
|
| 继电器控制时序 | 硬件损坏 | 添加最小间隔限制 |
|
||||||
|
|
||||||
|
***
|
||||||
|
|
||||||
|
## 五、总结
|
||||||
|
|
||||||
|
### 架构设计要点
|
||||||
|
|
||||||
|
1. **简化分层**:应用层 → 服务层 → 驱动层,职责清晰
|
||||||
|
2. **ASCII指令**:人类可读,方便调试,易于扩展
|
||||||
|
3. **时间片轮询**:基于现有裸机架构,无需RTOS
|
||||||
|
|
||||||
|
### 协议设计亮点
|
||||||
|
|
||||||
|
1. **ASCII文本格式**:`$CMD,param1,param2*CS\r\n`,简单直观
|
||||||
|
2. **异或校验**:计算简单,适合嵌入式系统
|
||||||
|
3. **统一响应格式**:`$OK,...` 或 `$ERR,...`
|
||||||
|
|
||||||
|
### 关键技术决策
|
||||||
|
|
||||||
|
| 决策点 | 选择 | 理由 |
|
||||||
|
| --- | --- | --- |
|
||||||
|
| 指令格式 | ASCII文本 | 人类可读,方便调试,兼容串口工具 |
|
||||||
|
| IO检测方式 | 定时扫描 | 4路统一管理,软件去抖灵活 |
|
||||||
|
| 打印缓冲 | 环形缓冲区 | ISR安全,非阻塞发送 |
|
||||||
|
|
||||||
|
### 下一步行动
|
||||||
|
|
||||||
|
建议按照以下顺序开始编码:
|
||||||
|
|
||||||
|
1. 实现 `UART2_Print` 模块,验证调试输出
|
||||||
|
2. 实现 `IO_Monitor` 模块,验证IO监控
|
||||||
|
3. 实现 `CmdParser` 模块,验证指令解析
|
||||||
|
4. 实现 `Relay_Control` 模块,验证继电器控制
|
||||||
274
docs/integration_guide.md
Normal file
274
docs/integration_guide.md
Normal file
@ -0,0 +1,274 @@
|
|||||||
|
/**
|
||||||
|
******************************************************************************
|
||||||
|
* @file integration_guide.md
|
||||||
|
* @brief 应用层模块集成指南
|
||||||
|
* @author Application Layer
|
||||||
|
* @version 1.0
|
||||||
|
******************************************************************************
|
||||||
|
* @attention
|
||||||
|
* 本文档说明如何将uart2_print、io_monitor、cmd_parser、relay_control
|
||||||
|
* 四个模块集成到现有工程中。
|
||||||
|
******************************************************************************
|
||||||
|
*/
|
||||||
|
|
||||||
|
# 应用层模块集成指南
|
||||||
|
|
||||||
|
## 一、文件清单
|
||||||
|
|
||||||
|
### 新增文件
|
||||||
|
|
||||||
|
| 文件路径 | 说明 |
|
||||||
|
|---------|------|
|
||||||
|
| `Core/Inc/uart2_print.h` | UART2打印模块头文件 |
|
||||||
|
| `Core/Src/uart2_print.c` | UART2打印模块实现 |
|
||||||
|
| `Core/Inc/io_monitor.h` | IO监控模块头文件 |
|
||||||
|
| `Core/Src/io_monitor.c` | IO监控模块实现 |
|
||||||
|
| `Core/Inc/cmd_parser.h` | 指令解析模块头文件 |
|
||||||
|
| `Core/Src/cmd_parser.c` | 指令解析模块实现 |
|
||||||
|
| `Core/Inc/relay_control.h` | 继电器控制模块头文件 |
|
||||||
|
| `Core/Src/relay_control.c` | 继电器控制模块实现 |
|
||||||
|
|
||||||
|
### 需要修改的文件
|
||||||
|
|
||||||
|
| 文件路径 | 修改内容 |
|
||||||
|
|---------|---------|
|
||||||
|
| `Core/Src/main.c` | 添加头文件引用、初始化调用、主循环任务 |
|
||||||
|
| `Core/Src/usart.c` | 添加UART2接收中断处理 |
|
||||||
|
| `Core/Src/stm32f1xx_it.c` | 添加UART2接收缓冲变量 |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 二、main.c 修改说明
|
||||||
|
|
||||||
|
### 2.1 在 `USER CODE BEGIN Includes` 区域添加
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* USER CODE BEGIN Includes */
|
||||||
|
#include "rf433.h"
|
||||||
|
#include "rf433_config.h"
|
||||||
|
#include "rf433_hal.h"
|
||||||
|
|
||||||
|
/* 应用层模块头文件 */
|
||||||
|
#include "uart2_print.h"
|
||||||
|
#include "io_monitor.h"
|
||||||
|
#include "cmd_parser.h"
|
||||||
|
#include "relay_control.h"
|
||||||
|
|
||||||
|
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
|
#include "rf433_tx_app.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
|
#include "rf433_rx_app.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* USER CODE END Includes */
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.2 在 `USER CODE BEGIN PV` 区域添加
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* USER CODE BEGIN PV */
|
||||||
|
static uint8_t uart2_rx_byte = 0;
|
||||||
|
/* USER CODE END PV */
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.3 在 `USER CODE BEGIN 2` 区域修改
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
|
||||||
|
/* 初始化应用层模块 */
|
||||||
|
UART2_Print_Init();
|
||||||
|
IO_Monitor_Init();
|
||||||
|
CmdParser_Init();
|
||||||
|
Relay_Init();
|
||||||
|
|
||||||
|
/* 启动UART2接收中断 */
|
||||||
|
HAL_UART_Receive_IT(&huart2, &uart2_rx_byte, 1);
|
||||||
|
|
||||||
|
/* 初始化RF433模块 - 使用默认配置 */
|
||||||
|
rf433_init(NULL);
|
||||||
|
|
||||||
|
/* 启动UART接收 - 使用rf433_hal中的临时变量 */
|
||||||
|
HAL_UART_Receive_IT(&huart1, &rf433_uart_rx_tmp, 1);
|
||||||
|
|
||||||
|
/* 根据配置模式初始化TX/RX应用层 */
|
||||||
|
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
|
/* TX模式初始化 */
|
||||||
|
rf433_tx_app_init(NULL);
|
||||||
|
rf433_tx_app_start(RF433_DEFAULT_TX_COUNT, RF433_DEFAULT_TX_INTERVAL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
|
/* RX模式初始化 */
|
||||||
|
rf433_rx_app_init(NULL);
|
||||||
|
rf433_rx_app_start();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* 打印启动信息 */
|
||||||
|
UART2_Print_Printf("\r\n========================================\r\n");
|
||||||
|
UART2_Print_Printf("E32-433TBH-SC Application Started\r\n");
|
||||||
|
UART2_Print_Printf("System Clock: %d MHz\r\n", SystemCoreClock / 1000000);
|
||||||
|
UART2_Print_Printf("========================================\r\n");
|
||||||
|
|
||||||
|
/* USER CODE END 2 */
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.4 在 `USER CODE BEGIN 3` 区域修改
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* USER CODE BEGIN 3 */
|
||||||
|
|
||||||
|
/* 应用层任务处理 */
|
||||||
|
UART2_Print_Task();
|
||||||
|
IO_Monitor_Task();
|
||||||
|
CmdParser_Task();
|
||||||
|
|
||||||
|
#if (RF433_MODE == RF433_MODE_TX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
|
/* TX任务 */
|
||||||
|
rf433_tx_app_task();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (RF433_MODE == RF433_MODE_RX) || (RF433_MODE == RF433_MODE_BOTH)
|
||||||
|
/* RX任务 */
|
||||||
|
rf433_rx_app_task();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* USER CODE END 3 */
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2.5 在 `USER CODE BEGIN 4` 区域添加
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* USER CODE BEGIN 4 */
|
||||||
|
|
||||||
|
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||||
|
{
|
||||||
|
if (huart->Instance == USART1)
|
||||||
|
{
|
||||||
|
/* 调用RF433模块的UART接收回调 */
|
||||||
|
rf433_hal_uart_rxcplt_callback();
|
||||||
|
}
|
||||||
|
else if (huart->Instance == USART2)
|
||||||
|
{
|
||||||
|
/* 喂入指令解析器 */
|
||||||
|
CmdParser_FeedByte(uart2_rx_byte, HAL_GetTick());
|
||||||
|
|
||||||
|
/* 重新启动接收 */
|
||||||
|
HAL_UART_Receive_IT(&huart2, &uart2_rx_byte, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
|
||||||
|
{
|
||||||
|
if (huart->Instance == USART2)
|
||||||
|
{
|
||||||
|
/* 调用UART2打印模块的发送完成回调 */
|
||||||
|
UART2_Print_TxCpltCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* USER CODE END 4 */
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 三、usart.c 修改说明
|
||||||
|
|
||||||
|
### 3.1 删除原有的 `HAL_UART_RxCpltCallback` 函数
|
||||||
|
|
||||||
|
原有的回调函数在 `USER CODE BEGIN 1` 区域,需要删除:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
// 删除以下代码
|
||||||
|
// void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
|
||||||
|
// {
|
||||||
|
// if (huart->Instance == USART1)
|
||||||
|
// {
|
||||||
|
// rf433_hal_uart_rxcplt_callback();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
/* USER CODE END 1 */
|
||||||
|
```
|
||||||
|
|
||||||
|
改为:
|
||||||
|
|
||||||
|
```c
|
||||||
|
/* USER CODE BEGIN 1 */
|
||||||
|
/* UART回调函数已移至main.c统一管理 */
|
||||||
|
/* USER CODE END 1 */
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 四、Keil工程配置
|
||||||
|
|
||||||
|
### 4.1 添加源文件到工程
|
||||||
|
|
||||||
|
1. 打开Keil工程 `MDK-ARM/project.uvprojx`
|
||||||
|
2. 在Project窗口中,右键点击 `Application/User/Core` 分组
|
||||||
|
3. 选择 `Add Existing Files...`
|
||||||
|
4. 添加以下文件:
|
||||||
|
- `Core/Src/uart2_print.c`
|
||||||
|
- `Core/Src/io_monitor.c`
|
||||||
|
- `Core/Src/cmd_parser.c`
|
||||||
|
- `Core/Src/relay_control.c`
|
||||||
|
|
||||||
|
### 4.2 添加头文件路径
|
||||||
|
|
||||||
|
1. 点击工程设置图标(魔术棒)
|
||||||
|
2. 切换到 `C/C++` 标签页
|
||||||
|
3. 在 `Include Paths` 中确认 `Core/Inc` 已在路径中
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 五、测试验证
|
||||||
|
|
||||||
|
### 5.1 编译工程
|
||||||
|
|
||||||
|
编译应无错误,如有警告请检查:
|
||||||
|
- 头文件路径是否正确
|
||||||
|
- 源文件是否已添加到工程
|
||||||
|
|
||||||
|
### 5.2 下载运行
|
||||||
|
|
||||||
|
下载程序后,通过串口调试助手连接UART2(115200bps),应看到:
|
||||||
|
|
||||||
|
```
|
||||||
|
========================================
|
||||||
|
E32-433TBH-SC Application Started
|
||||||
|
System Clock: 72 MHz
|
||||||
|
========================================
|
||||||
|
[UART2] Init OK, buffer size: 256
|
||||||
|
[IO] Init OK, initial states: 0x00
|
||||||
|
[CMD] Init OK
|
||||||
|
[RELAY] Init OK, state=OFF
|
||||||
|
```
|
||||||
|
|
||||||
|
### 5.3 指令测试
|
||||||
|
|
||||||
|
发送以下指令测试:
|
||||||
|
|
||||||
|
```
|
||||||
|
$RL,1,1*FF\r\n 打开继电器1
|
||||||
|
$RL,1,0*FF\r\n 关闭继电器1
|
||||||
|
$DI,0*FF\r\n 查询所有DI状态
|
||||||
|
$DI,1*FF\r\n 查询DI1状态
|
||||||
|
$ECHO*FF\r\n 心跳测试
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 六、注意事项
|
||||||
|
|
||||||
|
1. **不要修改HAL初始化代码**:`MX_GPIO_Init`、`MX_USARTx_UART_Init` 等函数由CubeMX生成,不应手动修改
|
||||||
|
|
||||||
|
2. **中断优先级**:UART1优先级为0,UART2优先级为1,UART3优先级为2,已按计划配置
|
||||||
|
|
||||||
|
3. **调试开关**:各模块开头有 `DEBUG_xxx` 宏,设为1启用调试日志,设为0禁用
|
||||||
|
|
||||||
|
4. **缓冲区大小**:`UART2_TX_BUFFER_SIZE` 默认256字节,可根据需要调整
|
||||||
|
|
||||||
|
5. **去抖参数**:`IO_DEBOUNCE_COUNT` 默认3次,`IO_SCAN_PERIOD_MS` 默认10ms
|
||||||
@ -1,16 +1,3 @@
|
|||||||
# Driver_RF433 技术README文档生成计划
|
|
||||||
|
|
||||||
## 项目概述
|
|
||||||
|
|
||||||
为基于STM32F103的E32-433TBH-SC无线通信模块驱动项目生成详细的技术README文档,涵盖架构分析、API接口、配置指南和集成示例。
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 完整README文档内容
|
|
||||||
|
|
||||||
以下是将要生成的README.md文档的完整内容:
|
|
||||||
|
|
||||||
```markdown
|
|
||||||
# Driver_RF433 技术文档
|
# Driver_RF433 技术文档
|
||||||
|
|
||||||
## 项目概述
|
## 项目概述
|
||||||
Reference in New Issue
Block a user