|
汽车零部件采购、销售通信录 填写你的培训需求,我们帮你找 招募汽车专业培训老师
实验环境
Matlab版本:2023b
操作系统:Win10专业版
硬件平台:YF-STM32-ALPHA 1R5
实验内容:使用 Constant 变量控制 S-Function Builer 模块数码管显示数字 0~F
模型与原理图
本次实验效果如图 5.1 所示,改变“Constant”变量值可以控制数码管的数字显示,所用到的simulink模型如图5.2所示,电路原图如图5.3所示。
图 5.1 使用自建模型驱动数码管效果
图 5.2 I2C 自建数码管驱动模型
图 5.3 数码管原理图
基础模型介绍与分析
如图 5.4 所示为拖入 simulink 工程中的“S-Function Builder”函数,通过在里面添加 C /C++ 语言语句就可以帮助我们实现相应功能,对于习惯于使用 C /C++ 语言用户的 来说,这无疑是非常方便的,"S-Function Builder"模型在库中的位置如图 5.5 所示。
图 5.4 “S-Function Builder” 模型
图 5.5 “S-Function Builder” 模型位置
双击“S-Function Builder”模型,弹出如图 5.6 所示窗口,在“S-Function 名称”中填入名字“CH422G”,注意该名字不要与 本工程 xxx.slx 名字同名,然后将“语言”设置为“C++”(这是因为本次使用的接口函数底层使用 C ++编写),右侧的离散状态的树木设置为“1”,采样模式设置为“Discrete”,”采样时间值“设置为“0.01”,将最下边不用的端口删除,并对照着将“名称”和“数据类型”进行设置,其它保持默认即可。
⚠️注 意:由于 mbed-os 部分代码使用 C++编写,“语言”栏一定要设置为“C++”,否则在 simulink 中编译时会报莫名其妙的错误。
图 5.6 “S-Function Builder”窗口参数设置
接下来我们往 “编辑器”中添加代码,完整代码如下所示,看起来感觉有点复杂,其实我们实际使用中不用关注那么多,根据实际需要操作其中部分内容即可。
⚠️注 意:在 S-Function Builder 编辑代码时,实际可改动的位置为/* xxx_BEGIN */ /* xxx_END */中间部分,读者朋友如果更改其它地方,可能会出现编辑不了的情况。
/* Includes_BEGIN */#include <math.h>
#ifndef MATLAB_MEX_FILE
#include <mbed.h>
I2C i2c1(PB_11, PB_10);
char BCD_decode_tab[ 0x10 ] = { 0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F, 0X77, 0X7C, 0X58, 0X5E, 0X79, 0X71 }; // unsigned char cnt = 0; // 定义计数变量char *seg_ptr; // 定义指针变量
#endif/* Includes_END */
/* Externs_BEGIN *//* extern double func(double a); *//* Externs_END */
void CH422G_Start_wrapper(real_T *xD){ /* Start_BEGIN */ /* * 此处显示自定义开始代码。 */ /* Start_END */}
void CH422G_Outputs_wrapper(const uint8_T *NMU,const real_T *xD){ /* Output_BEGIN */ #ifndef MATLAB_MEX_FILE seg_ptr = BCD_decode_tab + NMU[0]; i2c1.write(0x60,seg_ptr,1); #endif /* 此示例将输出设置为等于输入 y0[0] = u0[0]; 对于复信号,使用: y0[0].re = u0[0].re; y0[0].im = u0[0].im; y1[0].re = u1[0].re; y1[0].im = u1[0].im; */ /* Output_END */}
void CH422G_Update_wrapper(const uint8_T *NMU,real_T *xD){ /* Update_BEGIN */ if(xD[0] !=1 ) { #ifndef MATLAB_MEX_FILE char cmd[2];
/* 输出引脚 OC3~OC0 开漏输出使能 */ cmd[0] = 0x01; i2c1.write(0x48,cmd,1); // 往地址0x48设置0x01值
/* 使OC3~OC0引脚输出低电平*/ cmd[0] = 0x00; i2c1.write(0x44,cmd,1);
cmd[0] = 0x00; i2c1.write(0x46,cmd,1); #endif }
/* Update_END */}
void CH422G_Terminate_wrapper(real_T *xD){ /* Terminate_BEGIN */ /* * 此处显示自定义终止代码。 */ /* Terminate_END */}
第一部分:头文件包含,与 C /C++ 语言中使用方法类型,本次实验因为用到 mbed-os 框架的接口函数,所以我们需要添加 mbed.h 头文件,其余部分跟使用 C /C++ 语言方式 操作方式 差不多。注意添加的代码需要使用#ifndef MATLAB_MEX_FILE #endif 将添加内容包含起来。
/* Includes_BEGIN */#include <math.h>
#ifndef MATLAB_MEX_FILE
#include <mbed.h>
I2C i2c1(PB_11, PB_10);
char BCD_decode_tab[ 0x10 ] = { 0X3F, 0X06, 0X5B, 0X4F, 0X66, 0X6D, 0X7D, 0X07, 0X7F, 0X6F, 0X77, 0X7C, 0X58, 0X5E, 0X79, 0X71 }; // unsigned char cnt = 0; // 定义计数变量char *seg_ptr; // 定义指针变量
#endif/* Includes_END */
第二部分:初始化,这部分用于初始化变量或驱动芯片,代码如下所示,同样需要将内容放置#ifndef MATLAB_MEX_FILE #endif 中,示例代码中初始化 CH422 芯片的内部寄存器设置。
void CH422G_Update_wrapper(const uint8_T *NMU,real_T *xD){ /* Update_BEGIN */ if(xD[0] !=1 ) { #ifndef MATLAB_MEX_FILE char cmd[2];
/* 输出引脚 OC3~OC0 开漏输出使能 */ cmd[0] = 0x01; i2c1.write(0x48,cmd,1); // 往地址0x48设置0x01值
/* 使OC3~OC0引脚输出低电平*/ cmd[0] = 0x00; i2c1.write(0x44,cmd,1);
cmd[0] = 0x00; i2c1.write(0x46,cmd,1); #endif }
/* Update_END */}
第三部分:实际运行交互内容,这里面用于实际要控制或操作的内容,示例代码中接收“NMU”数据,然后通过 I2C 接口写入芯片驱动数码管显示对应数字。
void CH422G_Outputs_wrapper(const uint8_T *NMU,const real_T *xD){ /* Output_BEGIN */ #ifndef MATLAB_MEX_FILE seg_ptr = BCD_decode_tab + NMU[0]; i2c1.write(0x60,seg_ptr,1); #endif /* 此示例将输出设置为等于输入 /* Output_END */}
以上内容设置好后,需要对代码进行进行编译包装,在编译器设置中只需勾选“生成 TLC 包装”即可,其它根据实际需求选择,然后点击编译,右侧编译日志会显示是否编译成功。
图 5.5 “S-Function Builder”编译设置及编译成功效果
回到 simulink 窗口中,我们可以看到“S-Function Builder”名字发生了改变,并且有一个输入端口“NMU”,如图 5.6 所示,往模型中 添加一个 "Constant"变量就可以控制显示数码管数字,其它 simulink 设置参考之前文章,这里就不再赘述。
图 5.6 设置并编译好的自定义模型
✏️总结
本节实验中我们通过添加一个自定义的“S-Function Builder”模型,然后在其中添加 mbed-os 接口函数从而实现驱动 I2C 数码管驱动芯片显示对应数字,这对于使用 simulink 提供了一定的灵活度,并且后期的外部 开源驱动模块都可以通过该方式引入到 simulink 中来,还是非常方便的。 |
|