CanMsgParser 是一款开源的车载 CAN 总线报文分析工具,功能对标 Vector CANoe / CANalyzer,基于 Python + PyQt5 开发,运行于 Windows。 支持 DBC 解析、BLF / ASC 日志加载、CAN FD、多信号曲线绘制、实时报文监控、信号模拟上报、报文回放与 DBC 位图可视化,专为汽车电子工程师分析 CAN 总线数据而设计。
- 解析格式:DBC、BLF、ASC、CAN FD(最大 64 字节)
- 采集硬件:PCAN-USB(PEAK),波特率默认 500 kbit/s
- 核心能力:信号解码、曲线绘制(LTTB 降采样)、时间差测量、信号值枚举描述(DBC / Excel)、报文录制与回放
关键词:CanMsgParser、CAN 报文分析工具、CAN 总线分析、车载报文解析、CANoe 替代、CANalyzer 替代、DBC 解析、DBC 位图、BLF 日志、ASC 日志、CAN FD、CAN 曲线绘制、CAN 信号解码、实时报文监控、CAN 报文回放、信号模拟上报、PCAN、cantools、python-can、PyQt5
📸 界面截图 ↓
- DBC 文件解析:基于 cantools 库,支持完整 DBC 信号定义(起始位、长度、字节序、缩放因子、偏移量、单位、值描述等)
- 日志文件加载:支持 BLF 和 ASC 两种常见 CAN 日志格式(基于 python-can)
- CAN FD 支持:同时兼容经典 CAN(8 字节)和 CAN FD(最大 64 字节)
- 拖放加载:直接拖拽 .dbc / .blf / .asc / .xlsx 文件到窗口即可加载
- 配置记忆:自动记住上次加载的 DBC、Excel、分组配置路径,下次启动自动恢复
- 树形结构展示所有报文(Message)和信号(Signal)
- 模糊搜索:支持按信号名/报文名搜索,也支持按 CAN ID(hex)搜索(如输入
1A0或0x1A0) - 搜索时自动展开匹配的报文节点
- 支持单选、全选当前报文、取消全选
- 多信号时间-值曲线绘制,X 轴为时间戳(秒),Y 轴为信号物理值
- 每个信号用不同颜色折线 + 圆点标记(标记报文发送时刻)
- 两种图表模式可切换(曲线图与实时监控均默认独立子图):
- 独立子图模式:每个信号一个 subplot,共享 X 轴
- 共享 Y 轴模式:所有信号在同一图表,自动缩放
- 丰富交互:
Ctrl + 鼠标滚轮:以鼠标位置为中心 X/Y 轴同时缩放- 鼠标位置靠近 X/Y 轴区域 + 滚轮:单轴缩放
- 鼠标左键拖拽:实时平移曲线视图(跟手);位移小于 4 像素视为单击
- 悬停高亮:鼠标靠近曲线时加粗显示,弹出注释框显示信号名、当前值、时间
- 值含义显示:悬停注释框显示 DBC/Excel 中定义的值描述(如
2 (OFF)) - 图例显示报文 ID:实时曲线图例在信号名后附所属报文 ID,例如
TCU_3.TCU_Drivemode(0x112),便于区分多个同名信号 - 点击数值说明框:单击曲线弹出数值说明框并固定高亮,每条曲线最多同时显示 3 个,超出按先进先出淘汰;右键说明框可关闭
- 说明框智能避让:优先显示在不遮挡曲线、不出界的位置
- 时间差标记:最多 3 组,每组两个标记点,组内同色 + 区间色带,显示 Δt 时间差
- 自适应复位:一键恢复最佳视图
- 大数据优化:LTTB 降采样算法,超过 10000 点自动降采样,保留曲线特征;交互走 blit 局部刷新(背景位图缓存 + 仅重绘变化元素),悬停 / 拖动响应约 20~40 ms(优化前约 200 ms)
- 创建自定义分组(如"空调"、"车辆设置"、"能量流")
- 通过内嵌信号树的「加入分组」按钮批量添加信号到分组
- 分组内信号可逐个勾选或全选;选中组内信号后按 Delete 键(或点「移除选中」)即可移除
- 组内信号搜索:分组内信号列表上方有搜索框,支持按信号名 / 报文名 / 备注内容实时过滤(仅改变显示,不改动底层分组数据);备注列行高已加大,输入更顺手
- 分组配置支持保存/加载(JSON 格式);备注列:每个已添加信号都有「备注」可编辑列,用于描述该信号的功能,随配置一并持久化
- 自动保存:修改备注或增删信号/分组后,面板每 2 秒检查一次,若有变化且已存在配置文件路径(首次手动「保存配置」或启动时自动加载的路径),即静默自动保存,无需反复点保存
- DBC 匹配:加载分组配置时,与当前 DBC 不匹配的信号自动置灰不可勾选
- 协议数据加载:本页分别加载三类协议数据,点击「加载」由主窗口统一选择文件:
- 矩阵 xlsx(值描述):补充 DBC 缺失的信号值描述(ValueDescriptions)
- DBC 数据库:信号解码、位图、曲线与模拟上报的根基
- 待分析报文(日志 BLF/ASC):供报文表格 / 实时报文页回放
- CAN 总线连接:选择通道(PCAN_USBBUS1~4)与波特率(默认 500000),点击「连接 CAN / 断开 CAN」
- 连接状态是实时监控、模拟上报、实时报文三页共用的通道与波特率唯一来源(各页不再单独设置)
- 无 PCAN 硬件时给出明确错误提示
- 通过 PCAN-USB 实时接收 CAN 帧,使用 DBC 解码勾选信号的物理值并实时绘制曲线
- 在「信号分组」窗勾选要监控的信号 → 点击「添加到实时监控」→ 点击「开始监控」即开始接收并绘图
- 实时曲线复用曲线图页的交互(缩放、平移、悬停高亮、值描述含义:悬停注释框「值」一行会显示 DBC/Excel 定义的枚举描述,如
2 (OFF));默认以「独立子图」展示(每个信号一个子图,共享 X 轴),可点「切换为共享 Y 轴」合并 - 重置曲线:点击「重置曲线」按钮清空当前画面;监控进行中会清空并继续记录,停止状态下则仅清空画面、保留已选信号配置
- 通道与波特率统一由「连接状态」页提供,无需在本页设置
- 左侧「已选信号」列表选中后,可按 Delete 键(或点「移除选中」)快速移除该信号
- 通过 PCAN-USB 周期性发送选定信号的 CAN 报文,模拟真实 ECU 报文流
- 在「信号分组」窗勾选信号 → 点击「添加到模拟上报」→ 已选信号按 报文 ID 自动聚合成「报文组」,以树形展示(顶层=报文组,子层=组内信号)
- 树形表列:
- 父行(报文组):
📦 报文组 0xXXX标题 / 信号数 / 组周期 SpinBox(ms) / 组状态 / (发送·停止) - 子行(信号):
信号名(报文)/ 换算公式 / 模拟值·手动值 / 自动递增 / 状态 / 详情 / (移除)
- 父行(报文组):
- 上报周期只由报文组控制:每个报文组有独立周期 SpinBox,组内全部信号按该周期填入同一帧一次性编码发送 —— 彻底解决「同 ID 多个信号各发各帧、互相用 offset 默认值覆盖、取值来回切换」的问题 (例如 0x3E3 的 A/B 两个信号会始终出现在同一帧里,不再交替被清零)
- 换算公式 =
scale × raw + offset;每信号可设「模拟值 / 手动值(支持 0x 十六进制)」与「自动递增」(手动模式按范围循环 +1) - 组行「发送 / 停止」按钮控制单个报文组;顶部「开始 / 停止模拟上报」按钮按实际发送状态刷新——只要任一报文组正在发送,顶部即显示「停止模拟上报」,全部停止后恢复「开始模拟上报」(单独发某组也会同步顶部按钮)
- 发送范围保护:若某信号原始值超出其位宽/符号可表示范围(如向无符号信号写入负值,旧版会报
can't convert negative int to unsigned崩溃),现自动钳制到可表示范围并在该信号行标红报错,同帧其它信号仍正常发送,不再整帧崩溃 - 信号行「移除」从所在组删除该信号;移除组内最后一个信号时该报文组自动消失
- 左侧「已选信号(可删除)」列表选中后,可按 Delete 键(或点「移除选中」)移除,移除后该信号同时从其所在报文组删除
- 通道与波特率统一由「连接状态」页提供;发送日志实时显示最近帧的 ID 与 Data(同名 ID 占一行并累计发送计数)
- 监听 PCAN 总线上的全部报文(需先在「连接状态」页连接 CAN),同 ID 仅保留一行并原地刷新数据 / 计数 / 时间
- 双击报文行就地展开其解码信号(无需弹窗,比「报文表格」页更直接)。展开后的子项以「父子分层」形式列出每个信号:
- 十六进制值(左侧) + 十进制值(右侧,含枚举名) + 单位 + 信号描述
- 信号描述来源:DBC 值描述(VAL_)优先,DBC 缺失时回退到 Excel 值描述;二者皆无则留空
- 示例:
TCU_Drivemode | 0x1 | 1 (前进) | | 前进
- 工具栏支持:清除、⏸ 暂停监听 / ▶ 开始监听、开始录制 / 停止录制(录制格式可选 BLF / ASC,默认路径
CANLOG_年月日_时分秒.blf,可自定义)- 连接 CAN 后自动监听;手动「暂停监听」仅停止本页收帧、不影响共享总线与其他页面;手动「开始监听」复用共享连接恢复收帧
- 若设备中途断开后重连,不会自动恢复监听(尊重手动暂停的意图),需手动点「开始监听」
- 与「报文表格」页的区别:本页面向实时总线、同 ID 单行;报文表格页面向已加载日志、按帧展开(两者展开后信号子项布局一致)
- 加载 BLF / ASC / LOG 报文日志,按原始时序回放到 CAN 总线(复用「连接状态」页注入的共享总线,无需本页配置通道 / 波特率)
- 常用回放设置:
- 回放次数:1 次或 N 次
- 循环回放:勾选后无限循环
- 回放速度:0.1x 慢放 ~ 10x 快进(保持原帧间隔比例)
- 起始延迟:每轮开始前等待的毫秒数
- 按报文 ID 勾选:仅回放勾选 ID 的帧(其余跳过),可全选 / 全不选;DBC 加载后 ID 列表会显示报文名
- 回放过程中把每帧主动 fan-out 给监控页 / 报文页,便于在监控页实时观察回放效果;下方显示进度(帧序号 / 轮次)
- 「信号分组」从曲线图页内嵌面板抽离为可停靠 / 可悬浮 / 可关闭的停靠窗(菜单「视图 → 信号分组」开关)
- 分组信号在曲线图、实时监控、模拟上报三页共享:任一页搜索添加信号,悬浮窗管理分组与勾选
- 分组配置保存 / 加载(JSON)逻辑保持不变
- 表格形式显示原始 CAN 报文(序号、时间、ID、DLC、Channel、Data)
- 可展开行:双击展开查看该帧所有解码后的信号值。子项以「父子分层」列出每个信号:十六进制值(左侧) + 十进制值(右侧,含枚举名) + 单位 + 信号描述(DBC 优先 / Excel 补充)
- 值变化高亮:当某字节值变化时,以亮红色高亮显示,并在后续 500 帧内逐渐渐变消退(基于筛选后的帧数)
- 多条件过滤:按报文 ID、信号名、时间范围过滤,支持回车键触发
- 大数据量优化:只渲染可见行
- 显示报文数据帧的位布局网格(8 字节 = 64 bits,CAN FD 最大 512 bits)
- Intel(小端)/ Motorola(大端)正确渲染
- 每个信号用不同颜色高亮占用的 bit 位置(ColorBrewer 风格调色板)
- 单元格内显示:信号名(左上角)、bit 位号(居中)、MSB(左下角)、LSB(右下角)
- 鼠标悬停显示信号详细信息(起始位、长度、字节序、scale、offset、范围等)
- 搜索框支持按 ID 或报文名/信号名模糊搜索
- 网格随窗口大小动态缩放
- 下方信号详情表显示完整信号定义 + 值描述
- 图表导出:PNG(300 DPI)/ SVG 矢量图
- 信号数据导出:CSV / Excel,多信号按时间戳对齐
- 报文表格导出:CSV 格式,含解码信号
- 启动画面:带小车和坐标图插图的优美启动界面,显示加载进度
- 依赖检测:启动时自动检测必需 Python 库,缺失时弹窗询问是否自动 pip 安装
- 多线程架构:QThread 后台加载和解码,UI 始终响应
- 专业暗色主题:统一设计系统,护眼且美观
- Excel 值描述:支持从复杂 CAN 矩阵 Excel 表格提取信号值描述,DBC 优先、Excel 补充
| 库 | 用途 |
|---|---|
| PyQt5 | GUI 框架 |
| matplotlib | 图表绘制(qt5agg backend 嵌入) |
| cantools | DBC 文件解析与信号解码(41/42 兼容) |
| python-can | BLF/ASC 日志文件读取 |
| pandas | 数据处理与过滤 |
| numpy | 数值计算 |
| openpyxl | .xlsx 文件读写 |
| xlrd 1.2.0 | .xls(OLE2)文件读取(1.2.0 是最后支持 .xls 的版本) |
| lxml | HTML 表格格式的 Excel 文件解析 |
| PyInstaller | 打包为可执行文件 |
- Python 3.10+
- Windows 10/11(推荐)
git clone <repo-url>
cd CanMsgParser
pip install -r requirements.txt
python main.py首次启动时,应用会自动检测依赖库,如缺失会弹窗询问是否自动安装。
python build.py生成的可执行文件位于 dist/CanMsgParser/CanMsgParser.exe,运行时不弹出控制台窗口。
-
加载 DBC 文件
- 菜单:文件 → 加载 DBC...
- 或直接拖拽 .dbc 文件到窗口
- 加载后左侧信号树显示所有报文和信号
-
加载日志文件
- 菜单:文件 → 加载日志 (BLF/ASC)...
- 或拖拽 .blf / .asc 文件到窗口
- 状态栏显示帧数和时间范围
-
绘制信号曲线
- 在「信号分组」窗搜索树中勾选信号 → 点击「添加到曲线图」,曲线图页「已选信号」区会列出当前选择(可「移除选中 / 清空」,选中后按 Delete 键亦可);加入不自动绘图,需在曲线图页点击「绘制」按钮才会解码并绘图
- 也可在曲线图页点击"绘制"按钮对当前已选信号重新解码并绘制
- 曲线显示在曲线图 Tab
-
查看原始报文
- 切换到"报文表格"Tab
- 双击报文行展开查看解码后的信号值
- 使用过滤栏按 ID/信号名/时间筛选
-
信号模拟上报(PCAN 发送)
- 先在「连接状态」页连接 CAN(设置通道 / 波特率)
- 在「信号分组」窗勾选信号,点击「添加到模拟上报」
- 信号按报文 ID 自动聚合成「报文组」(树形);在组周期 SpinBox 设该组上报周期,为组内各信号设「模拟值 / 手动值」(可勾选「自动递增」)
- 点击组行「发送」单独发该组(顶部按钮会同步变为「停止模拟上报」),或点顶部「开始模拟上报」一键发全部;下方日志显示已发送帧
-
信号实时监控(PCAN 接收)
- 先在「连接状态」页连接 CAN(设置通道 / 波特率)
- 在「信号分组」窗勾选要监控的信号,点击「添加到实时监控」
- 点击「开始监控」,实时曲线自动绘制(默认独立子图,可点「切换为共享 Y 轴」合并);监控中可点「重置曲线」清空画面并继续记录
-
查看实时报文
- 在「连接状态」页连接 CAN 后,切换到"实时报文"Tab,自动开始监听总线报文
- 总线上的报文按 ID 单行实时刷新;双击任意行就地展开该帧解码信号,子项显示:十六进制值(左侧)/ 十进制值(右侧,含枚举名)/ 单位 / 信号描述(DBC 优先、缺失回退 Excel)
- 工具栏「⏸ 暂停监听 / ▶ 开始监听」可随时暂停或恢复本页收帧(暂停不影响共享总线与其他页面;设备重连后不会自动恢复,需手动开始)
- 点击「开始录制」可将总线报文保存为日志,格式可选 BLF / ASC(默认
CANLOG_年月日_时分秒.blf)
-
报文回放
- 在「连接状态」页连接 CAN(回放复用同一共享总线)
- 在「报文回放」Tab 点「选择文件」加载 BLF/ASC/LOG 日志,按需要设置回放次数 / 循环 / 速度 / 起始延迟,勾选要回放的报文 ID
- 点「▶ 开始回放」按原始时序发送;点「■ 停止回放」随时停止;回放帧会同步显示在监控页 / 实时报文页
-
查看位图布局
- 切换到"位图查看器"Tab
- 搜索报文 ID 或名称
- 查看信号在数据帧中的位布局
Tab 顺序:连接状态 → 曲线图 → 报文表格 → 模拟上报 → 实时监控 → 实时报文 → 报文回放 → 位图查看器。
共享分组悬浮窗:「信号分组」为可停靠 / 可悬浮 / 可关闭的停靠窗(菜单「视图 → 信号分组」开关)。曲线图、实时监控、模拟上报三页共用同一分组窗,分组内勾选的信号可通过「添加到曲线图 / 实时监控 / 模拟上报」按钮一键分发到对应页。
工具已按「每监视器 DPI 感知(PerMonitorV2)」处理缩放,在混合 DPI 的多屏环境下表现正确:
- 不同分辨率屏幕间拖动窗口:Qt 会按目标屏幕真实 DPI 自动重算缩放比例,小分辨率屏上不再出现按钮/曲线图/搜索树被放得过大、操作空间被挤压的情况。
- 锁屏后解锁:系统按真实 DPI 刷新窗口坐标映射,鼠标点击位置不再整体偏移。
- 实现要点:
main.py在导入 PyQt5 前设置QT_AUTO_SCREEN_SCALE_FACTOR=1等环境变量;build.py通过--manifest app.manifest在 exe 中嵌入PerMonitorV2声明;main_window.py另监听 DPI/分辨率变化并重建平台窗口以兜底刷新缓存比例。
若在某台小屏设备上仍希望整体再缩小一点,可在启动时设置环境变量
QT_SCALE_FACTOR=0.9(需重启生效)做进一步微调。
如果你的 DBC 没有定义信号值描述(ValueDescriptions),可以通过 Excel 文件补充:
- 菜单:文件 → 加载值描述 Excel...
- 或拖拽 .xlsx / .xls 文件到窗口
Excel 文件格式要求:
- 必须包含
Signal Name / 信号名称列 - 必须包含
Signal Value Description / 信号值描述列 - 支持双语表头(英文+中文换行分隔)
- 值描述格式:
0:OFF, 1:ON或0=OFF; 1=ON或0x0-OFF等 - 支持多 sheet(自动查找数据 sheet)
- 兼容 .xls(OLE2)、.xlsx(OpenXML)、HTML 表格伪装的 .xls
- 菜单「视图 → 信号分组」打开共享停靠窗(默认停靠左侧,可拖出悬浮)
- 在分组下拉选择已有分组或点「+ 新建」输入名称(如"空调");「保存配置 / 加载配置」以 JSON 持久化
- 在分组窗内嵌信号树中搜索并勾选信号,点击「加入分组」把勾选信号加入当前分组
- 在分组信号列表中勾选要使用的信号
- 使用分组下方的「添加到曲线图 / 添加到实时监控 / 添加到模拟上报」按钮,将勾选信号一键分发到对应页(点击后自动跳转到对应页;曲线图需再点「绘制」按钮才会绘图)
| 操作 | 效果 |
|---|---|
Ctrl + 鼠标滚轮 |
以鼠标位置为中心 X/Y 轴同时缩放 |
| 鼠标靠近 X 轴 + 滚轮 | 仅 X 轴缩放 |
| 鼠标靠近 Y 轴 + 滚轮 | 仅 Y 轴缩放 |
| 鼠标左键拖拽 | 实时平移曲线视图(跟手) |
| 鼠标悬停曲线 | 高亮 + 弹说明框显示值信息(自动避让曲线) |
| 单击曲线 | 弹出数值说明框并固定高亮(每条曲线最多 3 个) |
| 右键数值说明框 | 关闭该说明框 |
| "标记时间差"按钮 | 进入标记模式,最多放 3 组标记点显示 Δt |
| "自适应复位"按钮 | 恢复最佳视图 |
| "切换为独立子图/共享Y轴" | 切换图表模式 |
CanMsgParser/
├── main.py # 应用入口(含启动画面、依赖检测)
├── main_window.py # 主窗口布局
├── build.py # PyInstaller 打包脚本
├── requirements.txt # 依赖列表
├── core/
│ ├── can_data.py # 数据模型 (SignalDef, MessageDef, DecodedSignal)
│ ├── dbc_parser.py # DBC 解析封装 (cantools)
│ ├── log_loader.py # BLF/ASC 加载器 (python-can)
│ ├── signal_cache.py # LRU 解码缓存
│ ├── can_connection.py # 进程内共享 CAN 连接管理器(CanConnectionManager,多页 fan-out)
│ └── can_utils.py # PCAN 连接与 DBC 编解码共享工具
├── widgets/
│ ├── signal_tree.py # 信号树 + 搜索
│ ├── plot_widget.py # 曲线图 + 交互(含实时曲线模式)
│ ├── signal_group_panel.py # 信号分组管理(共享悬浮窗)
│ ├── message_table.py # 报文表格 + 值变化高亮
│ ├── bit_layout_view.py # 位图可视化
│ ├── realtime_monitor_widget.py # 信号实时监控页(PCAN 实时接收 + 实时曲线)
│ ├── realtime_message_widget.py # 实时报文页(PCAN 实时收帧 + 就地展开解码信号 + 暂停/开始监听)
│ ├── signal_sim_widget.py # 信号模拟上报页(按报文 ID 分组 + 整帧聚合发送)
│ ├── replay_widget.py # 报文回放页(BLF/ASC/LOG 回放 + 次数/循环/速度)
│ └── splash_screen.py # 启动画面
├── utils/
│ ├── bit_utils.py # Intel/Motorola 位布局计算
│ ├── lttb.py # LTTB 降采样算法
│ ├── export_utils.py # 导出工具
│ ├── excel_value_loader.py # Excel 值描述加载
│ └── dependency_check.py # 启动依赖检测
├── workers/
│ ├── load_worker.py # QThread 工作线程(日志加载/解码)
│ ├── can_capture_worker.py # QThread 工作线程(PCAN 实时接收监控)
│ └── can_sim_worker.py # 遗留:QThread 周期模拟上报(现由 signal_sim_widget 直接整帧聚合发送,已不再调用)
└── tests/ # 单元测试与集成测试
python -m pytest tests/ -v覆盖:数据模型、位布局计算、DBC 解析、日志加载、LTTB 降采样、信号缓存、报文表格展开、字节变化高亮等。
截图基于 v1.3.0,运行环境 Windows 11 / 深色主题 / 1920×1080。
日志回放曲线,支持时间差标记(最多 3 组,组内同色 + 区间色带 + Δt 提示框)、 悬停查看数值、左键拖动平移、Ctrl+滚轮以鼠标位置为中心缩放。
实时曲线 + 时间差标记;工具栏提供「切换为共享 Y 轴 / 标记时间差 / 自适应复位 / 清除标记」。
支持按报文 ID / 信号名 / 时间区间筛选,报文行可展开查看该帧解码出的全部信号值。
多报文 ID 同时筛选(顶部带 ID 搜索)、报文名模糊搜索,以及 BLF / ASC 两种录制格式。
按分组批量模拟上报信号,可设置周期、模式与取值,并查看各 ID 的发送计数。
更多截图与说明见 CanMsgParser/README.md。
- 作者:laizhenxin
- 邮箱:lzxDchaser@126.com




