From 7171f1153491e6788b6988e2def6020525b5abf9 Mon Sep 17 00:00:00 2001 From: edisondeng Date: Sun, 10 May 2026 11:24:49 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=BF=83=E8=B7=B3=E5=8C=85=E6=96=B0?= =?UTF-8?q?=E5=A2=9E=E5=9B=BA=E4=BB=B6=E7=89=88=E6=9C=AC=E5=8F=B7=E5=AD=97?= =?UTF-8?q?=E6=AE=B5=EF=BC=8C=E6=9B=B4=E6=96=B0=E5=8D=8F=E8=AE=AE=E6=96=87?= =?UTF-8?q?=E6=A1=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Core/Inc/main.h | 26 +++++++++++++++++++++++ Core/Inc/modbus_tcp_client.h | 2 +- Core/Src/main.c | 38 ++++++++++++++++++++++----------- User/user_main/user_main.c | 4 ++-- docs/报文.md | 41 ++++++++++++++++++++++++------------ 5 files changed, 83 insertions(+), 28 deletions(-) diff --git a/Core/Inc/main.h b/Core/Inc/main.h index 917d108..0056d06 100644 --- a/Core/Inc/main.h +++ b/Core/Inc/main.h @@ -48,6 +48,32 @@ extern "C" { /* Exported macro ------------------------------------------------------------*/ /* USER CODE BEGIN EM */ +// 基准年份 +#define XTELL_BASE_YEAR 2026 +/** + * 宏定义:3-4-5-4 固件版本编码 + * y: Year (2026-2033) + * m: Month (1-12) + * d: Day (1-31) + * b: Build (0-15) + */ +#define MAKE_XTELL_CODE(y, m, d, b) ( \ + ((( (y) - XTELL_BASE_YEAR ) & 0x07) << 13) | \ + (((m) & 0x0F) << 9) | \ + (((d) & 0x1F) << 4) | \ + (((b) & 0x0F) << 0) \ +) + +// 举例:2026年3月19日,第10次编译 (b=9) +// 计算过程: (0 << 13) | (3 << 9) | (19 << 4) | 9 = 0x0600 | 0x0130 | 0x0009 +#define XTELL_FIRMWARE_CODE MAKE_XTELL_CODE(2026, 5, 10, 1) +// ---- - -- - +// | | | | +// | | | 编译次数 +// | | 日 +// | 月 +// 年 + #ifndef USE_W5500 #define USE_W5500 1 /* 默认启用W5500以太网模块 */ #endif diff --git a/Core/Inc/modbus_tcp_client.h b/Core/Inc/modbus_tcp_client.h index 8d35127..94ea486 100644 --- a/Core/Inc/modbus_tcp_client.h +++ b/Core/Inc/modbus_tcp_client.h @@ -14,7 +14,7 @@ /* Modbus TCP 配置 */ #if TEST_A701 -#define MODBUS_SERVER_IP {192, 168, 6, 4} /* A701 测试服务器 */ +#define MODBUS_SERVER_IP {192, 168, 0, 6} /* A701 测试服务器 */ #else #define MODBUS_SERVER_IP {192, 168, 0, 1} /* 现场生产服务器 */ #endif diff --git a/Core/Src/main.c b/Core/Src/main.c index abc52ba..d3da5bf 100644 --- a/Core/Src/main.c +++ b/Core/Src/main.c @@ -388,21 +388,35 @@ int main(void) #if USE_IO_MONITOR if (HAL_GetTick() - g_last_hb_tick >= 30000) { g_last_hb_tick = HAL_GetTick(); - uint8_t hb_payload[5]; // 扩充为 5 字节 - hb_payload[0] = IO_Monitor_GetAllStates(); - hb_payload[1] = (uint8_t)(g_hb_seq >> 8); - hb_payload[2] = (uint8_t)(g_hb_seq & 0xFF); - - uint16_t modbus_val = 0xFFFF; // 默认值 + uint8_t hb_payload[7]; + uint8_t io_state = IO_Monitor_GetAllStates(); + #if USE_W5500 - modbus_val = ModbusTCP_Get_LastRegVal(); // 获取最新 Modbus 寄存器值 + uint8_t phy_link_status; + ctlwizchip(CW_GET_PHYLINK, (void *)&phy_link_status); + if (phy_link_status == PHY_LINK_ON) { + io_state |= 0x80; + } #endif - hb_payload[3] = (uint8_t)(modbus_val >> 8); - hb_payload[4] = (uint8_t)(modbus_val & 0xFF); - + + hb_payload[0] = (uint8_t)(g_hb_seq >> 8); + hb_payload[1] = (uint8_t)(g_hb_seq & 0xFF); + + hb_payload[2] = (uint8_t)(XTELL_FIRMWARE_CODE >> 8); + hb_payload[3] = (uint8_t)(XTELL_FIRMWARE_CODE & 0xFF); + + hb_payload[4] = io_state; + + uint16_t modbus_val = 0xFFFF; + #if USE_W5500 + modbus_val = ModbusTCP_Get_LastRegVal(); + #endif + hb_payload[5] = (uint8_t)(modbus_val >> 8); + hb_payload[6] = (uint8_t)(modbus_val & 0xFF); + g_hb_seq++; - - RF433_SendPacket(PROTO_TYPE_HB, hb_payload, 5); // 发送 5 字节 + + RF433_SendPacket(PROTO_TYPE_HB, hb_payload, sizeof(hb_payload)); } #endif diff --git a/User/user_main/user_main.c b/User/user_main/user_main.c index c1d39cd..52da4c2 100644 --- a/User/user_main/user_main.c +++ b/User/user_main/user_main.c @@ -18,8 +18,8 @@ wiz_NetInfo default_net_info = { .mac = {0x00, 0x08, 0xdc, 0x12, 0x22, 0x12}, #if TEST_A701 - .ip = {192, 168, 6, 212}, - .gw = {192, 168, 6, 1}, + .ip = {192, 168, 0, 212}, + .gw = {192, 168, 0, 1}, #else .ip = {192, 168, 0, 5}, .gw = {192, 168, 0, 1}, diff --git a/docs/报文.md b/docs/报文.md index d384efd..531e9df 100644 --- a/docs/报文.md +++ b/docs/报文.md @@ -68,26 +68,41 @@ AA 55 LEN ID [DATA] SUM ``` ### 2.4 系统心跳包 (30秒/次) -系统定时上报当前存活状态,包含当前的 I/O 状态及防丢包序列号。 +系统定时上报当前存活状态,包含当前的 I/O 状态、防丢包序列号、固件版本及 Modbus 寄存器值。 + +#### 2.4.1 标准心跳包 (8字节Payload) ```text -AA AA 05 ID [IO] [SEQ_H] [SEQ_L] SUM --- -- -- -- ---- ------- ------- --- - | | | | | | | | - | | | | | | | +-- 校验和 - | | | | | +-------+-------- 2字节序列号 (0-65535, 循环自增) - | | | | +----------------------- 当前 4 路 I/O 状态位 - | | | +---------------------------- 本机设备 ID - | | +-------------------------------- 长度固定为 0x05 (ID + 3字节Payload + SUM) - | +------------------------------------ 类型标识:0xAA (Heartbeat) - +---------------------------------------- 固定起始符 +AA AA 09 [DEVICE_ID] [SEQ_H] [SEQ_L] [FW_H] [FW_L] [IO_STATUS] [MODBUS_H] [MODBUS_L] SUM +-- -- -- ----------- --------------- ------------- ----------- --------------------- --- + | | | | | | | | | + | | | | | | | | +-- 1字节 校验和 + | | | | | | | +-------------------- 2字节 Modbus 寄存器值 + | | | | | | +------------------------------------- 1字节 I/O 状态 + | | | | | | Bit7: W5500 网线连接状态 + | | | | | | Bit3-Bit0: 4路 DI 状态 + | | | | | +--------------------------------------------------- 2字节序列号 + | | | | +------------------------------------------------------------------ 2字节固件版本编码 + | | | +----------------------------------------------------------------------------------- 1字节本机设备 ID + | | +--------------------------------------------------------------------------------------------- 长度 0x09,后续的总字节数 + | +------------------------------------------------------------------------------------------------- 类型 0xAA + +----------------------------------------------------------------------------------------------------- 固定起始符 ``` +**Payload 字段说明:** +| 字段 | 长度 | 说明 | +|------|------|------| +| SEQ_H, SEQ_L | 2 | 2字节序列号 (0-65535, 循环自增) | +| FW_H, FW_L | 2 | 2字节固件版本编码 (MAKE_XTELL_CODE 宏定义) | +| DEVICE_ID | 1 | 本机设备 ID (MY_DEVICE_ID) | +| IO_STATUS | 1 | 1字节 I/O 状态 | +| MODBUS_H, MODBUS_L | 2 | 2字节 Modbus 寄存器值 (最新读取值) | + --- ## 3. 示例说明 (假设 Device ID = 0x01) -* **心跳包示例**:`AA AA 04 01 0F 00 05 72` - * 表示:ID为1的设备,I/O全为高,序列号为5。 +* **心跳包示例**:`AA AA 08 01 00 05 06 41 01 0F 01 2C 5A` + * 表示:ID为1的设备,序列号5,固件版本 0x0641 (2026年5月10日第1次编译),本机ID=1,I/O全高,Modbus=0x012C (300)(8字节payload) * **485透传示例**:`AA 48 05 01 41 42 43 44 4D` * 表示:ID为1的设备,转发了 485 数据 "ABCD" (长度 4+1=5)。