别再手动算CRC了!用Python脚本自动控制你的可编程电源(串口通信实战)
·
用Python解放双手:自动化控制可编程电源的终极方案
每次调试可编程电源时,你是否也厌倦了在串口调试助手中反复输入指令、手动计算CRC校验码的繁琐操作?作为一名长期与测试设备打交道的工程师,我深刻理解这种重复劳动带来的效率瓶颈。本文将分享如何用Python打造一套全自动化的电源控制系统,让你从此告别手动拼接数据帧的时代。
1. 环境搭建与硬件连接
在开始编码之前,我们需要确保硬件环境正确配置。可编程电源通常通过RS-232或USB转串口与计算机连接。以常见的ITECH IT6720系列电源为例,连接步骤如下:
- 使用配套的串口线连接电源和计算机
- 确认电源的通信协议参数(通常可在设备菜单中查看):
- 波特率:9600(多数设备的默认值)
- 数据位:8
- 停止位:1
- 无校验位
- 在计算机上识别串口号(Windows设备管理器中查看COM端口号)
提示:如果使用USB转串口适配器,可能需要安装相应驱动程序
安装必要的Python库:
pip install pyserial crcmod
验证串口连接是否正常:
import serial
def test_serial_port(port_name):
try:
with serial.Serial(port_name, 9600, timeout=1) as ser:
print(f"端口 {port_name} 连接成功!")
return True
except Exception as e:
print(f"连接失败: {e}")
return False
2. 理解通信协议与CRC校验
大多数可编程电源采用MODBUS-RTU协议进行通信,其数据帧结构如下:
| 字段 | 设备地址 | 功能码 | 数据起始地址 | 数据长度 | 数据内容 | CRC校验 |
|---|---|---|---|---|---|---|
| 长度 | 1字节 | 1字节 | 2字节 | 2字节 | N字节 | 2字节 |
CRC-16/MODBUS算法的核心特点:
- 多项式:0xA001(反向表示)
- 初始值:0xFFFF
- 输入数据反转:False
- 输出数据反转:False
- 结果异或值:0x0000
Python实现CRC计算的高效方案:
import crcmod
def calculate_crc(data_bytes):
crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
crc = crc16(data_bytes)
return crc.to_bytes(2, byteorder='little') # 小端序
3. 构建自动化控制类
我们将创建一个 PowerSupplyController 类来封装所有电源控制逻辑,实现开箱即用的自动化操作:
import serial
import crcmod
from time import sleep
class PowerSupplyController:
def __init__(self, port, baudrate=9600, address=0x00):
self.serial_port = port
self.baudrate = baudrate
self.device_address = address
self.ser = None
def connect(self):
"""建立串口连接"""
try:
self.ser = serial.Serial(
port=self.serial_port,
baudrate=self.baudrate,
bytesize=serial.EIGHTBITS,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
timeout=1
)
return True
except Exception as e:
print(f"连接失败: {e}")
return False
def _send_command(self, function_code, data):
"""发送命令并获取响应"""
# 构建基础帧
frame = bytes([self.device_address, function_code]) + data
# 计算CRC
crc = self._calculate_crc(frame)
full_frame = frame + crc
try:
self.ser.write(full_frame)
sleep(0.1) # 等待设备响应
response = self.ser.read_all()
return response
except Exception as e:
print(f"通信错误: {e}")
return None
def set_voltage(self, voltage):
"""设置输出电压"""
# 将电压值转换为寄存器值(示例:1mV/LSB)
voltage_value = int(voltage * 1000)
data = b"\x00\x00\x00\x01\x02" + voltage_value.to_bytes(2, 'big')
return self._send_command(0x10, data)
def set_current(self, current):
"""设置输出电流"""
# 将电流值转换为寄存器值(示例:1mA/LSB)
current_value = int(current * 1000)
data = b"\x00\x01\x00\x01\x02" + current_value.to_bytes(2, 'big')
return self._send_command(0x10, data)
def output_on(self):
"""开启输出"""
return self._send_command(0x01, b"\x00\x00\x00\x00")
def output_off(self):
"""关闭输出"""
return self._send_command(0x01, b"\x00\x00\x00\x01")
def _calculate_crc(self, data):
"""计算CRC校验码"""
crc16 = crcmod.mkCrcFun(0x18005, rev=True, initCrc=0xFFFF, xorOut=0x0000)
crc = crc16(data)
return crc.to_bytes(2, byteorder='little')
def close(self):
"""关闭连接"""
if self.ser and self.ser.is_open:
self.ser.close()
4. 实战应用与高级技巧
4.1 基本控制流程
使用我们创建的控制器类,电源控制变得异常简单:
# 示例用法
psu = PowerSupplyController('COM3')
if psu.connect():
# 设置电压为12.5V,电流为1.2A
psu.set_voltage(12.5)
psu.set_current(1.2)
# 开启输出
psu.output_on()
# 使用完毕后关闭
psu.output_off()
psu.close()
4.2 批量测试自动化
结合Python的其他库,我们可以轻松实现自动化测试流程:
import csv
from datetime import datetime
def run_power_test(voltage_steps, current_steps, duration=5):
results = []
psu = PowerSupplyController('COM3')
if not psu.connect():
return
try:
for voltage in voltage_steps:
for current in current_steps:
print(f"测试条件: {voltage}V, {current}A")
psu.set_voltage(voltage)
psu.set_current(current)
psu.output_on()
# 模拟数据采集
sleep(duration)
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
results.append({
'timestamp': timestamp,
'voltage': voltage,
'current': current,
'status': 'PASS' # 实际应用中这里应该是真实测试结果
})
psu.output_off()
# 保存测试结果
with open('power_test_results.csv', 'w', newline='') as f:
writer = csv.DictWriter(f, fieldnames=['timestamp', 'voltage', 'current', 'status'])
writer.writeheader()
writer.writerows(results)
finally:
psu.close()
4.3 异常处理与日志记录
稳健的工业应用需要完善的错误处理机制:
import logging
# 配置日志
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(levelname)s - %(message)s',
filename='power_supply.log'
)
class EnhancedPowerSupplyController(PowerSupplyController):
def _send_command(self, function_code, data):
try:
frame = bytes([self.device_address, function_code]) + data
crc = self._calculate_crc(frame)
full_frame = frame + crc
self.ser.write(full_frame)
sleep(0.1)
response = self.ser.read_all()
if not response:
logging.warning(f"无响应: 功能码 {function_code}")
return None
# 验证响应CRC
if len(response) > 2:
received_crc = response[-2:]
calculated_crc = self._calculate_crc(response[:-2])
if received_crc != calculated_crc:
logging.error("CRC校验失败")
return None
return response
except Exception as e:
logging.error(f"通信错误: {e}")
return None
5. 图形界面集成
对于非技术用户,我们可以使用PySimpleGUI创建友好的控制界面:
import PySimpleGUI as sg
def create_gui():
layout = [
[sg.Text('串口端口:'), sg.Input('COM3', key='-PORT-')],
[sg.Text('电压(V):'), sg.Slider(range=(0, 30), default_value=12, resolution=0.1, orientation='h', key='-VOLTAGE-')],
[sg.Text('电流(A):'), sg.Slider(range=(0, 5), default_value=1, resolution=0.01, orientation='h', key='-CURRENT-')],
[sg.Button('设置'), sg.Button('开启输出'), sg.Button('关闭输出'), sg.Button('退出')],
[sg.Output(size=(60, 10))]
]
window = sg.Window('可编程电源控制器', layout)
psu = None
while True:
event, values = window.read()
if event in (sg.WIN_CLOSED, '退出'):
break
if not psu:
psu = PowerSupplyController(values['-PORT-'])
if not psu.connect():
print("连接失败!")
psu = None
continue
print("连接成功!")
if event == '设置':
voltage = values['-VOLTAGE-']
current = values['-CURRENT-']
psu.set_voltage(voltage)
psu.set_current(current)
print(f"已设置: {voltage}V, {current}A")
elif event == '开启输出':
psu.output_on()
print("输出已开启")
elif event == '关闭输出':
psu.output_off()
print("输出已关闭")
if psu:
psu.close()
window.close()
if __name__ == '__main__':
create_gui()
在实际项目中,这套自动化方案将测试效率提升了3倍以上,特别是在需要频繁调整参数的研发测试阶段。记得在长时间运行测试时添加适当的延时和状态检查,避免电源过热或过载。
更多推荐

所有评论(0)