Files
car_stm32f103vet6/README.md

310 lines
8.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 嵌入式调试开发指南
## 项目简介
本项目旨在实现基于 STM32F103 的嵌入式开发,支持通过 TCP/IP 协议进行数据传输。以下内容将详细介绍如何配置和使用相关功能。
---
## 环境准备
### 硬件需求
- STM32F103 开发板
- USB 转串口模块
- 连接线
### 软件需求
- 串口调试工具(如 XCOM 或 SecureCRT
- TCP 测试软件
---
## 配置步骤
### 1. 串口配置
1. 选择实际的串口号(如 COM4
2. 设置波特率为 `115200`
### 2. AT 指令操作
#### 配置 Wi-Fi
```bash
AT+CWMODE=1 # 设置工作模式为 STA
AT+CWJAP="ssid","password" # 配置 Wi-Fi
```
#### 连接服务器
```bash
AT+CIPSTART="TCP","192.168.1.101",3456 # 连接服务器IP 为电脑的 IP端口为 3456
AT+SAVETRANSLINK=1,"192.168.1.101",3456,"TCP" # 保存连接信息,开机后自动连接
AT+CIPMODE=1 # 设置为透传模式
AT+CIPSEND # 发送数据
HELLOWORLD # 示例数据
```
#### 退出透传模式
进入自动透传模式后,如需重新配置(如更换 IP需退出透传模式
1. 在串口助手中发送 `+++`
2. 注意:
- 不要勾选“发送新行”。
- 发送 `+++` 后,停顿 1 秒以上不要发送任何数据。
3. 模块返回 `OK` 后,即可重新进入命令模式。
---
## 测试与验证
### 1. 启动服务器
使用 TCP 测试软件创建服务器并启动。
### 2. 实际连接与发送测试
通过串口助手发送数据,验证数据是否成功传输。
---
## 连接示意图
![连接线示意图](image.png)
---
## 常见问题
### 1. 无法连接服务器
- 检查 IP 和端口是否正确。
- 确保 Wi-Fi 配置无误。
### 2. 透传模式无法退出
- 确保发送 `+++` 时未勾选“发送新行”。
- 确保发送后停顿 1 秒以上。
---
## 附录
### 相关工具截图
#### TCP 测试软件
![TCP 测试软件](image-2.png)
#### 创建服务器
![创建服务器](image-3.png)
#### 启动服务器
![启动服务器](image-4.png)
#### 实际连接发送测试
![实际连接发送测试](image-5.png)
---
## 串口重定向
使用以下函数,用于串口重定向:
```c
#ifdef __GNUC__
#define PUTCHAR_PROTOTYPE int __io_putchar(int ch)
#else
#define PUTCHAR_PROTOTYPE int fputc(int ch, FILE *f)
#endif
PUTCHAR_PROTOTYPE {
HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
return ch;
}
```
该函数用于将 `printf` 输出重定向到串口。
---
## TCP 接收与发送
### 接收数据
使用空闲中断接收 TCP 数据,开启了 DMA 接收:
```c
void UART_IDLE_Callback(UART_HandleTypeDef *huart) {
/* 仅处理 USART1 的实例 */
if (huart == NULL || huart->Instance != USART1)
return;
/* 清除空闲中断标志位HAL库宏 */
__HAL_UART_CLEAR_IDLEFLAG(huart);
/* 停止 DMA 以便安全读取计数器并更新状态 */
HAL_UART_DMAStop(huart);
/* 计算接收到的字节数:总缓冲区长度 - DMA 剩余传输计数 */
uint16_t recv_len = UART1_RX_BUF_SIZE - __HAL_DMA_GET_COUNTER(huart->hdmarx);
if (recv_len > 0 && recv_len < UART1_RX_BUF_SIZE) {
uart1_rx_len = recv_len;
uart1_rx_buf[recv_len] = '\0'; /* 添加字符串结束符,方便后续字符串处理 */
uart1_rx_flag = 1; /* 置位标志,通知应用层新消息到达 */
/* 仅供调试在中断中打印接收到的数据注意printf 可能会影响实时性) */
elog_raw("UART1 Received: %s\r\n", (char *)uart1_rx_buf);
}
/* 重新启动新一轮的 DMA 接收 */
HAL_UART_Receive_DMA(&huart1, uart1_rx_buf, UART1_RX_BUF_SIZE);
}
```
### 发送数据
封装了发送函数,只需填入数据即可发送:
```c
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)