wangbeihong 1cc8327f13 特性:实现电机控制与霍尔传感器功能
新增电机板级支持包:基于 AT8236-MS 驱动芯片,实现了对 4 个直流电机的 PWM 控制。
实现霍尔传感器功能:用于速度测量和脉冲计数。
更新 GPIO 初始化:为霍尔传感器添加了外部中断(EXTI)配置。
修改系统时钟配置:改用高速外部时钟(HSE)并调整了锁相环(PLL)设置。
更改定时器配置:将时基生成从 TIM8 改为 TIM4。
增强 FreeRTOS 任务:实现从霍尔传感器周期性读取并更新速度数据。
更新项目配置:以反映外设使用情况和优先级的变更。
2026-04-03 20:24:55 +08:00

嵌入式调试开发指南

项目简介

本项目旨在实现基于 STM32F103 的嵌入式开发,支持通过 TCP/IP 协议进行数据传输。以下内容将详细介绍如何配置和使用相关功能。


环境准备

硬件需求

  • STM32F103 开发板
  • USB 转串口模块
  • 连接线

软件需求

  • 串口调试工具(如 XCOM 或 SecureCRT
  • TCP 测试软件

配置步骤

1. 串口配置

  1. 选择实际的串口号(如 COM4
  2. 设置波特率为 115200

2. AT 指令操作

配置 Wi-Fi

AT+CWMODE=1  # 设置工作模式为 STA
AT+CWJAP="ssid","password"  # 配置 Wi-Fi

连接服务器

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. 实际连接与发送测试

通过串口助手发送数据,验证数据是否成功传输。


连接示意图

连接线示意图


常见问题

1. 无法连接服务器

  • 检查 IP 和端口是否正确。
  • 确保 Wi-Fi 配置无误。

2. 透传模式无法退出

  • 确保发送 +++ 时未勾选“发送新行”。
  • 确保发送后停顿 1 秒以上。

附录

相关工具截图

TCP 测试软件

TCP 测试软件

创建服务器

创建服务器

启动服务器

启动服务器

实际连接发送测试

实际连接发送测试


串口重定向

使用以下函数,用于串口重定向:

#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 接收:

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);
}

发送数据

封装了发送函数,只需填入数据即可发送:

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号站写为 00112号站写为 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

我创建了 处理解析指令的任务和传递消息的消息队列。 指令处理任务和队列

Description
物流小车
Readme 268 MiB
Languages
C 97.8%
Assembly 1.9%
C++ 0.2%