Simulink 模型构建 C 代码流程
一、安装插件
1.1 安装方式
在这里在线安装就可以了。

1.2 安装列表
- Simulink Coder:生成 C 代码
- Embedded Coder:工业级嵌入式代码生成
- ARM Cortex-M Support from Embedded Coder:支持 ARM Cortex-M 和 CMSIS
在线安装速度视网络情况决定。
关于 ARM 支持包 MATLAB 官网有一个专题页:
ARM Support from Embedded Coder - Hardware Support - MATLAB & Simulink
二、新建 Simulink 工程
2.1 保存文件
新建一个文件夹:

使用 MATLAB 打开:

打开 MATLAB R2025b 后 点击 Simulink 模块:

我们选择Embedded Coder 下的单速率应用程序:

打开后,界面内已经有一个现成的两个变量相加的案例,我们选择模型设置。
其于多速率应用程序区别在于:
- 单速率 (Single-rate):整个系统,一个节拍跑到底
- 多速率 (Multi-rate):不同模块,按不同频率运行
因为我们只是简单案例,所以选择单速率应用程序即可。
打开后保存文件:

文件夹内多了一个 .slx 模型文件:

2.2 模型设置

我们选择定步长,每一步长度为 1e-5 秒,也就是 0.00001 秒:

选择仅生成代码:

选择代码样式中的缩进格式,不修改也没关系:

选择创建代码生成报告:

设置目标中,选择执行效率和可溯源性优先:

2.3 新建数据字典
我们添加一个 Gain 模块:

其这个变量名设为 k,因为 k 这个变量不存在,所以周围一圈是红色的:

我们选择基础工作区,添加 k 变量:

选择新建数据字典:

在我们新建的数据字典中,新建一个 k 变量。
关于 parameter 详细可以看:
简单来说,使用 Simulink.Parameter 对象可以:
- 在多个模块参数之间共享一个值
- 表示工程常量或可调标定参数
- 将参数值与其数据类型和其他属性分离
- 配置用于代码生成的参数数据
根据下图选择:

其数据类型选择 single;StorageClass 选择 model default
这样在生成 C 代码时 k 就不是常量了:

生成好之后右键保存我们的 .sldd:

在空白处右键选择模型属性:

在这里选择我们刚创建的 .sldd 文件,载入:

2.4 生成代码
选择 Embedded Coder:

进入 Embedded Coder 后,选择生成代码和查看代码:

可以阅读代码生成报告:

3.5 新建工程
最后我们回到 Matlab 界面,新建一个工程:

三、使用 Simulink bus 生成代码
3.1 模块规范
对于每一个模块来说,我们均需要给他配置三个结构体,分别为:
- input
- config
- outout
模块最外围被一个子系统包括,三个 Simulink 总线进行输入和输出。
以一个 MIT 控制的 Simulink 仿真示例:

等到我们生成每一个 Simulink 模块的时候,均会将数据生成这三个结构体:
MitCtlInput{}:
typedef struct
{
/* 前馈力矩电流 */
real32_T tq_set_NM;
/* 目标位置 */
int64_T pos_tar_p;
/* 当前位置 */
int64_T pos_now_p;
/* q轴最大输出电流 */
real32_T iq_max_A;
/* 目标速度 */
real32_T speed_tar_p_s;
/* 当前速度 */
real32_T speed_now_rad_s;
}
MitCtlInput;
MotorCtlSmConfig{}:
typedef struct
{
/* 运行模式 */
int8_T mode;
/* 欠压保护阈值 */
real32_T under_voltage_protection_V;
/* 过压保护阈值 */
real32_T over_voltage_protection_V;
/* 过速保护阈值 */
real32_T over_speed_protection_rad_s;
/* 欠温保护阈值 */
real32_T under_temperature_protection_d;
/* 过温保护阈值 */
real32_T over_temperature_protection_d;
/* 位置跟随误差保护阈值 */
int32_T position_following_error_protection;
/* 保护生效 */
uint32_T error_enable;
/* 过流保护阈值 */
real32_T over_current_protection_A;
}
MotorCtlSmConfig;
MitCtlOutput{}:
typedef struct
{
/* 目标q轴电流 */
real32_T iq_tar_A;
}
MitCtlOutput;
3.2 创建 Simulink bus

创建总线:

创建三个总线:

代码生成这里我们自定义一个名字,三个都要相同:
3.3 创建子系统
框选我们之前的模型,创建子系统:

至此,我们得到了这样的模型:

3.4 子系统使用 Simulink bus 数据
对这三个 Inport 分别配置成:
- Bus: untited_input
- Bus: untited_config
- Bus: untited_output

将子系统内的数据使用 Bus Selector 分发:

此时生成代码,便将其创造到我们指定的文件夹中,同时也是结构体形式:

3.5 将所有结构体再次打包
创建 untited_Bus:

同样的,这个总线也需要修改头文件:

为了这个数据结构参与编译,我们设置一个透传,输入和输出直接相连即可:


最后,我们得到了这样的一个结构体:

建议使用指针去访问:
typedef struct
{
untited_config untited_config;
untited_input untited_input;
untited_output untited_output;
}
untited_Bus;
untited_Bus bus;
void init(){
untited_Bus *pBus = &bus;
pBus->untited_config.k = 10;
}
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐




所有评论(0)