1. 从Simulink模型生成C代码并集成到dSPACE原型

从Simulink模型生成C代码并集成到dSPACE原型 学习卡片

任务说明

本案例完成从Simulink模型生成嵌入式C代码,并集成到dSPACE原型环境的完整闭环。目标是将一个离散PID控制器模型通过Simulink Coder生成平台无关的C代码,再封装为dSPACE可调用的函数接口,最终在dSPACE ControlDesk中完成变量观测与参数在线修改。

模型准备

在Simulink中建立离散PID控制器模型,采样时间设为0.001s。模型输入为误差信号e(k),输出为控制量u(k),内部状态包含积分累加项与上一拍误差。PID参数Kp、Ki、Kd定义为Simulink参数对象,便于生成代码后作为全局变量暴露。

代码生成配置

使用Simulink Coder生成C代码,关键配置如下:

  • 系统目标文件:ert.tlc(嵌入式实时目标)
  • 求解器:离散(fixed-step,步长0.001s)
  • 代码接口打包:Nonreusable function,生成独立函数PID_Step
  • 全局变量:勾选Kp、Ki、Kd为Exported global
  • 生成报告:仅保留model.h、model.c、model_private.h

生成代码核心结构

生成后的PID_Step函数原型如下(以实际生成头文件为准):

/* model.h 关键声明 */
extern real_T Kp;   /* 比例系数 */
extern real_T Ki;   /* 积分系数 */
extern real_T Kd;   /* 微分系数 */

extern void PID_Step(real_T rtu_e, real_T *rty_u);

dSPACE集成封装

在dSPACE DS1104或SCALEXIO环境中,通过S-Function Builder或手写TLC封装层调用生成的C函数。以下为最小封装实现,将Simulink生成的步进函数映射为dSPACE实时任务回调:

/* dSPACE_wrapper.c */
#include "model.h"

/* dSPACE实时中断服务中调用 */
void dSPACE_Task_1ms(void)
{
    real_T err = ReadADC_Channel(0);   /* 从ADC读取实际值 */
    real_T ref = 1.0;                   /* 目标值,可在ControlDesk修改 */
    real_T e = ref - err;
    real_T u = 0.0;

    PID_Step(e, &u);                    /* 调用生成的PID步进函数 */

    WriteDAC_Channel(0, u);             /* 输出控制量 */
}

变量映射与观测

在dSPACE ControlDesk中建立变量文件(.var),将Kp、Ki、Kd、u、e映射为可观测变量。通过ControlDesk的在线调参界面,可在原型运行过程中实时修改PID参数并观察阶跃响应曲线。

验证方法

验证分为两个层面:

  1. 代码生成正确性:在Simulink中搭建相同的PID模型,使用相同输入序列(如单位阶跃),对比模型仿真输出与生成的C代码在PC上位机(通过VS或MinGW编译)的输出,两者误差应小于1e-6。
  2. dSPACE实时运行:将封装后的代码下载到dSPACE板卡,通过ControlDesk给定阶跃参考信号,观察实际输出响应曲线。判定标准:稳态误差小于2%,超调量小于10%,调节时间小于50ms(与模型仿真趋势一致)。

判定标准

当满足以下条件时,本案例判定通过:

  • Simulink Coder成功生成C代码,且无编译错误;
  • 封装层代码在dSPACE环境中编译链接通过;
  • ControlDesk能正确显示Kp、Ki、Kd及输出变量;
  • 在线修改Kp后,输出响应幅值随之变化,且变化方向符合PID控制规律。
Simulink模型 离散PID控制器 Ts = 0.001s Simulink Coder ert.tlc → model.c/.h 导出全局变量 Kp/Ki/Kd dSPACE集成层 S-Function封装 实时任务调用 自动生成 手写封装 数据流与观测路径 ADC采集 实际值 y(k) 误差计算 e(k) = r(k) - y(k) PID_Step() Kp, Ki, Kd 全局变量 ControlDesk在线可调 DAC输出 控制量 u(k) 参考值 r(k) ControlDesk设定 观测点(ControlDesk) e(k), u(k), Kp, Ki, Kd 验证路径:模型仿真输出 vs dSPACE实测输出 → 误差 < 1e-6(离线) / 稳态误差 < 2%(实时)