Files
car_stm32f103vet6/README.md

499 lines
15 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.
# 物流小车嵌入式控制系统STM32F103TCP/IP
# Logistics AGV Embedded System (STM32F103, TCP/IP)
---
## 📖 项目简介 | Project Overview
本项目为基于 STM32F103 的物流小车AGV嵌入式控制系统支持 TCP/IP 局域网通信、RFID 站点识别、红外循迹、超声避障、电机闭环控制等功能。适用于智能仓储、自动运输等场景。
This project is an embedded control system for a logistics AGV based on STM32F103, supporting TCP/IP LAN communication, RFID station recognition, IR line tracking, ultrasonic obstacle avoidance, and closed-loop motor control. Suitable for smart warehouse and auto-transport scenarios.
---
## 📦 目录结构 | Directory Structure
```
├── Core/ # 主代码BSP、驱动、协议、控制任务等
│ ├── Bsp/ # 板级支持包电机、PID、循迹、RFID、超声、串口等
│ ├── Inc/ # 头文件
│ └── Src/ # CubeMX自动生成及主循环
├── Drivers/ # HAL库、CMSIS等外部驱动
├── Middlewares/ # 第三方中间件如FreeRTOS
├── build/ # 构建输出
├── cmake/ # CMake工具链与脚本
├── 物流小车/ # 机械结构、上位机、3D模型、调试工具
│ ├── 3D/ # 机械3D模型SolidWorks/STEP
│ ├── esp_12f/ # ESP-12F相关工具
│ └── web/ # 上位机/调试脚本
├── CMakeLists.txt # CMake主构建脚本
├── f103_car.ioc # CubeMX工程文件
└── README.md # 项目说明文档
```
---
## 🛠️ 硬件与软件需求 | Hardware & Software Requirements
### 硬件 | Hardware
- STM32F103ZET6 开发板
- ESP-12F WiFi模块TCP透传
- AT8236-MS 电机驱动板 + 4路直流电机
- 霍尔测速传感器 ×4
- 红外循迹模块 ×4
- 超声波测距模块HC-SR04
- RC522 RFID读卡器
- 3.3V/5V 电源、线缆、机械底盘
### 软件 | Software
- Keil/STM32CubeIDE/GCC + CMake
- FreeRTOS
- 串口调试助手XCOM/SecureCRT
- TCP调试工具NetAssist等
- SolidWorks/STEP查看器3D结构
---
## ⚙️ 编译与烧录 | Build & Flash
1. 安装依赖HAL库、FreeRTOS、CMake等
2. 用 STM32CubeMX 生成代码f103_car.ioc
3. CMake 构建:
```sh
mkdir build && cd build
cmake .. -G "Ninja"
ninja
```
4. 用 JLink/ST-Link 烧录 .elf/.bin 到开发板
5. ESP-12F 配置为 TCP Server波特率115200透传模式
---
## 🚗 功能总览 | Features
- TCP/IP 通信协议,支持上位机远程控制与状态监控
- RFID 站点识别与到站锁存
- 红外循迹4路/5路带去抖与方向判定
- 超声波避障(自动停车/恢复)
- 电机PWM闭环控制PID支持死区补偿
- 任务调度与消息队列FreeRTOS
- 详细日志输出EasyLogger
---
## 📡 通信协议 | Communication Protocol
### 指令帧结构 | Frame Structure
```
LOGI:<PAYLOAD>:<CS>#
```
- LOGI: 固定帧头
- <PAYLOAD>: 有效载荷(如 ST:RUN、GS:001
- <CS>: 2字节十六进制校验和从'L'累加到最后一个冒号前)
- #: 帧尾
### 下行指令(上位机→小车)| Downlink (PC→Car)
| 功能 | 指令格式 | 示例 | 说明 |
|------|----------|------|------|
| 设置站点 | LOGI:GS:NNN:CS# | LOGI:GS:001:CA# | NNN为3位站点号 |
| 启动运行 | LOGI:ST:RUN:CS# | LOGI:ST:RUN:3B# | 启动自动循迹 |
| 停止运行 | LOGI:ST:STOP:CS# | LOGI:ST:STOP:8C# | 急停/暂停 |
| 设置速度 | LOGI:SP:VVV:CS# | LOGI:SP:050:D7# | VVV为000-100 |
### 上行遥测(小车→上位机)| Uplink (Car→PC)
- 周期状态:
`LOGI:STAT:SP:050,STA:001,RUN:1,DIS:12.5,TRK:0010,RPM:25:25:25:25:CS#`
- 指令反馈:
`LOGI:FB:GS:1:A5#`1=成功0=失败)
### 校验和算法 | Checksum
所有字符ASCII累加取低8位转2位十六进制。
```python
def calculate_cs(data_str):
return sum(data_str.encode('ascii')) & 0xFF
```
---
## 🧩 主要模块说明 | Main Modules
### 1. 电机与PID | Motor & PID
- 4路PWM控制AT8236-MS驱动支持正反转与刹车
- PID参数可调支持死区补偿闭环速度控制
### 2. 霍尔测速 | Hall Speed
- 外部中断计数定时计算RPM支持实时测速
### 3. 红外循迹 | IR Tracking
- 4路/5路红外带去抖与方向判定支持丢线/十字/偏移等状态
### 4. 超声波避障 | Ultrasonic
- HC-SR04DWT微秒级测距自动停车/恢复
### 5. RFID站点 | RFID Station
- RC522UID白名单匹配支持多站点扩展到站自动锁存
### 6. 串口与TCP | UART & TCP
- UART1+DMAESP-12F透传TCP空闲中断帧接收
### 7. 协议栈 | Protocol
- 指令解析、校验、消息队列、状态上报、反馈应答
---
## 🚦 典型使用流程 | Typical Workflow
1. 上电ESP-12F配置为TCP Server波特率115200透传模式
2. 上位机通过TCP工具连接小车IP/端口
3. 发送 `LOGI:GS:001:XX#` 设置目标站点
4. 发送 `LOGI:ST:RUN:XX#` 启动小车
5. 小车自动循迹遇障碍自动停车RFID到站自动锁存
6. 上位机周期接收状态帧,随时可发 `STOP`/`SP:xxx` 控制
---
## 🖥️ 上位机开发建议 | PC/Host Development
- 推荐用 Python/C#/LabVIEW 等实现 TCP 客户端,直接发送/解析 ASCII 指令
- 校验和算法见上,协议字段可扩展
- 参考 `Core/Bsp/up_readme.md` 获取协议范例
---
## 🛠️ 调试与常见问题 | Debug & FAQ
### 1. 无法连接TCP
- 检查IP/端口/波特率/透传配置
- 确认ESP-12F与主控串口连接正常
### 2. 指令无响应/校验失败
- 检查指令格式与校验和
- 查看串口/网络日志
### 3. RFID/循迹/测速异常
- 检查硬件连线、电源、模块初始化
- 查看日志与状态上报帧
### 4. CubeMX生成代码被覆盖
- 用户代码请写在 `USER CODE BEGIN ... END` 区域
- 驱动/业务任务建议放在 `Core/Bsp/`,主循环仅调用接口
---
## 🤝 贡献与联系方式 | Contributing & Contact
- 欢迎提交PR、Issue或邮件联系作者
- Author: Beihong Wang
- Email: [your_email@example.com]
- 日期/Date: 2026-04-16
---
## 📝 附录 | Appendix
- 详细协议范例、上位机代码、硬件原理图、3D模型等请见 `Core/Bsp/up_readme.md`、`物流小车/3D/`、`物流小车/web/`
- 关键代码均含中文注释,便于二次开发与维护
---
> 本文档中英双语,便于团队协作与国际交流。后续如有更新请及时同步。
## 测试与验证
### 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 通信协议 (v1.2)
本项目采用自定义 ASCII 协议进行上位机控制与状态监控。
### 1. 指令帧结构
`LOGI:<PAYLOAD>:<CS>#`
- **LOGI**: 固定帧头
- **PAYLOAD**: 有效载荷 (详见下表)
- **CS**: 2字节十六进制校验和 (从 'L' 累加到 ':' 之前)
- **#**: 固定帧尾
### 2. 控制指令 (上位机 -> 小车)
| 功能 | 指令格式 | 示例 | 说明 |
| :--- | :--- | :--- | :--- |
| **设置站点** | `GS:NNN` | `LOGI:GS:001:CA#` | NNN为3位站点号 (支持 001/002) |
| **启动运行** | `ST:RUN` | `LOGI:ST:RUN:3B#` | 开始任务 (必须先设有效站点) |
| **停止运行** | `ST:STOP` | `LOGI:ST:STOP:8C#` | 立即停止 |
| **设置速度** | `SP:VVV` | `LOGI:SP:050:D7#` | VVV为000-100 (百分比) |
### 3. 上行遥测 (小车 -> 上位机)
#### 3.1 状态推送 (每 500ms 推送一次)
**格式**: `LOGI:STAT:SP:速度,STA:站点,RUN:运行,DIS:距离,TRK:循迹状态,RPM:M1:M2:M3:M4:CS#`
**字段**:
- `SP`: 当前速度 %
- `STA`: 目标站点号
- `RUN`: 运行状态 (1:运行, 0:停止)
- `DIS`: 避障距离 (cm)
- `TRK`: 4位红外状态 (0/1组合, 顺序为 H4 H3 H2 H1)
- `RPM`: 四路电机实际转速,以 `:` 分隔 (顺序为 LR:LF:RF:RR)
#### 3.2 指令反馈 (即时回复)
**格式**: `LOGI:FB:指令类型:状态值:CS#`
**示例**: `LOGI:FB:GS:1:A5#` (1代表成功, 0代表失败)
---
### 4. 业务逻辑约束
1. **到站锁存**: 到达站点后小车自动停下,`RUN` 变为 0。
2. **解锁流程**: 车辆停稳后,必须重新发送 `GS` 指令设置新站点(或覆盖旧站点),方可再次发送 `ST:RUN` 启动。否则,小车将报警并拒绝运行。
这些是上位机发送的指令:
按照这些来写代码
这是一个基于 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)