feat: 添加协议处理和校验和计算功能,更新 UART 相关代码

This commit is contained in:
2026-04-02 01:52:28 +08:00
parent 8d2a0ea0c8
commit a53aa38ed3
11 changed files with 390 additions and 40 deletions

130
README.md
View File

@@ -177,3 +177,133 @@ void UART_IDLE_Callback(UART_HandleTypeDef *huart) {
const char *message = "Hello, ESP12F! This is a test message.";
HAL_StatusTypeDef status = ESP12F_TCP_SendMessage(message);
```
这些是上位机发送的指令:
按照这些来写代码
这是一个基于 TCP/IP 局域网通信的物流小车控制指令协议设计方案。
为了方便调试和开发,本协议采用 **ASCII 文本格式**(类似于 Modbus ASCII 或简单的串口透传格式),而不是二进制格式。这样你可以直接使用网络调试助手(如 NetAssist手动发送字符串来测试小车而无需编写专门的上位机软件。
---
### 📡 通信基础参数
- **通信方式**TCP Client (上位机) 连接 TCP Server (单片机/小车)
- **数据格式**ASCII 字符串
- **换行符**:建议使用 `\r\n` (回车+换行) 作为每条指令的结束标志,以便单片机解析。
- **字节序**N/A (文本协议不涉及大小端问题)
---
### 📦 指令帧结构
每条指令由以下几个部分组成,字段之间用英文冒号 `:` 分隔:
`[帧头][命令字][数据内容][校验和][帧尾]`
- **帧头**:固定为 `LOGI` (代表 Logistics),用于快速识别有效数据包。
- **命令字**2位字符代表具体操作`GS` 代表去站点)。
- **数据内容**:具体的参数,长度可变。
- **校验和**2位十六进制数用于验证数据完整性防止丢包或乱码
- **帧尾**:固定为 `#`
---
### 📝 具体控制指令定义
以下是针对你提出的四个需求(去站点、停止、启动、速度)的具体指令格式。
#### 1. 去往指定站点
- **功能**:指示小车移动到编号为 N 的站点。
- **指令格式**`LOGI:GS:NNN:CS#`
- **参数说明**
- `GS`: 命令字 (Go to Station)。
- `NNN`: 站点编号3位数字不足补0。例如1号站写为 `001`12号站写为 `012`
- `CS`: 校验和。
- **示例**
- 去往 **5号站点**`LOGI:GS:005:15#` (假设校验和计算结果为15)
#### 2. 启动运行
- **功能**:让处于停止或待机状态的小车开始执行任务或继续运行。
- **指令格式**`LOGI:ST:RUN:CS#`
- **参数说明**
- `ST`: 命令字 (Start/Status)。
- `RUN`: 固定参数,表示启动。
- **示例**
- 启动小车:`LOGI:ST:RUN:2A#`
#### 3. 紧急停止/暂停
- **功能**:立即停止小车的运动,通常用于急停或到达站点后的确认暂停。
- **指令格式**`LOGI:ST:STOP:CS#`
- **参数说明**
- `STOP`: 固定参数,表示停止。
- **示例**
- 停止小车:`LOGI:ST:STOP:32#`
#### 4. 设置运行速度
- **功能**:动态调整小车的行驶速度。
- **指令格式**`LOGI:SP:VVV:CS#`
- **参数说明**
- `SP`: 命令字 (Set Speed)。
- `VVV`: 速度值3位数字 (000-100)代表百分比或具体PWM占空比等级。
- `000`: 停止
- `050`: 50% 速度
- `100`: 全速
- **示例**
- 设置速度为 **80%**`LOGI:SP:080:04#`
---
### 🧮 校验和算法
为了防止无线信号干扰导致指令错误,我们需要一个简单的校验和。
- **算法**:将 **帧头****数据内容** 结束的所有字符的 ASCII 码值相加,然后对 256 取余,最后转换为 2位十六进制字符串。
- **公式**`Sum = (Byte1 + Byte2 + ... + ByteN) % 256`
**举例计算 (去往 1 号站点):**
1. 原始字符串:`LOGI:GS:001`
2. ASCII 码值相加:
- 'L'(76) + 'O'(79) + 'G'(71) + 'I'(73) + ':'(58) + 'G'(71) + 'S'(83) + ':'(58) + '0'(48) + '0'(48) + '1'(49)
- 总和 = 614
3. 取余:`614 % 256 = 102`
4. 转十六进制:`102` -> `66`
5. 最终发送指令:`LOGI:GS:001:66#`
---
### 💬 小车回复机制 (可选但推荐)
单片机执行指令后,应向上位机返回执行结果,以便上位机显示状态。
**回复格式**`[命令字]:[状态码]:[描述]#`
- **状态码定义**
- `OK`: 指令接收正确并执行。
- `ERR`: 指令格式错误或校验失败。
- `BUSY`: 小车正在忙,无法执行新指令。
**示例回复**
- 成功去往站点:`GS:OK:Arrived#`
- 速度设置成功:`SP:OK:SpeedSet#`
- 校验错误:`CMD:ERR:CheckSum#`
---
### 📌 总结清单
你可以直接将下表发给单片机开发人员:
| 功能 | 指令模板 | 示例 (假设校验和为 XX) | 说明 |
| :--- | :--- | :--- | :--- |
| **去站点** | `LOGI:GS:NNN:XX#` | `LOGI:GS:003:XX#` | NNN为3位站点号 |
| **启动** | `LOGI:ST:RUN:XX#` | `LOGI:ST:RUN:XX#` | 开始运动 |
| **停止** | `LOGI:ST:STOP:XX#` | `LOGI:ST:STOP:XX#` | 立即停止 |
| **设速度** | `LOGI:SP:VVV:XX#` | `LOGI:SP:050:XX#` | VVV为0-100 |
我创建了 处理解析指令的任务和传递消息的消息队列。
![指令处理任务和队列](image-6.png)