一、前言
在车载 MBD(基于模型设计)开发流程中,项目变量、参数、信号、总线、枚举、类型别名数量庞大,如果手动在 Simulink 数据字典(.sldd)里逐条创建,存在如下痛点:
- 人工录入效率极低,变量上百条时重复工作量巨大;
- 手敲容易出现名称、数据类型、上下限、单位、存储类写错,后期仿真、代码生成报错难排查;
- 多人协作时,Excel 作为通用文档方便需求、测试、软件工程师统一维护变量清单,而原生 Simulink 不支持直接导入 Excel 批量生成 SLDD;
- 项目自定义
THBPackage存储类需要批量绑定,手动逐条设置 StorageClass/PackageName 极其繁琐。
针对以上车载开发场景痛点,本文分享一套成熟可直接复用的Excel2SLDD.m自动化脚本,支持类型别名 Alias、枚举 Enum、Bus 总线、InPort 信号、Parameter 参数五大类对象批量生成 SLDD,完美适配自定义 Package 存储类,一键完成 Excel 到数据字典全流程转换。
二、整体方案架构
2.1 文件结构说明
plaintext
bash
Location_ver2
├─ Location.xlsx # 变量总配置表,分多Sheet管理不同类型对象
│ ├─ othername # 类型别名AliasType(SvcDataType/OrcDataType)
│ ├─ Enums # 枚举定义表
│ ├─ Bus # 总线结构体定义
│ ├─ InPort # 输入信号Signal
│ ├─ Parameter # 可调参数Parameter
│ ├─ OutPort # 输出信号(拓展预留)
│ └─ Matlab Var # 自定义Matlab变量预留Sheet
├─ Location.sldd # 脚本自动生成/更新的数据字典
└─ Excel2SLDD.m # 核心转换脚本
2.2 Excel 各 Sheet 字段规范(核心配置模板)
1)Parameter 参数表(可调标定参数)
表格
| Name | Min | Max | Width | Discription | PackageName | Storageclass | Datatype | Unit | InitialValue |
|---|---|---|---|---|---|---|---|---|---|
| cUwbLocation_x_PointA | X-coordinate of base station A | THBPackage | Auto | single | m | ||||
| Kp | 0 | 100 | 比例增益 | Auto | Auto | single | Nm |
PackageName:填写THBPackage则绑定项目自定义存储包,填Auto使用默认规则;Min/Max:参数上下限,用于模型参数校验;InitialValue:参数默认初始值,支持标量 / 一维 / 二维数组(如[4 5 6;16 19 20])。
2)InPort 信号表(模型输入信号 Signal)
表格
| Name | Min | Max | Width | Discription | PackageName | Storageclass | Datatype | Unit | InitialValue |
|---|---|---|---|---|---|---|---|---|---|
| sUwbLocation_L_DistanceAC | 0 | 100 | Distance between tag C and A | THBPackage | Auto | single | m | 22 | |
| bus1 | 总线输入信号 | Auto | Auto | Bus_CMAMeasure |
- Datatype 支持基础类型
single/double/uint16,也支持自定义 Bus/Enum 类型; - Width:向量信号长度,标量留空。
3)othername(类型别名 AliasType)
用于给基础数据类型起项目统一别名,如SvcDataType = single、OrcDataType = uint32,统一全模型数据类型规范。
4)Enums(枚举表)
支持多枚举定义,自动向下填充枚举名称,批量生成EnumTypeDefinition对象,适配故障码、状态码场景。
5)Bus(总线表)
逐行定义总线内部元素名称、类型、上下限、注释,脚本自动组装Bus与BusElement对象。
2.3 脚本执行流程
- 前置清理 :关闭所有打开的 Simulink 模型,解除模型与 SLDD 绑定,强制关闭所有
.sldd文件,释放文件句柄,避免文件锁定读写失败; - Excel 分 Sheet 读取:统一读取规则,全部单元格转为 char 消除数据类型警告,过滤空名称无效行;
- 分层生成 SLDD 对象:按「类型别名→枚举→总线→参数→信号」顺序创建,解决对象依赖问题(总线依赖枚举、信号依赖总线);
- 批量绑定自定义 Package :读取 Excel 中
PackageName字段,自动给 Parameter/Signal 设置自定义存储包THBPackage; - 生成汇总日志:控制台打印各类对象成功数量,方便校验是否漏生成;
- 保存 SLDD 文件:持久化写入数据字典,可直接关联 Simulink 模型使用。
三、核心脚本代码解析(Excel2SLDD.m)
3.1 前置清理模块(解决 SLDD 文件锁定)
Simulink 打开模型时会占用绑定的 sldd,直接覆盖写入会报文件只读、锁定错误,因此脚本开头强制释放所有占用:
matlab
bash
clc;
clear all;
close all;
%% ========== 前置步骤:释放所有Simulink模型与SLDD字典占用 ==========
% 作用:防止sldd被模型锁定导致删除/写入失败
fprintf('正在检查已打开simulink模型,准备释放sldd文件占用...\n');
% 获取当前所有打开的模型
openModels = find_system('type','block_diagram');
if ~isempty(openModels)
fprintf('检测到打开的模型,执行字典解绑操作\n');
% 遍历所有打开模型,解除DataDictionary绑定
for mdlIdx = 1:length(openModels)
mdlName = openModels{mdlIdx};
try
% 获取模型当前关联的字典
dictList = get_param(mdlName,'DataDictionary');
if ~isempty(dictList)
% 置空字典绑定
set_param(mdlName,'DataDictionary','');
fprintf('模型【%s】已解除关联数据字典\n',mdlName);
end
catch ME
% 捕获模型读取异常,不中断脚本
fprintf('模型【%s】解除字典关联提示:%s\n',mdlName,ME.message);
end
end
else
fprintf('当前未打开任何Simulink模型,跳过模型解绑步骤\n');
end
% 强制关闭全部打开的sldd,丢弃未保存修改,彻底释放文件句柄
Simulink.data.dictionary.closeAll('-discard');
pause(0.3); % 短暂延时等待文件释放完成
clear dictObj designData; % 清空旧字典变量
fprintf('已全部释放sldd文件占用\n\n');
3.2 Excel 文件读取通用逻辑
统一配置readtable读取规则:保留原始列名、全部单元格读取为字符串,避免数字 / 空单元格自动转类型引发警告;同时过滤 Name 为空的无效行:
matlab
bash
%% ========== 1. Excel文件路径配置与读取初始化 ==========
fullExcelPath = 'Location.xlsx';
filePath = fileparts(fullExcelPath);
if ~exist(fullExcelPath,'file')
error('Excel文件不存在!');
end
% 将Excel所在目录加入MATLAB搜索路径,兼容外部枚举m文件
addpath(filePath);
fprintf('已添加当前路径到Matlab搜索路径:%s\n',filePath);
%% 2.1 othername:数据类型别名 AliasType
fprintf('\n>>> 读取Sheet othername(类型别名)\n');
opts_alias = detectImportOptions(fullExcelPath,'Sheet','othername');
opts_alias.VariableNamingRule = "preserve"; % 保留原始列名,不自动替换空格
opts_alias.VariableTypes(:) = {'char'}; % 全部列读取为字符串
rawAlias = readtable(fullExcelPath, opts_alias,'Sheet','othername');
rawAlias = rawAlias(~ismissing(rawAlias."Name"),:); % 过滤名称为空的无效行
fprintf('读取到有效别名数量:%d\n',height(rawAlias));
%% 2.3 Enums 枚举表读取(适配自定义枚举列)
fprintf('\n>>> 读取Sheet Enums\n');
opts_enum = detectImportOptions(fullExcelPath,'Sheet','Enums');
opts_enum.VariableNamingRule = "preserve";
opts_enum.VariableTypes(:) = {'char'};
rawEnum0 = readtable(fullExcelPath, opts_enum,'Sheet','Enums');
% 向下填充EnumName空单元格,解决Excel只首行填枚举名、下方空白问题
rawEnum = fillmissing(rawEnum0,'previous','DataVariables',{'EnumName','ElementNum'});
3.3 SLDD 对象创建核心逻辑(Parameter 信号示例)
读取 Excel 中 PackageName 字段,自动绑定项目自定义THBPackage存储类,兼容标量、数组初始值:
matlab
bash
% 循环创建Parameter对象
for pIdx = 1:height(rawParam)
pRow = rawParam(pIdx,:);
paramName = pRow.Name;
% 创建Simulink Parameter对象
paramObj = Simulink.Parameter;
paramObj.DataType = pRow.Datatype;
paramObj.Unit = pRow.Unit;
paramObj.Description = pRow.Discription;
% 上下限赋值
if ~ismissing(pRow.Min) && ~strlength(pRow.Min)
paramObj.Min = str2double(pRow.Min);
end
if ~ismissing(pRow.Max) && ~strlength(pRow.Max)
paramObj.Max = str2double(pRow.Max);
end
% 初始值支持数组字符串解析
initStr = pRow.InitialValue;
if ~ismissing(initStr) && strlength(initStr)>0
paramObj.Value = eval(initStr);
end
% 绑定自定义Package存储类
pkgName = pRow.PackageName;
if strcmp(pkgName,'THBPackage')
paramObj.StorageClass = 'THBPackage';
else
paramObj.StorageClass = 'Auto';
end
% 写入SLDD设计区
designData.assignin(paramName, paramObj);
end
3.4 执行结果汇总打印
脚本全部执行完成后,控制台输出各类对象创建成功数量,快速校验是否漏生成变量:
plaintext
bash
================================ 生成完成汇总 =================================
数据字典最终路径: E:\Mat_tool\THB_Trunk\Trunk\sldd\Location_ver2\Location.sldd
1. 类型别名(AliasType): 成功 2 个 [SvcDataType,OrcDataType]
2. 枚举(EnumTypeDefinition): 成功 3 个 [Enum1,FAULT_CODE,LOC_STATUS]
3. Bus总线: 成功 3 / 总 3 个
4. Parameter参数: 成功 12 / 总 12 个
5. Signal信号: 成功 7 / 总 7 个
================================================================================
四、使用操作步骤
- 维护 Excel 变量清单:按照 Sheet 规范填写所有参数、信号、总线、枚举、类型别名,统一交付给软件工程师;
- 配置脚本文件路径 :修改
fullExcelPath为你的 Excel 文件路径; - 运行脚本 :直接执行
Excel2SLDD.m,等待控制台输出汇总日志; - 校验 SLDD 内容 :打开生成的
.sldd文件,在模型资源管理器 Design Data 查看所有对象,核对数量与 Excel 一致; - 关联 Simulink 模型:模型右键→属性→数据字典,选择生成的 sldd 文件,模型即可直接调用字典内所有变量。