当前位置: 首页 > news >正文

手把手教你用Python实现树莓派与STM32的串口数据交互(附完整代码)

树莓派与STM32串口通信实战:从硬件配置到Python代码实现

在物联网和嵌入式系统开发中,串口通信是最基础也最可靠的设备间通信方式之一。树莓派作为一款功能强大的微型计算机,与STM32这类嵌入式微控制器的组合,能够为智能家居、工业自动化、机器人控制等场景提供灵活的解决方案。本文将带你从零开始,完成树莓派与STM32之间的串口通信全流程实现。

1. 硬件准备与环境配置

1.1 所需硬件清单

在开始之前,请确保你已准备好以下硬件设备:

  • 树莓派(推荐3B+/4B型号,配备40针GPIO接口)
  • STM32开发板(如STM32F103C8T6最小系统板)
  • USB转TTL模块(用于调试,如CH340G或CP2102)
  • 杜邦线若干(建议使用母对母或公对母线)
  • 电源供应(树莓派专用电源和STM32的供电)

1.2 树莓派串口引脚说明

树莓派的GPIO接口上有两个串口相关引脚:

引脚编号功能物理引脚位置
GPIO 14TXD第8针
GPIO 15RXD第10针

重要提示:树莓派的串口默认是作为控制台使用的,我们需要先修改配置才能用于普通串口通信。

1.3 树莓派串口配置步骤

  1. 首先通过SSH或直接连接显示器键盘登录树莓派
  2. 执行以下命令更新系统:
sudo apt update && sudo apt upgrade -y
  1. 使用raspi-config工具配置串口:
sudo raspi-config

在界面中选择:

  • 3 Interface Options
  • P6 Serial Port
  • 当询问"Would you like a login shell to be accessible over serial?"时选择No
  • 当询问"Would you like the serial port hardware to be enabled?"时选择Yes
  1. 禁用蓝牙以释放硬件串口(可选):
sudo nano /boot/config.txt

在文件末尾添加:

dtoverlay=pi3-disable-bt

保存后重启树莓派:

sudo reboot

2. STM32端串口配置

2.1 STM32硬件连接

以常见的STM32F103C8T6为例,串口引脚通常为:

  • USART1_TX- PA9
  • USART1_RX- PA10

连接方式如下:

树莓派引脚STM32引脚
TX (GPIO14)RX (PA10)
RX (GPIO15)TX (PA9)
GNDGND

2.2 STM32串口初始化代码

以下是使用HAL库的STM32串口初始化代码示例:

// 在main.c中添加以下代码 UART_HandleTypeDef huart1; void SystemClock_Config(void); static void MX_GPIO_Init(void); static void MX_USART1_UART_Init(void); int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); MX_USART1_UART_Init(); char welcome[] = "STM32 Ready\r\n"; HAL_UART_Transmit(&huart1, (uint8_t*)welcome, strlen(welcome), HAL_MAX_DELAY); while (1) { // 主循环 } } static void MX_USART1_UART_Init(void) { huart1.Instance = USART1; huart1.Init.BaudRate = 115200; huart1.Init.WordLength = UART_WORDLENGTH_8B; huart1.Init.StopBits = UART_STOPBITS_1; huart1.Init.Parity = UART_PARITY_NONE; huart1.Init.Mode = UART_MODE_TX_RX; huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE; huart1.Init.OverSampling = UART_OVERSAMPLING_16; if (HAL_UART_Init(&huart1) != HAL_OK) { Error_Handler(); } }

3. Python串口通信实现

3.1 安装Python串口库

在树莓派上安装pyserial库:

pip install pyserial

3.2 基础串口通信代码

创建一个名为serial_comm.py的文件,内容如下:

import serial import time class STM32Communicator: def __init__(self, port='/dev/ttyAMA0', baudrate=115200, timeout=1): self.ser = serial.Serial(port, baudrate, timeout=timeout) time.sleep(2) # 等待串口初始化 def send_command(self, command): try: self.ser.write(command.encode('utf-8')) print(f"Sent: {command}") return True except Exception as e: print(f"Send error: {e}") return False def read_response(self, timeout=1): start_time = time.time() response = b'' while time.time() - start_time < timeout: if self.ser.in_waiting > 0: response += self.ser.read(self.ser.in_waiting) if response: print(f"Received: {response.decode('utf-8')}") return response.decode('utf-8') return None def close(self): self.ser.close() if __name__ == "__main__": communicator = STM32Communicator() try: while True: # 发送数据到STM32 communicator.send_command("Hello STM32\r\n") # 读取STM32的响应 response = communicator.read_response() time.sleep(1) except KeyboardInterrupt: print("Exiting...") finally: communicator.close()

3.3 数据帧协议设计

在实际项目中,我们需要定义通信协议来确保数据的可靠性。下面是一个简单的帧结构设计:

字段起始标志数据长度数据内容校验和结束标志
字节1 (0xAA)1N11 (0x55)

对应的Python实现:

def calculate_checksum(data): return sum(bytearray(data, 'utf-8')) % 256 def create_frame(data): start_byte = 0xAA end_byte = 0x55 length = len(data) checksum = calculate_checksum(data) frame = bytearray() frame.append(start_byte) frame.append(length) frame.extend(data.encode('utf-8')) frame.append(checksum) frame.append(end_byte) return frame def parse_frame(frame): if len(frame) < 5: return None if frame[0] != 0xAA or frame[-1] != 0x55: return None length = frame[1] data = frame[2:2+length].decode('utf-8') received_checksum = frame[-2] if calculate_checksum(data) != received_checksum: return None return data

4. 高级应用与性能优化

4.1 多线程串口通信

对于需要同时处理串口数据和其他任务的应用,可以使用Python的threading模块:

import threading class SerialThread(threading.Thread): def __init__(self, port='/dev/ttyAMA0', baudrate=115200): threading.Thread.__init__(self) self.ser = serial.Serial(port, baudrate) self.running = True self.callback = None def run(self): while self.running: if self.ser.in_waiting > 0: data = self.ser.read(self.ser.in_waiting) if self.callback: self.callback(data) def stop(self): self.running = False self.ser.close() def send_data(self, data): self.ser.write(data)

4.2 串口通信性能优化技巧

  1. 缓冲区管理

    • 设置适当的读取超时(timeout)和缓冲区大小
    • 定期清空输入缓冲区避免数据堆积
  2. 波特率选择

    • 对于短距离通信,115200是比较稳定的选择
    • 长距离或干扰环境可降低到9600或19200
  3. 错误处理

    • 添加重试机制应对偶发的通信失败
    • 实现心跳包检测连接状态
def robust_send(ser, data, max_retries=3): for attempt in range(max_retries): try: ser.write(data) return True except serial.SerialException as e: print(f"Attempt {attempt+1} failed: {e}") time.sleep(0.1) return False

4.3 实际项目集成示例

将串口通信集成到传感器数据采集系统中:

import json from datetime import datetime class SensorMonitor: def __init__(self): self.serial = STM32Communicator() self.sensor_data = { 'temperature': 0, 'humidity': 0, 'timestamp': '' } def update_sensors(self): self.serial.send_command("GET_SENSORS\r\n") response = self.serial.read_response() if response: try: # 假设返回格式为 "TEMP:25.6,HUM:45.2" parts = response.strip().split(',') temp_part = parts[0].split(':') hum_part = parts[1].split(':') self.sensor_data['temperature'] = float(temp_part[1]) self.sensor_data['humidity'] = float(hum_part[1]) self.sensor_data['timestamp'] = datetime.now().isoformat() return True except (IndexError, ValueError) as e: print(f"Parse error: {e}") return False def save_to_database(self): # 这里可以添加数据库存储逻辑 with open('sensor_log.json', 'a') as f: json.dump(self.sensor_data, f) f.write('\n') def run(self, interval=5): try: while True: if self.update_sensors(): self.save_to_database() time.sleep(interval) except KeyboardInterrupt: print("Monitoring stopped") finally: self.serial.close()

5. 常见问题与调试技巧

5.1 串口通信常见问题排查

  1. 无数据接收

    • 检查TX/RX线是否交叉连接
    • 确认两端的波特率、数据位、停止位和校验位设置一致
    • 使用示波器或逻辑分析仪检查信号
  2. 数据乱码

    • 确认波特率误差在允许范围内(通常<3%)
    • 检查地线连接是否良好
    • 尝试降低波特率测试
  3. 通信不稳定

    • 缩短连接线长度(建议<1米)
    • 添加适当的终端电阻(如120Ω)
    • 检查电源稳定性

5.2 调试工具推荐

  1. minicom- Linux下的串口调试工具

    sudo apt install minicom minicom -D /dev/ttyAMA0 -b 115200
  2. screen- 简单的串口终端

    screen /dev/ttyAMA0 115200
  3. Python交互式调试

    >>> import serial >>> ser = serial.Serial('/dev/ttyAMA0', 115200) >>> ser.write(b'test') >>> ser.read(10)

5.3 性能测试方法

  1. 吞吐量测试

    • 发送大量数据并计算传输时间
    • 测试不同数据包大小的影响
  2. 可靠性测试

    • 长时间运行测试通信稳定性
    • 模拟恶劣环境(如电源波动)
  3. 延迟测试

    • 测量从发送到接收的往返时间
    • 测试不同波特率下的延迟变化
def latency_test(ser, test_cycles=100): total_time = 0 successful = 0 for _ in range(test_cycles): start = time.time() ser.write(b'PING') response = ser.read(4) if response == b'PONG': total_time += time.time() - start successful += 1 time.sleep(0.1) if successful > 0: avg_latency = (total_time / successful) * 1000 # 转换为毫秒 print(f"Average latency: {avg_latency:.2f}ms ({successful}/{test_cycles} successful)") else: print("No successful responses received")
http://www.jsqmd.com/news/570312/

相关文章:

  • STM32CubeMX配置MAX31856 SPI驱动,5分钟搞定K型热电偶测温(附完整工程)
  • 避坑指南:DCA1000EVM + IWR6843ISK 毫米波雷达数据采集,从硬件连接到MATLAB可视化的完整流程
  • Claw-Code 项目深度分析(-) 架构设计分析
  • LTS部署与运维指南:从单机到集群的完整部署流程
  • 【实战指南】TransGPT:交通智能解决方案的开源部署与应用
  • 破解投研 / 法务 / 研发效率瓶颈:Kimi-K2-Thinking-Turbo 高性能模型落地指南
  • AI时代产品推广新范式:福州榕臻科技的智能营销实践 - 资讯焦点
  • UDOP-large实战手册:英文技术文档FAQ自动生成Prompt模板库
  • Skateshop部署终极指南:Vercel、Netlify和Docker三种方案详解
  • 3个核心功能实现极域电子教室系统优化与学习效率提升
  • cool-admin(midway版)后端异常分类:业务异常与系统异常处理
  • mrm-ref-can:面向嵌入式光电传感器的轻量级CAN通信库
  • Pixel Epic智识终端一文详解:16-bit UI设计×AgentCPM引擎×Symlink安全机制
  • FRCRN开源模型多场景落地:客服录音净化、有声书制作、教学音频增强
  • testing-nestjs Sequelize 测试教程:传统 ORM 的完整测试指南
  • 别再死记硬背公式了!用Python实战带你搞懂AR模型谱估计(附Burg/协方差法代码)
  • 中国最美油菜花田推荐:踏青赏花必去目的地盘点 - 资讯焦点
  • Qwen3.5-2B企业集成教程:对接钉钉/企微机器人,实现IM内图文问答服务
  • 智能歌词助手:重新定义音乐聆听体验
  • 完全自主可控的物联网平台
  • Ryzen处理器终极调试指南:3步诊断+4维优化释放AMD隐藏性能
  • 链表操作避坑指南:实现多项式运算时,你的内存管理做对了吗?
  • SteamShutdown终极指南:游戏下载完成自动关机的完整解决方案
  • 2026五款CRM客户管理系统盘点,企业选型专业指南 - jfjfkk-
  • 保姆级教程:用ENVI 5.3搞定高分二号(GF-2)影像预处理全流程(含FLAASH大气校正与NNDiffuse融合)
  • Qwen3-14B-Int4-AWQ在软件测试中的应用:自动化测试用例与缺陷报告生成
  • 解锁流畅观影体验:PiliPlus全方位应用指南
  • OmenSuperHub:3个步骤彻底解决惠普游戏本性能与散热难题
  • 别再死记硬背了!用Keras从零搭建一个英法翻译模型(附完整代码和数据集)
  • 3步实现VR视频自由探索:让普通设备变身360度影院