【研发日记】Matlab/Simulink自动生成代码(二)——五种选择结构实现方法
文章目录
前言
Simulink实现选择结构
自动生成C代码
变式一
变式二
变式三
变式四
总结
前言
见《深入拆解Simulink自动生成代码(一)——数据流处理》
Simulink实现选择结构
用Simulink实现选择结构的一个最简单编程举例如下:
自动生成C代码
上述选择结构的Simulink自动生成的对应C代码如下:
/* Switch: '/Switch' incorporates: * UnitDelay: '/Output' */ if (CodeGenerate_DW.Output_DSTATE > 0) { /* Outport: '/y1' incorporates: * Constant: '/Constant' */ CodeGenerate_Y.y1 = 5.0; } else { /* Outport: '/y1' incorporates: * Constant: '/Constant2' */ CodeGenerate_Y.y1 = 10.0; } /* End of Switch: '/Switch' */ /* Switch: '/FixPt Switch' incorporates: * Constant: '/FixPt Constant' * Constant: '/Constant' * Sum: '/FixPt Sum1' * UnitDelay: '/Output' */ if ((uint8_T)(CodeGenerate_DW.Output_DSTATE + 1U) > 7) { CodeGenerate_DW.Output_DSTATE = 0U; } else { CodeGenerate_DW.Output_DSTATE++; } /* End of Switch: '/FixPt Switch' */
变式一
基于上述举例,增加选择结构的选项,生成的对应代码如下所示:
/* SwitchCase: '/Switch Case' incorporates: * UnitDelay: '/Output' */ switch (CodeGenerate_DW.Output_DSTATE) { case 1: /* Outputs for IfAction SubSystem: '/Switch Case Action Subsystem' incorporates: * ActionPort: '/Action Port' */ /* Outport: '/y1' incorporates: * Constant: '/Constant1' * Inport: '/In1' */ CodeGenerate_Y.y1 = 5.0; /* End of Outputs for SubSystem: '/Switch Case Action Subsystem' */ break; case 2: /* Outputs for IfAction SubSystem: '/Switch Case Action Subsystem1' incorporates: * ActionPort: '/Action Port' */ /* Outport: '/y1' incorporates: * Constant: '/Constant3' * Inport: '/In1' */ CodeGenerate_Y.y1 = 10.0; /* End of Outputs for SubSystem: '/Switch Case Action Subsystem1' */ break; case 3: /* Outputs for IfAction SubSystem: '/Switch Case Action Subsystem2' incorporates: * ActionPort: '/Action Port' */ /* Outport: '/y1' incorporates: * Constant: '/Constant4' * Inport: '/In1' */ CodeGenerate_Y.y1 = 15.0; /* End of Outputs for SubSystem: '/Switch Case Action Subsystem2' */ break; default: /* Outputs for IfAction SubSystem: '/Switch Case Action Subsystem3' incorporates: * ActionPort: '/Action Port' */ /* Outport: '/y1' incorporates: * Constant: '/Constant5' * Inport: '/In1' */ CodeGenerate_Y.y1 = 0.0; /* End of Outputs for SubSystem: '/Switch Case Action Subsystem3' */ break; } /* End of SwitchCase: '/Switch Case' */ /* Switch: '/FixPt Switch' incorporates: * Constant: '/FixPt Constant' * Constant: '/Constant' * Sum: '/FixPt Sum1' * UnitDelay: '/Output' */ if ((uint8_T)(CodeGenerate_DW.Output_DSTATE + 1U) > 7) { CodeGenerate_DW.Output_DSTATE = 0U; } else { CodeGenerate_DW.Output_DSTATE++; } /* End of Switch: '/FixPt Switch' */
变式二
基于上述举例,升级选择结构的判断条件,生成的对应代码如下所示:
real_T tmp; /* Math: '/Mod' incorporates: * Constant: '/Constant6' * DataTypeConversion: '/Data Type Conversion' * Math: '/Mod1' * Math: '/Mod2' * UnitDelay: '/Output' */ tmp = rt_modd_snf((real_T)CodeGenerate_DW.Output_DSTATE, 3.0); /* Outputs for Enabled SubSystem: '/Subsystem' incorporates: * EnablePort: '/Enable' */ /* RelationalOperator: '/Compare' incorporates: * Constant: '/Constant' * Math: '/Mod' */ if (tmp == 0.0) { /* Merge: '/Merge1' incorporates: * Constant: '/Constant7' * Inport: '/In1' */ CodeGenerate_B.Merge1 = 5.0; } /* End of RelationalOperator: '/Compare' */ /* End of Outputs for SubSystem: '/Subsystem' */ /* Outputs for Enabled SubSystem: '/Subsystem1' incorporates: * EnablePort: '/Enable' */ /* RelationalOperator: '/Compare' incorporates: * Constant: '/Constant' */ if (tmp == 1.0) { /* Merge: '/Merge1' incorporates: * Constant: '/Constant9' * Inport: '/In1' */ CodeGenerate_B.Merge1 = 10.0; } /* End of RelationalOperator: '/Compare' */ /* End of Outputs for SubSystem: '/Subsystem1' */ /* Outputs for Enabled SubSystem: '/Subsystem2' incorporates: * EnablePort: '/Enable' */ /* RelationalOperator: '/Compare' incorporates: * Constant: '/Constant' */ if (tmp == 2.0) { /* Merge: '/Merge1' incorporates: * Constant: '/Constant11' * Inport: '/In1' */ CodeGenerate_B.Merge1 = 15.0; } /* End of RelationalOperator: '/Compare' */ /* End of Outputs for SubSystem: '/Subsystem2' */ /* Switch: '/FixPt Switch' incorporates: * Constant: '/FixPt Constant' * Constant: '/Constant' * Sum: '/FixPt Sum1' * UnitDelay: '/Output' */ if ((uint8_T)(CodeGenerate_DW.Output_DSTATE + 1U) > 7) { CodeGenerate_DW.Output_DSTATE = 0U; } else { CodeGenerate_DW.Output_DSTATE++; } /* End of Switch: '/FixPt Switch' */ /* Outport: '/y1' incorporates: * MATLAB Function: '/MATLAB Function2' */ CodeGenerate_Y.y1 = CodeGenerate_B.Merge1;
变式三
基于上述举例,用MATLAB Function来实现,生成的对应代码如下所示:
#include "untitled.h" #include "untitled_private.h" /* Block states (default storage) */ DW_untitled_T untitled_DW; /* External outputs (root outports fed by signals with default storage) */ ExtY_untitled_T untitled_Y; /* Real-time model */ static RT_MODEL_untitled_T untitled_M_; RT_MODEL_untitled_T *const untitled_M = &untitled_M_; /* Model step function */ void untitled_step(void) { uint8_T rtb_Output; /* UnitDelay: '/Output' */ rtb_Output = untitled_DW.Output_DSTATE; /* Switch: '/FixPt Switch' incorporates: * Constant: '/FixPt Constant' * Constant: '/Constant' * Sum: '/FixPt Sum1' * UnitDelay: '/Output' */ if ((uint8_T)(untitled_DW.Output_DSTATE + 1U) > 7) { untitled_DW.Output_DSTATE = 0U; } else { untitled_DW.Output_DSTATE++; } /* End of Switch: '/FixPt Switch' */ /* MATLAB Function: '/MATLAB Function' */ switch (rtb_Output) { case 1: /* Outport: '/y' */ untitled_Y.y = 5.0; break; case 2: /* Outport: '/y' */ untitled_Y.y = 10.0; break; case 3: /* Outport: '/y' */ untitled_Y.y = 15.0; break; default: /* Outport: '/y' */ untitled_Y.y = 0.0; break; } /* End of MATLAB Function: '/MATLAB Function' */ }
变式四
基于上述举例,用Stateflow配合Simulink Function来实现选择结构,参见《【研发日记】嵌入式处理器技能解锁(一)——多任务异步执行调度的三种方法》,示例如下:
总结
以上就是本人拆解Simulink模块自动生成代码时,讲解的第二部分。主要针对Simulink的选择结构,展示了这类模块的使用方法,并对比了相应的C代码。
后续还会更新Simulink其他的几种模块,欢迎评论区留言、点赞、收藏和关注,这些鼓励和支持都将成为笔者持续分享的动力。
另外,上述例程使用的Demo工程可以到笔者的主页查找和下载。
版权声明:原创文章,转载和引用请注明出处和链接,侵权必究!
文章版权声明:除非注明,否则均为主机测评原创文章,转载或复制请以超链接形式并注明出处。