项目目标:
调试遥控器数据读取的源代码(厂家提供),让STM32可以读取到遥控手柄的数据;验证遥控器的性能(延迟以及最远遥控距离);在上位机(QT5,python)上实时以图形化显示遥控手柄状态。任务分解:
1、STM32读取遥控器数据,并通过串口转发至上位机
2、在上位机上以图形方式显示控制状态(手柄状态)
技术栈:
STM32/SPI接口,蓝牙,上位机/QT/Python
硬件说明:
stm32最小系统板,PS2手柄,PS2手柄无线接收器,横插转接板,UART串口
实现过程与思路:
1.明确项目目标:实现一个“遥控器数据读取与图形化显示”的系统,涉及STM32、上位机(QT/Python)和遥控器三个主要部分。
2.厘清数据流向:确定整个系统的数据流动路径:遥控手柄 → 接收器 → STM32 → 上位机(电脑)
3.识别接口类型:明确串口(UART)通信/类SPI协议的PS2手柄接收器的引脚使用方法。
4.确定硬件连接方案:基于对接口类型的使用,明确连接方式。
5.写出单片机执行代码:分两部分。先写出下位机的执行代码,初始化硬件使其正常工作;随后查询技术手册明确该硬件的信息上传方式与解析方式,在STM32端解码信号并使用串口上传信息。
6.烧录程序后,打开串口助手,收到来自单片机的 PS2 手柄数据流,确认串口数据能正常接收,且数据流稳定,证明硬件连接、单片机程序和串口电平都是正确的
7.配置库,让 Python 连接到 串口,利用上位机解析数据流并作出对应的反应。
8.测试功能是否完全实现,测试最大传输距离和延迟。此时即可认为此项目完成。
具体操作:
第一步:硬件连接
将PS2接收器与STM32开发板正确连接
引脚对应关系:
特别注意电源电压!
| 接收器引脚 | 功能说明 | 连接至 STM32 | 注意事项 |
|---|---|---|---|
VCC | 电源 | 3.3V | 严禁接5V,否则可能烧毁模块 |
GND | 地线 | GND | 必须与STM32共地 |
DAT/DI | 数据输入(接收器→STM32) | PA4 | 配置为输入模式 |
CMD | 命令输出(STM32→接收器) | PA5 | 配置为输出模式 |
CS | 片选信号 | PA6 | 配置为输出模式,低电平有效 |
CLK | 时钟信号 | PA7 | 配置为输出模式,频率建议50-100kHz |
第二步:STM32端编程
这个阶段的目标是让STM32读懂手柄的数据,并通过串口发送给电脑。
创建工程并配置GPIO:
使用Keil5创建工程,选择芯片型号(STM32F103C8T6)。
将第一步中选定的GPIO引脚分别配置为输入或输出模式。
同时,配置一个串口(UART)(如USART1,使用
PA9/PA10),用于后续与电脑通信。生成初始化代码。
编写PS2通信协议:
PS2手柄使用的是类SPI的同步串行通信协议。通信时,CS引脚为低电平,数据在时钟CLK的下降沿进行传输。实现方式:选择软件模拟SPI或硬件SPI(效率更高)。
通信时序:STM32通过
CMD引脚发送命令,同时从DAT引脚读取数据。一个典型的读取流程如下:拉低
CS,开始一次通信。STM32发送命令
0x01,接收器会回复其ID(如0x41表示绿灯模式,0x73表示红灯模式)。STM32接着发送命令
0x42,请求手柄数据。接收器会回复
0x5A,表示“数据来了”。随后,接收器会连续发送多个字节的数据包,包含所有按键和摇杆的状态。
解析手柄数据:
接收器发回的数据包通常包含9个字节(Data[0]~Data[8])。Data[3]和Data[4]:用于存放按键值。当某个按键被按下时,其对应的位会被置为0。例如,SELECT键按下时,Data[3]变为1111 1110。Data[5]~Data[8]:用于存放摇杆的模拟量(0x00~0xFF)。代码需要根据协议解析出这些原始数据,并将其转换为有意义的数值。
通过串口发送数据:
将解析好的数据(如各个按键的状态、摇杆的X/Y轴数值)按照自定义的格式(例如:X:128, Y:200, KEY:0x0F\n),通过之前配置好的串口发送给电脑。
第三步:上位机开发
编写一个运行在电脑上的程序,来接收数据并图形化显示。
选择开发环境:
使用Python结合PyQt5(用于创建图形界面)和pyqtgraph(用于快速绘图)。
安装必要的库:
pip install pyqt5 pyqtgraph pyserial
实现串口通信:
使用
pyserial库来打开、读取和关闭与STM32连接的串口,
解析并显示数据:
读取从串口接收到的数据字符串。
按照在STM32端定义的数据格式,解析出各个数据项。
将解析出的数据实时更新到图形界面的对应控件上。
设计图形界面:
坐标映射算法:摇杆值是 0~255,中心点为 128。引入了 反误触(Deadzone=15),即 |值-128| < 15 时视为归零。
速度控制:引入
speed_scale变量。计算偏移量dx = (值-128) / 50,让移动顺滑而不跳帧。边界碰撞:小球不能跑出画布,所以每次更新坐标时,用
max(半径, min(画布宽-半径, 新坐标))进行钳位。多线程隔离:串口读取线程(
read_loop)和界面刷新线程(update_gui)分离。具体操作是使用 Python 的queue.Queue传递数据,避免串口堵塞导致界面卡死。
最后,将软硬件整合起来,进行调试。
分步测试:
电源测试:给STM32上电,检查接收器上的指示灯是否正常。
STM32测试:将STM32的串口连接到电脑,用串口调试助手查看是否有数据输出,输出格式是否正确。
上位机测试:先使用串口调试助手发送一些模拟数据,看上位机能否正确解析和显示。
联合调试:
将STM32和上位机连接起来,实际操作手柄,观察上位机的显示是否与操作同步。
如果数据异常,检查硬件连接是否牢固,通信时序是否正确,数据解析逻辑是否有误。
3.完成上述后,测试最大通信距离与延迟,实测信号可以传输约7m,延迟测试结果波动较}
大
至此,该项目完成
图片: