# TCP2UART AT 固件使用手册

## 1. 文档说明

本文档用于说明 `TCP2UART` 固件的 `AT` 配置功能使用方法。

本手册适用于当前工程中的 STM32 固件版本，配置口通过 `USART1` 提供，主要用于：

- 查询当前设备参数
- 修改网络参数
- 修改串口透传参数
- 保存参数到 Flash
- 恢复默认参数
- 软件复位设备

本文档内容基于以下信息整理：

- 当前代码实现 `App/config.c`、`App/config.h`
- 当前默认配置定义
- 实板测试结果
- `uart-ch390-debug-handoff.md` 中已记录的 bench 经验

## 1.1 版本更新说明（2026-04-02）

为避免引入额外时序噪声与误判，当前固件已移除 CH390 的 bit-bang 诊断读路径。

当前版本仅保留 CH390 硬件 SPI 访问路径，启动探测与运行期寄存器访问均通过统一 SPI 接口执行。

## 2. 适用硬件

- 主控：`STM32F103R8T6`
- 以太网芯片：`CH390D`
- 配置串口：`USART1`
- 透传串口：`USART2`、`USART3`

当前引脚用途如下：

- `PA9`：`USART1_TX`，配置口发送
- `PA10`：`USART1_RX`，配置口接收
- `PA2/PA3`：`USART2`，对应 TCP Server 透传串口
- `PB10/PB11`：`USART3`，对应 TCP Client 透传串口

## 3. 配置口通信参数

连接配置口时，使用以下串口参数：

- 波特率：`115200`
- 数据位：`8`
- 校验位：`None`
- 停止位：`1`

## 4. 最重要的使用规则

### 4.1 推荐使用 `\n` 作为命令结尾

这是当前固件 bench 联调中最重要的一条经验。

在当前实板联调中，使用 `\n` 结尾是最稳妥的做法。例如：

```text
AT\n
AT+?\n
AT+IP=192.168.1.123\n
```

代码中的帧接收逻辑会在收到 `\r` 或 `\n` 时结束当前命令，但当前 bench 记录表明，实际使用时优先采用 `\n` 结尾更可靠。如果上位机默认发送 `\r\n` 后看起来“设备没有响应”，优先改成只发送 `\n` 再测试。

### 4.2 修改参数后不会立刻写入 Flash

大多数设置命令只会先修改 RAM 中的当前配置，不会自动写入 Flash。

如果要让参数在复位或重新上电后继续保持，必须执行：

1. `AT+SAVE`
2. `AT+RESET`

### 4.3 `AT+DEFAULT` 只恢复当前默认值，不自动保存

执行 `AT+DEFAULT` 后，当前参数会恢复为默认值，但如果要让默认值持久生效，仍然需要：

1. `AT+SAVE`
2. `AT+RESET`

## 5. 默认参数

当前固件默认值如下：

| 参数 | 默认值 |
|------|--------|
| MAC | `02:00:00:00:00:01` |
| DHCP | `0` |
| IP | `192.168.1.100` |
| MASK | `255.255.255.0` |
| GW | `192.168.1.1` |
| PORT | `8080` |
| RIP | `192.168.1.200` |
| RPORT | `9000` |
| BAUD1 | `115200` |
| BAUD2 | `115200` |

说明：

- `BAUD1` 对应 `USART2`，即 TCP Server 对应的透传串口
- `BAUD2` 对应 `USART3`，即 TCP Client 对应的透传串口

## 6. AT 命令总览

当前固件支持以下命令：

- `AT`
- `AT+?`
- `AT+QUERY`
- `AT+IP=...`
- `AT+MASK=...`
- `AT+GW=...`
- `AT+RIP=...`
- `AT+MAC=...`
- `AT+PORT=...`
- `AT+RPORT=...`
- `AT+BAUD1=...`
- `AT+BAUD2=...`
- `AT+DHCP=0`
- `AT+SAVE`
- `AT+RESET`
- `AT+DEFAULT`

## 7. 命令详细说明

### 7.1 测试设备在线

命令：

```text
AT\n
```

返回：

```text
OK
```

用途：

- 用于确认配置口通信正常

### 7.2 查询当前参数

命令 1：

```text
AT+?\n
```

命令 2：

```text
AT+QUERY\n
```

返回示例：

```text
MAC: 02:00:00:00:00:01
DHCP: 0
IP: 192.168.1.100
MASK: 255.255.255.0
GW: 192.168.1.1
PORT: 8080
RIP: 192.168.1.200
RPORT: 9000
BAUD1: 115200
BAUD2: 115200
```

用途：

- 查询当前运行配置
- 可用于保存前后、复位前后对比参数是否一致

### 7.3 设置设备 IP 地址

命令：

```text
AT+IP=192.168.1.123\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid IP format
```

说明：

- 推荐使用标准 IPv4 点分十进制格式
- 当前参数会立即更新到 RAM
- 需要 `AT+SAVE` 和 `AT+RESET` 后才会以持久配置重新启动

### 7.4 设置子网掩码

命令：

```text
AT+MASK=255.255.255.0\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid mask format
```

### 7.5 设置网关

命令：

```text
AT+GW=192.168.1.1\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid gateway format
```

### 7.6 设置远端服务器 IP

命令：

```text
AT+RIP=192.168.1.201\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid remote IP format
```

说明：

- 该参数用于 TCP Client 主动连接的目标地址

### 7.7 设置 MAC 地址

命令：

```text
AT+MAC=02:12:34:56:78:9A\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid MAC format
```

说明：

- 推荐使用 `:` 分隔的标准 MAC 字符串
- 当前实现也兼容 `-` 分隔格式

### 7.8 设置 TCP Server 监听端口

命令：

```text
AT+PORT=10001\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid port
```

说明：

- 推荐使用 `1 ~ 65535` 范围内的十进制端口号

### 7.9 设置 TCP Client 远端端口

命令：

```text
AT+RPORT=10002\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid port
```

说明：

- 推荐使用 `1 ~ 65535` 范围内的十进制端口号

### 7.10 设置 USART2 波特率

命令：

```text
AT+BAUD1=57600\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid baudrate
```

说明：

- `BAUD1` 对应 `USART2`
- 推荐使用 `1200 ~ 921600` 范围内的标准波特率值

### 7.11 设置 USART3 波特率

命令：

```text
AT+BAUD2=38400\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回：

```text
ERROR: Invalid baudrate
```

说明：

- `BAUD2` 对应 `USART3`
- 推荐使用 `1200 ~ 921600` 范围内的标准波特率值

### 7.12 设置 DHCP

命令：

```text
AT+DHCP=0\n
```

成功返回：

```text
OK
Note: Use AT+SAVE then AT+RESET to apply changes
```

失败返回 1：

```text
ERROR: Invalid value
```

失败返回 2：

```text
ERROR: DHCP disabled in this build
```

说明：

- 当前固件构建不支持 DHCP
- 因此 `AT+DHCP=1` 会明确返回失败
- 当前版本建议固定使用静态 IP

### 7.13 保存参数到 Flash

命令：

```text
AT+SAVE\n
```

成功返回：

```text
OK: Configuration saved
```

失败返回：

```text
ERROR: Save failed
```

用途：

- 将当前 RAM 中的配置写入 Flash
- 只有执行成功后，参数才会在复位后保留

### 7.14 软件复位设备

命令：

```text
AT+RESET\n
```

返回：

```text
OK: Resetting...
```

用途：

- 请求设备执行软件复位
- 通常用于 `AT+SAVE` 之后让新配置重新生效

### 7.15 恢复默认参数

命令：

```text
AT+DEFAULT\n
```

返回：

```text
OK: Defaults restored
```

用途：

- 将当前配置恢复为固件默认值
- 如果要让默认值长期生效，仍然需要再执行 `AT+SAVE` 和 `AT+RESET`

## 8. 常见错误返回

当前固件已验证的错误返回如下：

| 场景 | 返回 |
|------|------|
| 未知命令 | `ERROR: Unknown command` |
| 非法端口 | `ERROR: Invalid port` |
| 非法波特率 | `ERROR: Invalid baudrate` |
| 非法 IP 地址 | `ERROR: Invalid IP format` |
| 非法掩码 | `ERROR: Invalid mask format` |
| 非法网关 | `ERROR: Invalid gateway format` |
| 非法远端 IP | `ERROR: Invalid remote IP format` |
| 非法 MAC | `ERROR: Invalid MAC format` |
| 非法 DHCP 参数 | `ERROR: Invalid value` |
| DHCP 在当前构建中不可用 | `ERROR: DHCP disabled in this build` |
| Flash 保存失败 | `ERROR: Save failed` |

## 9. 推荐操作流程

### 9.1 查询当前参数

```text
AT\n
AT+?\n
```

### 9.2 修改参数并永久保存

例如修改设备 IP、监听端口和远端地址：

```text
AT+IP=192.168.1.123\n
AT+PORT=10001\n
AT+RIP=192.168.1.201\n
AT+RPORT=10002\n
AT+SAVE\n
AT+RESET\n
```

设备复位后，再执行：

```text
AT+?\n
```

确认参数是否与修改值一致。

### 9.3 恢复出厂默认参数

```text
AT+DEFAULT\n
AT+SAVE\n
AT+RESET\n
AT+?\n
```

## 10. Flash 持久化说明

当前固件已在实板上验证以下保存/复位路径：

- 设置参数后执行 `AT+SAVE`
- 再执行 `AT+RESET`
- 设备重启后再次查询参数
- 查询结果与保存前一致
- 原始 Flash 参数页 `0x0800FC00` 在 reset 前后读回一致

这说明在上述测试路径下：

- 配置确实被写入 Flash
- reset 后加载流程正常
- 参数在 `设置 -> 保存 -> 复位 -> 查询` 这条路径下可以保持一致

## 11. 故障排查建议

### 11.1 发送 `AT` 没有返回

优先检查以下几项：

1. 是否连接到了 `USART1`
2. 串口参数是否为 `115200 8N1`
3. 是否优先使用 `\n` 作为命令结尾
4. USB 转串口模块接线是否正确
5. 设备是否已经正常上电运行

### 11.2 设置成功但重启后参数丢失

检查是否漏掉了以下步骤：

1. `AT+SAVE`
2. `AT+RESET`

如果只执行设置命令但没有保存，参数只会停留在当前 RAM 中。

### 11.3 `AT+DHCP=1` 失败

这是当前固件设计行为，不是故障。

当前构建不支持 DHCP，因此：

```text
AT+DHCP=1\n
```

返回：

```text
ERROR: DHCP disabled in this build
```

## 12. 已实测通过的命令行为

本手册中的以下命令行为已经在实板上验证通过：

- `AT`
- `AT+?`
- `AT+QUERY`
- `AT+IP=...`
- `AT+MASK=...`
- `AT+GW=...`
- `AT+RIP=...`
- `AT+MAC=...`
- `AT+PORT=...`
- `AT+RPORT=...`
- `AT+BAUD1=...`
- `AT+BAUD2=...`
- `AT+DHCP=0`
- `AT+SAVE`
- `AT+RESET`
- `AT+DEFAULT`

已实测通过的错误路径包括：

- `AT+UNKNOWN`
- `AT+PORT=0`
- `AT+PORT=65536`
- `AT+BAUD1=1199`
- `AT+BAUD1=921601`
- `AT+DHCP=1`
- `AT+IP=999.1.1.1`
- `AT+MAC=GG:11:22:33:44:55`

## 13. 相关文件

- AT 命令实现：[config.c](/D:/code/STM32Project/TCP2UART/App/config.c)
- 配置结构与默认值：[config.h](/D:/code/STM32Project/TCP2UART/App/config.h)
- 调试与测试记录：[uart-ch390-debug-handoff.md](/D:/code/STM32Project/TCP2UART/uart-ch390-debug-handoff.md)
