外观
FNIRSI DPS-150:便携数控电源,从官方规格到串口直控

巴掌大的 FNIRSI DPS-150 数控电源(0~30V / 0~5A / 150W),官方只给 Windows 上位机。 社区已把它的 USB 串口协议完整逆向,一行 pyserial 就能读遥测、设电压电流、开关输出。 本文前半整理官方手册的规格与界面(含实物图),后半是实测逆向与踩坑(DPS-150P / 固件 V1.6),代码已固化成
tool/dps150.py。
官方资料
规格速查(官方手册)
| 项目 | 值 | 项目 | 值 |
|---|---|---|---|
| 型号 / 屏幕 | DPS-150 · 2.8 寸 320×240 | 输出电压 / 电流 / 功率 | 0~30V / 0~5A / 0~150W |
| 输入电压 / 电流 | DC 5.0~32V / 100mA~5A(支持 PD / QC 快充,可用充电宝) | 满载效率 | 高(手册标称,详见 PDF) |
| 设定分辨率 | 电压 10mV · 电流 1mA | 设定精度 | 电压 ≤0.1%±5mV · 电流 ≤0.1%±3mA |
| 回读精度 | 输入电压 ≤0.2%±5mV · 输出电压 ≤0.1%±10mV | 负载调整率 | 0.49% |
手册里叫 DPS-150,实机型号是 DPS-150P(本文全程按实机型号写)。
面板与主界面

正面是 2.8 寸屏 + 六个按键(滚轮可左右滑动调参):

主界面信息量很足(对应手册序号):输入电压、内部温度、运行状态、当前 V/A/W 与累计能量(Wh/Ah)、设定电压(0.01V 步进)、设定电流(0.001A 步进)、预设组编号、控制面板锁定状态、输出模式。
工作状态有七类,除 OK 外检测到任一异常都会自动关闭输出 + 蜂鸣器报警:
| 状态 | 含义 |
|---|---|
OVP / OCP / OPP | 过压 / 过流 / 过功率保护 |
OTP | 过热保护 |
REP | 反接保护 |
LVP | 欠压保护(此状态下禁止开启输出) |
预设组:设备支持 6 组(M1~M6)预设输出,每组都包含独立的电压设定与恒流设定,短按即可切换——多设备交替供电时很实用。
输出模式:恒压 CV / 恒流 CC 两种。
操作要点
- 调参:单击设置键进入高亮位,滚轮左右滑动调整;再次单击在电压/电流设定间切换,短按保存退出
- 菜单项(电源设置 / 系统设置 / 关于):过压/过流/过功率/过温/欠压保护的阈值都可单独设,另有语言、常规↔工业风界面、背光亮度、音量、计量开关
- 预设组保存:进入数据组页 → 单击出高亮位 → 滚轮调整 → 短按保存
- ⚠️ 连上位机后控制面板自动锁定(锁图标变白),断开串口会话才解锁——我们后面写的控制工具也会触发这个行为

上位机自带的高级功能
官方 Windows 上位机除了基础监控/波形记录(电压电流曲线可滚轮缩放、可保存删除),还有三块"按程序跑输出"的高级功能:
| 功能 | 干什么 |
|---|---|
| 序列输出 | 按序号范围和循环次数,定时依次输出设定好的 V/I;支持手动单步、暂停/继续 |
| 电流扫描 | 电压固定,电流在起止范围内按"步进电流 + 延时"扫描输出(恒流模式常用) |
| 电压扫描 | 电流固定,电压在起止范围内按"步进电压 + 延时"扫描输出(恒压模式常用) |


固件升级(两条路)
- U 盘法:按住升级键插数据线,电脑弹出 U 盘,把固件拷进去,设备自动升级
- 上位机法:联机后点「固件升级 → BOOT/重启」,同样弹 U 盘拷贝固件

⚠️ 注意:固件升级走的是 DFU 模式。别把它和我们串口协议里的
0xC0混淆——那是"进 DFU"的命令字节,发错会直接丢串口(见文末危险字节)。
设备识别
走 Micro-USB 数据口,枚举为 USB CDC 虚拟串口(内部主控是 Artery AT32):
bash
system_profiler SPUSBDataType | grep -A6 "AT32 Virtual Com Port" # 识别设备
ls /dev/cu.usbmodem* # 串口设备节点协议全景(社区逆向)
帧结构极简——头 1 字节 + 命令 + 寄存器 + 长度 + 数据 + 校验和:
| 0xF1 | 命令 | 寄存器 | 长度 | 数据 (0..N) | 校验和 |
|---|---|---|---|---|---|
| Header | Cmd | Reg | Len | Data… | Sum |
校验和 =
(寄存器 + 长度 + Σ数据) & 0xFF(头与命令不参与);设备回包头0xF0;数值一律 IEEE754 float32 小端。
命令字节:
| 命令 | 用途 |
|---|---|
0xA1 | 读寄存器 |
0xB1 | 写寄存器 |
0xB0 | 设波特率 |
0xC1 | 会话连接/断开 |
0xC0 | ⚠️ 进 DFU 刷机模式——禁发(CDC 消失,需拔插恢复) |
关键寄存器:
| 寄存器 | 类型 | 含义 |
|---|---|---|
0xC1 | float32 | 电压设定 |
0xC2 | float32 | 电流设定 |
0xDB | uint8 | 输出开关(0/1) |
0xC0 | float32 | 输入电压 |
0xC3 | 3×float32 | 实测输出 V/A/W |
0xDC | uint8 | 保护状态(0=OK,1=OVP…6=REP) |
0xDD | uint8 | 0=CC / 1=CV |
0xFF | 139B | 全状态 dump(含 6 组预设、保护阈值、Ah/Wh) |
控制闭环实测
一条命令设定并开启输出,软启动约 1.5 s 爬升到位:
| 能力 | 实测 |
|---|---|
| 读型号/固件/硬件 | DPS-150P · V1.6 · V1.0 |
| 读遥测 | 输入 20.08V、温度 30.5°C、输出 V/A/W 全状态 139 字节 |
| 写设定 | 5.000V / 0.500A,回读一致 |
| 开关输出 | 开 → 5.000V(软启动 ~1.5s);关 → 泄放 ~1.2s 归零 |
常用操作:
bash
python3 tool/dps150.py status # 读全状态
python3 tool/dps150.py set --voltage 12.0 --current 2.0 # 设 12V/2A(不开启)
python3 tool/dps150.py set --on # 开输出
python3 tool/dps150.py set --off # 关输出踩坑档案
| 现象 | 根因 | 解决 |
|---|---|---|
| 读寄存器字段错乱、只回 12 字节 | 设备主动推送遥测帧(0xC3 等)混进响应流 | 读回按寄存器号过滤,丢弃非目标帧 |
| 单独读 0xE2/0xE3 返回 0 | 能力寄存器只在推送帧里有值 | 从全状态 dump 的 0x6F/0x73 偏移取 max V/I |
| 设 30V 设不上去 | 降压架构:输出上限钳到输入电压以下(20V 输入 → 19.88V max) | 想高输出先提高输入电压 |
| 开输出立刻读电压只有零点几 V | 软启动爬升中 | 等待 ≥1.5s 再读 |
| 面板按键失效 | 连上位机后自动锁面板 | 断开串口会话即解锁 |
一个危险字节
0xC0 不是重启,是进 DFU 刷机模式:USB CDC 端口直接消失,必须物理拔插恢复。设备没有软重启命令。
复现与出处
- 控制工具:skill
fnirsi-dps150的tool/dps150.py(仅依赖 pyserial) - 协议出处:社区逆向 nasheed-x/dps150_api(PROTOCOL.md,交叉验证 JS/C/Python/Rust 四份实现 + 反编译官方 .NET 上位机)
- 官方资料:FNIRSI 官方产品页 · 官方说明书 PDF(本文规格/界面图均出自该手册,已存档本站)
- 完整寄存器表、139 字节布局、预设组公式见 skill
fnirsi-dps150参考文档