当前位置:   article > 正文

Simlulink学习笔记——C代码自动生成解析_sinlink模型怎么生成.c

sinlink模型怎么生成.c

一、理想质量 - 弹簧 - 阻尼系统

        弹簧-质量-阻尼系统是一种比较普遍的机械振动系统,生活中也随处可见这种系统,例如汽车缓冲器就是一种可以耗减运动能量的装置,是保证驾驶员行车安全的必备装置。我们通过建立理想的质量 - 弹簧 - 阻尼系统的二阶物理系统模型,来学习simulink的应用。系统方程的的组成部分为质量,刚度和阻尼,方程如下所示:

接下来我们建立模型如下所示:

我们打开红色文本 Parameter Initialization,里面是一些参数初始化命令,如下所示:

在运行模型前,点击该文本,触发回调函数,完成参数初始化过程,点击之后,我们观察到工作空间中的变量如下:

参数初始化以后,我们运行模型:

 

 

二、C代码自动生成

            本示例学习如何为Simulink模型选择目标,生成用于实时模拟的C代码以及查看生成的文件。该模型代表一个8位计数器,为一个触发子系统提供信号,该子系统由常量模块INC,LIMIT和RESET等组成。 输入和输出表示模型的I / O,放大器子系统通过增益系数K放大输入信号,当信号equal_to_count为真时,增益系数K更新。

          模型如下所示:

打开放大器子系统,可以看到内部结构如下:

   变量的参数初始化如下所示:

     建立好模型以后,单击Simulation -> Configuration Parameters,从模型编辑器打开Configuration Parameters对话框:

        为了生成特定目标环境或目的代码,我们需要使用系统目标文件提供一些内置目标选项,系统目标文件控制目标代码的生成过程。 

      设置完成以后,回到模型窗口,使用快捷键Ctrl + B生成代码:

在生成的文件当中,我们找到这几个源文件和头文件:

接下来我们解读自动生成的代码,为了方便起见,我们把它的注释删除掉。

头文件 example2018_7_25.h 如下所示:

  1. #ifndef RTW_HEADER_example2018_7_25_h_
  2. #define RTW_HEADER_example2018_7_25_h_
  3. #include <stddef.h>
  4. #include <string.h>
  5. #ifndef example2018_7_25_COMMON_INCLUDES_
  6. # define example2018_7_25_COMMON_INCLUDES_
  7. #include "rtwtypes.h"
  8. #include "rtw_continuous.h"
  9. #include "rtw_solver.h"
  10. #endif
  11. #include "example2018_7_25_types.h"
  12. #include "multiword_types.h"
  13. #ifndef rtmGetErrorStatus
  14. # define rtmGetErrorStatus(rtm) ((rtm)->errorStatus)
  15. #endif
  16. #ifndef rtmSetErrorStatus
  17. # define rtmSetErrorStatus(rtm, val) ((rtm)->errorStatus = (val))
  18. #endif
  19. typedef struct {
  20. uint8_T X;
  21. } DW_example2018_7_25_T;
  22. typedef struct {
  23. ZCSigState Amplifier_Trig_ZCE;
  24. } PrevZCX_example2018_7_25_T;
  25. typedef struct {
  26. int32_T Input;
  27. } ExtU_example2018_7_25_T;
  28. typedef struct {
  29. int32_T Output;
  30. } ExtY_example2018_7_25_T;
  31. struct tag_RTM_example2018_7_25_T {
  32. const char_T *errorStatus;
  33. };
  34. extern DW_example2018_7_25_T example2018_7_25_DW;
  35. extern ExtU_example2018_7_25_T example2018_7_25_U;
  36. extern ExtY_example2018_7_25_T example2018_7_25_Y;
  37. extern void example2018_7_25_initialize(void);
  38. extern void example2018_7_25_step(void);
  39. extern void example2018_7_25_terminate(void);
  40. extern RT_MODEL_example2018_7_25_T *const example2018_7_25_M;
  41. #endif

头文件 example2018_7_25_private.h 如下所示:

  1. #ifndef RTW_HEADER_example2018_7_25_private_h_
  2. #define RTW_HEADER_example2018_7_25_private_h_
  3. #include "rtwtypes.h"
  4. #include "multiword_types.h"
  5. #endif

源文件如下所示:

  1. #include "example2018_7_25.h"
  2. #include "example2018_7_25_private.h"
  3. // UnitDelay Block states
  4. DW_example2018_7_25_T example2018_7_25_DW;
  5. // Previous zero-crossings (trigger) states
  6. PrevZCX_example2018_7_25_T example2018_7_25_PrevZCX;
  7. // External inputs
  8. ExtU_example2018_7_25_T example2018_7_25_U;
  9. // External outputs
  10. ExtY_example2018_7_25_T example2018_7_25_Y;
  11. // Real-time model
  12. RT_MODEL_example2018_7_25_T example2018_7_25_M_;
  13. RT_MODEL_example2018_7_25_T *const example2018_7_25_M = &example2018_7_25_M_;
  14. /* Model step function */
  15. void example2018_7_25_step(void)
  16. {
  17. boolean_T rtb_equal_to_count;
  18. // 定义了一个布尔变量,用来表示比较结果
  19. example2018_7_25_DW.X++;
  20. // example2018_7_25_DW.X是延时模块的值,即累加值,
  21. // 由于模型中的INC为常数1,所以每次加1
  22. // 首先呢,变量example2018_7_25_DW是一个结构体,其变量声明语句如下所示:
  23. // extern DW_example2018_7_25_T example2018_7_25_DW;
  24. // 显然,DW_example2018_7_25_T代表一个结构体,我们找到这个结构体的定义如下:
  25. // typedef struct{
  26. // uint8_T X;
  27. // } DW_example2018_7_25_T;
  28. rtb_equal_to_count = (example2018_7_25_DW.X != 16);
  29. if ( rtb_equal_to_count && (example2018_7_25_PrevZCX.Amplifier_Trig_ZCE != POS_ZCSIG))
  30. {
  31. example2018_7_25_Y.Output = example2018_7_25_U.Input << 1;
  32. // 对于逻辑(算术)左移,且不发生溢出时,结果增加两倍,
  33. // 这正好对应于模型中触发子系统中的增益模块的增益值2
  34. }
  35. // 首先呢,变量example2018_7_25_PrevZCX 也是一个结构体变量,其变量声明语句如下所示:
  36. // PrevZCX_example2018_7_25_T example2018_7_25_PrevZCX;
  37. // 显然,PrevZCX_example2018_7_25_T是一个结构体,其结构体定义如下:
  38. // typedef struct {
  39. // ZCSigState Amplifier_Trig_ZCE;
  40. // } PrevZCX_example2018_7_25_T;
  41. // 那么,变量example2018_7_25_U 的定义如下:
  42. // ExtU_example2018_7_25_T example2018_7_25_U;
  43. // 结构体 ExtU_example2018_7_25_T的定义如下:
  44. // typedef struct {
  45. // int32_T Input;
  46. // } ExtU_example2018_7_25_T;
  47. // 最后,变量example2018_7_25_Y 的定义如下:
  48. // ExtY_example2018_7_25_T example2018_7_25_Y;
  49. // 结构体 ExtY_example2018_7_25_T 的定义如下:
  50. // typedef struct {
  51. // int32_T Output;
  52. // } ExtY_example2018_7_25_T;
  53. example2018_7_25_PrevZCX.Amplifier_Trig_ZCE = rtb_equal_to_count;
  54. // 更新触发状态
  55. if (!rtb_equal_to_count)
  56. {
  57. example2018_7_25_DW.X = 0U;
  58. }
  59. // 当布尔值rtb_equal_to_count为假时,代表计数器已经计数到16了,
  60. // 当计数到16时,需要重新将延时模块UnitDelay的状态值(即累加值)归零,
  61. // 此时0U表示无符号形式存储的零值
  62. // 在头文件中,还有定义:
  63. // Logical type definitions
  64. /* #if (!defined(__cplusplus))
  65. # ifndef false
  66. # define false (0U)
  67. # endif
  68. # ifndef true
  69. # define true (1U)
  70. # endif
  71. #endif
  72. #endif
  73. */
  74. }
  75. /* Model initialize function */
  76. void example2018_7_25_initialize(void)
  77. {
  78. rtmSetErrorStatus(example2018_7_25_M, (NULL));
  79. // 首先,变量example2018_7_25_M的定义如下:
  80. // RT_MODEL_example2018_7_25_T * const example2018_7_25_M = &example2018_7_25_M_;
  81. // 那么,RT_MODEL_example2018_7_25_T又是个什么数据类型呢?可以看到定义如下:
  82. // typedef struct tag_RTM_example2018_7_25_T RT_MODEL_example2018_7_25_T;
  83. (void) memset((void *)&example2018_7_25_DW, 0,sizeof(DW_example2018_7_25_T));
  84. // 将example2018_7_25_DW所在的内存空间赋0
  85. // memset函数经常用于清0
  86. example2018_7_25_U.Input = 0;
  87. example2018_7_25_Y.Output = 0;
  88. example2018_7_25_PrevZCX.Amplifier_Trig_ZCE = POS_ZCSIG;
  89. example2018_7_25_DW.X = 0U;
  90. example2018_7_25_Y.Output = 0;
  91. }
  92. /* Model terminate function */
  93. void example2018_7_25_terminate(void)
  94. {
  95. /* (no terminate code required) */
  96. }

      显然自动生成的代码默认变量的数据类型为结构体,因此程序中运用了大量的结构体类型,读起来额外的费劲,后期可以自己手动完善来增强的代码的可读性。当然源文件当中没有主函数,不能直接运行,里面只是逻辑代码,也没有涉及到硬件的底层驱动。不过,基于模型的设计还是能够加快项目的研发速度,降低研发成本。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/744696
推荐阅读
相关标签
  

闽ICP备14008679号