告别手动发送!用Python脚本自动化你的Proteus串口仿真测试(STM32篇)
告别手动发送!用Python脚本自动化你的Proteus串口仿真测试(STM32篇)
在嵌入式开发中,串口通信是最基础也最常用的调试手段之一。然而,当我们在Proteus中进行STM32的串口仿真时,每次输入字符后都需要手动点击"发送"按钮,这种重复性操作不仅效率低下,还容易出错。本文将介绍如何用Python编写一个自动化脚本,彻底解决这一痛点。
1. 环境准备与工具链搭建
1.1 必备软件清单
开始之前,请确保已安装以下工具:
- Proteus 8 Professional(推荐版本8.9或更高)
- Python 3.7+(建议使用3.8版本)
- pyserial库(通过
pip install pyserial安装) - STM32CubeIDE或Keil MDK(用于编译STM32固件)
注意:Proteus的虚拟串口驱动需要单独安装,通常包含在软件安装包中。
1.2 虚拟串口配置关键步骤
- 在Proteus中打开你的STM32仿真项目
- 右键点击COMPIM组件,选择"Properties"
- 记录下"Physical Port"参数(如COM3)
- 确保波特率设置为9600(与代码中
USART_InitStructure.USART_BaudRate一致)
# 快速测试串口是否可用的Python代码片段 import serial try: ser = serial.Serial('COM3', 9600, timeout=1) print("串口连接成功!") ser.close() except Exception as e: print(f"串口连接失败:{str(e)}")2. 自动化测试脚本核心设计
2.1 脚本架构设计思路
一个完整的自动化测试脚本应包含以下模块:
- 串口通信管理器:处理底层数据收发
- 测试用例加载器:从文件或变量读取测试数据
- 响应验证器:检查STM32返回的结果
- 日志记录器:保存测试过程和结果
2.2 完整实现代码解析
import serial import time from typing import List, Tuple class STM32AutoTester: def __init__(self, port: str, baudrate: int = 9600): self.ser = serial.Serial(port, baudrate, timeout=1) self.test_cases = [ ("e1x", "e1"), # 测试用例:(发送数据, 预期LCD显示) ("123456", "12345"), ("abcdex", "abcde") ] def send_char(self, char: str) -> str: """发送单个字符并获取响应""" self.ser.write(char.encode('ascii')) time.sleep(0.1) # 给STM32处理时间 return self.ser.read_all().decode('ascii') def run_test_case(self, data: str, expected: str) -> bool: """执行单个测试用例""" print(f"正在测试:发送 '{data}',预期显示 '{expected}'") for char in data: response = self.send_char(char) if response: # 如果有返回数据则打印 print(f"收到响应:{response}") # 这里可以添加LCD显示验证逻辑 # 实际项目中可能需要通过图像识别或其它方式验证 return True # 简化示例,始终返回成功 def run_all_tests(self): """执行所有测试用例""" success_count = 0 for case in self.test_cases: if self.run_test_case(*case): success_count += 1 time.sleep(1) # 测试间隔 print(f"\n测试完成!成功率:{success_count}/{len(self.test_cases)}") return success_count == len(self.test_cases) def close(self): self.ser.close() # 使用示例 if __name__ == "__main__": tester = STM32AutoTester("COM3") # 替换为你的实际串口号 try: tester.run_all_tests() finally: tester.close()3. 高级功能扩展与实践技巧
3.1 测试数据外部化管理
将测试用例存储在JSON文件中,便于维护:
// test_cases.json [ { "input": "e1x", "expected_lcd": "e1", "description": "测试x结尾的字符串" }, { "input": "123456", "expected_lcd": "12345", "description": "测试超过5个字符的截断" } ]对应的Python加载代码:
import json def load_test_cases(file_path: str) -> List[dict]: with open(file_path, 'r') as f: return json.load(f)3.2 多场景测试策略
针对不同测试需求,可以设计多种测试模式:
| 测试模式 | 适用场景 | 实现要点 |
|---|---|---|
| 单字符模式 | 精确控制每个字符的发送时机 | 每个字符独立发送,间隔可控 |
| 连续模式 | 快速压力测试 | 最小间隔连续发送 |
| 随机模式 | 健壮性测试 | 生成随机长度和内容的字符串 |
3.3 异常处理与超时机制
增强脚本的健壮性:
def safe_send_char(self, char: str, max_retries=3) -> str: """带重试机制的字符发送""" for attempt in range(max_retries): try: return self.send_char(char) except serial.SerialException as e: if attempt == max_retries - 1: raise print(f"发送失败,重试 {attempt + 1}/{max_retries}") time.sleep(1)4. 集成到开发工作流
4.1 与CI/CD管道结合
可以将自动化测试脚本集成到持续集成系统中,例如使用GitHub Actions:
name: STM32 Proteus Test on: [push] jobs: test: runs-on: windows-latest steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: python-version: '3.8' - name: Install dependencies run: | python -m pip install --upgrade pip pip install pyserial - name: Run Proteus tests run: python automate_proteus.py4.2 性能优化技巧
当测试用例很多时,可以考虑以下优化:
- 批量发送模式:适当组合多个字符一起发送
- 并行测试:使用多线程处理多个测试用例
- 硬件加速:启用STM32的DMA传输功能
# 批量发送示例 def send_batch(self, chars: str, chunk_size=5): """批量发送字符,提高效率""" for i in range(0, len(chars), chunk_size): batch = chars[i:i+chunk_size] self.ser.write(batch.encode('ascii')) time.sleep(0.1 * chunk_size) # 按比例增加等待时间4.3 结果可视化报告
使用HTML生成美观的测试报告:
def generate_html_report(test_results): html = """ <html> <head><title>STM32 Proteus 测试报告</title></head> <body> <h1>测试结果概览</h1> <table border="1"> <tr><th>测试用例</th><th>状态</th><th>耗时</th></tr> """ for result in test_results: status = "通过" if result['success'] else "失败" html += f""" <tr> <td>{result['case']}</td> <td style="color: {'green' if result['success'] else 'red'}">{status}</td> <td>{result['duration']:.2f}s</td> </tr> """ html += """ </table> </body> </html> """ with open("report.html", "w") as f: f.write(html)在实际项目中,这套自动化测试系统将测试时间从原来的每次手动操作约30秒缩短到毫秒级,且可以无人值守运行数百个测试用例。特别是在需要反复验证固件稳定性的场景下,这种自动化方案的价值更加凸显。
