# serial_test **Repository Path**: Jichen_Li_good/serial_test ## Basic Information - **Project Name**: serial_test - **Description**: 该仓库主要用于进行串口程序测试,可视化收发数据,采用c和python混合编程的方式来进行开发,后续将集成上位机来进行开发 - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-09 - **Last Updated**: 2026-04-09 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 串口通信协议说明文档 作者:25届HERO 电控组 李纪晨 --- ## 项目结构 ``` serial_test/ ├── drv_CRC.h / drv_CRC.c # CRC8 / CRC16 校验算法 ├── drv_cmd_com.h / drv_cmd_com.c # 串口协议核心(打包/解包/注册) ├── visual_data.h # 所有数据结构和命令ID定义 ├── packet_gen.c # 导出 build_packet(),编译为共享库供Python调用 ├── serial_trans.py # Python串口发送脚本 └── README.md ``` --- ## 帧格式 ``` ┌────────┬────────────┬─────┬──────┬──────────┬────────┐ │ SOF(1) │DataLen(2) │Seq(1)│CRC8(1)│CmdID(2) │Data(N) │ CRC16(2) │ └────────┴────────────┴─────┴──────┴──────────┴────────┘ ``` | 字段 | 长度 | 说明 | |------|------|------| | SOF | 1字节 | 帧头,固定 `0xAA` | | DataLength | 2字节 | Data段字节数(不含帧头、CmdID、CRC16) | | Seq | 1字节 | 包序号,当前固定 `0x01` | | CRC8 | 1字节 | 对 `SOF+DataLength+Seq` 做CRC8校验 | | CmdID | 2字节 | 命令ID,见下方命令ID表 | | Data | N字节 | 数据载荷,长度由 DataLength 决定 | | CRC16 | 2字节 | 对整帧(帧头+CmdID+Data)做CRC16校验 | --- ## 命令ID表 | CmdID | 宏定义 | 数据结构 | 方向 | 说明 | |-------|--------|----------|------|------| | 0x01 | `CMD_ID_VISUAL_CTRL` | `Ctrl_info_t` | 视觉→底盘 | 控制指令(速度+小陀螺) | | 0x02 | `CMD_ID_VISUAL_RADAR` | `visual_data_t` | 视觉→底盘 | 雷达位置数据 | | 0x03 | `CMD_ID_SENTRY_CMD_INFO` | `sentry_cmd_info_t` | 视觉→底盘 | 哨兵自主决策指令 | | 0x04 | `CMD_ID_GAME_INFO` | `Game_info_t` | 底盘→视觉 | 比赛状态 | | 0x05 | `CMD_ID_GAME_ROBOT_survivors` | `Game_robot_survivors_t` | 底盘→视觉 | 机器人血量 | | 0x06 | `CMD_ID_EVENT_DATA` | `Event_data_t` | 底盘→视觉 | 场地事件 | | 0x07 | `CMD_ID_ROBOT_INFO` | `Robot_info_t` | 底盘→视觉 | 机器人自身状态 | | 0x08 | `CMD_ID_ROBOT_POSITION` | `Robot_position_t` | 底盘→视觉 | 机器人位置 | | 0x09 | `CMD_ID_Bullet_remaining` | `Bullet_remaining_t` | 底盘→视觉 | 剩余子弹/金币 | | 0x0A | `CMD_ID_Ground_robot_position` | `Ground_robot_position_t` | 底盘→视觉 | 地面机器人位置 | | 0x0B | `CMD_ID_Sentry_info` | `Sentry_info_t` | 底盘→视觉 | 哨兵决策反馈 | | 0x0C | `CMD_ID_Robot_command_map` | `Robot_command_map_t` | 底盘→视觉 | 云台手点位指令 | | 0x0D | `CMD_ID_Robot_wheel_odometry` | `Robot_wheel_odometry_t` | 底盘→视觉 | 轮式里程计速度 | --- ## 编译共享库 Python 脚本通过 ctypes 调用 `packet_gen.dll`(Windows)或 `packet_gen.so`(Linux)来打包数据帧。 **Windows(MinGW):** ```bash gcc -shared -o packet_gen.dll packet_gen.c drv_CRC.c -D_WIN32 -I. ``` **Linux:** ```bash gcc -shared -fPIC -o packet_gen.so packet_gen.c drv_CRC.c -I. ``` --- ## 运行 Python 脚本 **依赖安装:** ```bash pip uninstall serial # 如果装了错误的serial包先卸载 pip install pyserial ``` **运行:** ```bash python serial_trans.py ``` --- ## 如何修改发送数据 ### 1. 修改发送的数据内容 在 `serial_trans.py` 底部,按照对应结构体的字段顺序用 `struct.pack` 构造字节: ```python # Ctrl_info_t: float x, float y, float w, uint8_t is_tyro, uint16_t virt_yaw data = struct.pack(' `<` 表示小端序,与嵌入式端一致,不要修改。 ### 2. 修改串口号和波特率 ```python send_packet("COM18", 0x01, data, baudrate=115200) # ↑串口号 ↑波特率(默认115200) ``` ### 3. 修改发送次数和间隔 ```python ctypes.windll.winmm.timeBeginPeriod(1) # 提高Windows定时器精度到1ms,必须保留 for i in range(1000): # 修改发送次数 time.sleep(0.001) # 修改发送间隔(单位:秒) send_packet("COM18", 0x01, data) ctypes.windll.winmm.timeEndPeriod(1) # 恢复定时器精度,必须保留 ``` > **注意:** Windows 默认定时器精度为 15.6ms,`timeBeginPeriod(1)` 将其提升到 ~1ms。 > 不调用此函数时,`sleep(0.001)` 实际会睡约 15ms。 ### 4. 发送其他命令ID 参考命令ID表,选择对应结构体,按字段顺序打包: ```python # 发送 Robot_wheel_odometry_t (CmdID=0x0D): float vel_x, float vel_y data = struct.pack('x, ctrl->y, ctrl->w ... } Attach_Receive_callback(CMD_ID_VISUAL_CTRL, sizeof(Ctrl_info_t), &ctrl_info, on_ctrl_received); // 在接收中断或线程中调用 Receive_Handle(rx_buffer, rx_size); ```