LabWindows CVI与Matlab混合编程的一种实现方法_fmt函数 labwindows

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

函数末尾的hMatlab为全局的Matlab句柄,需提前定义(尤其当你想在其他地方也调用Matlab时)

不仅是该函数,大多数函数均会返回一个状态变量,故一般使用上面这种形式进行编程,以对软件的运行进行更好的控制,当加载错误时,能有效报错,防止软件无故崩溃

2.改变窗口大小:MinMaxMatlab

该函数在maltbutil.c文件中被定义,在最底层的MLApp之上进行进一步封装得到,0表示最小化窗口,1表示最大化窗口。

int MinMaxMatlab(CAObjHandle hMatlab, int minmaxFlag)    
MinMaxMatlab(hMatlab,0);

3.退出Matlab脚本:MLApp_DIMLAppQuit

该函数在MLApp.c文件中被定义,也可以对其进行进一步的封装。

HRESULT CVIFUNC MLApp_DIMLAppQuit (CAObjHandle objectHandle,
                                   ERRORINFO *errorInfo);
stat = MLApp_DIMLAppQuit (*hMatlab, NULL);    

4.运行Matlab命令:RunMatlabCommand

该函数在maltbutil.c文件中被定义,仅可执行Matlab内部函数相关的命令,无法执行自定义函数命令,否则会报“undefined function or method”错误。

int RunMatlabCommand(CAObjHandle hMatlab, char *command)       
result = RunMatlabCommand(hMatlab,"mMatrix=inv(cMatrix);");  
if (result != SUCCESS)
{
    MessagePopup ("ERROR", "Error in sending command to MATLAB");
    return 0;
}

涉及的变量mMatrix与cMatrix无需在CVI中进行声明。

5.发送/接收字符串:SendString/GetString

该函数在maltbutil.c文件中被定义,由于Matlab不支持BSTRs,故发送接收过程中需要使用Fmt函数进行字符串与双精度浮点数的转换。

Fmt函数示例如下:

Fmt(CVIString,"%s<Hello MATLAB");
Fmt(command,"%s<%s=transpose(%s)",matStringName,matStringName);  
Fmt(command,"%s<%s=char(%s)",matStringName,matStringName); 

发送接收函数如下所示

int SendString(CAObjHandle hMatlab, char *matStringName, char *CVIString)
int GetString(CAObjHandle hMatlab, char *matStringName, char **cString) 

result = SendString(hMatlab, "matStr", CVIString);
result = GetString(hMatlab,"matStr",&cStr); 

demo给出的例子是,将“Hello MATLAB”字符串转换为双精度浮点数,变量名为CVIString,传输到Matlab中,在Matlab中的名称为matStr,而后从Matlab中获得这个字符串,变量名为cStr。

在CVI程序中,matStr无需声明,然而CVIString与cStr是需要声明的,形式是一维数组。

6.发送/接收矩阵

同5,demo矩阵的传输演示是将一个2x2的矩阵传入Matlab,进行转置运算后接收回来。

int SendMatrix(CAObjHandle hMatlab, char *matlabName, double *matrixReal, 
                    double *matrixImag, size_t dim1, size_t dim2)
int GetMatrix(CAObjHandle hMatlab, char *matlabName, double **matrixReal, 
                    double **matrixImag, size_t *dim1, size_t *dim2)

result = SendMatrix(hMatlab,"cMatrix",(double*)matrix_r,(double*)matrix_i,2,2); 
result = GetMatrix(hMatlab,"mMatrix",&matrixReal,&matrixImag,&dim1,&dim2);

传输变量包括Matlab句柄,在Matlab中的名称,矩阵实部数值(也是矩阵),矩阵虚部数值(也是矩阵),行数,列数。其中没有虚部或者实部时可以用NULL表示。

同4,mMatrix与cMatrix无需在CVI中进行声明。但发送矩阵的实部数值matrix_r与虚部数值matrix_i需要在CVI中声明,形式是二维数组。接收矩阵的实部数值matrixReal和虚部数值matrixImag为初始化为NULL的指针,也需要提前声明,行数列数也需要提前确定。

7.运行M文件脚本:RunMatlabScript

该函数在matlabutil中定义。

int RunMatlabScript(CAObjHandle hMatlab, char *mFilePath)    
result = RunMatlabScript(hMatlab,"G:\\sig\_gen\\demo\_0728\\create\_chaffsig.m");

在设定路径时,Windows下的分隔符需使用\以强制转义,否则会使得路径解析出错,另外由于函数中对路径长度以及文件名长度最大值仅设为256,故运M文件脚本不可设置过深,以防止无法解析。

另外还可利用FileSelectPopupEx等系统相关的函数,实现选择m文件运行的操作,这里不再赘述。

调用自定义函数

若要调用自定义函数,建议采用以下两种方式:

1.不足5行的函数,直接使用RunMatlabCommand,拆分为多个语句进行代替。

2.程序较长,但不存在额外调用自定义函数的情况(额外调用自定义函数指:例如本打算调用自定义函数A,A函数中又使用了自定义函数B),则在Matlab中充分测试A函数后,去掉首行的声明(即function [输出变量] = 函数名(输入变量))以及末尾的”end”,将所需要的输入变量提前构成数组,直接传入Matlab,再在Matlab中还原为各参数变量。如下所示:

在CVI中将变量构成数组

m_out_data[0] = fc;
m_out_data[1] = fs;                                                     
m_out_data[2] = (double)m;                                              
m_out_data[3] = TotalTime*(1e-6);

在M文件头部还原

f0 = m_out_data(1);     
fs = m_out_data(2);     
m = m_out_data(3);     
T = m_out_data(4);     

完成运算后再将所需要的数据导出,由于一般调用Matlab的原因是C语言计算信号的各种变换较慢,所以所需数据一般也为行向量,可以用1xN的矩阵表示。

小结

调用Matlab时,需要在CVI代码中首先加载Matlab,其次具有一定的技巧地使用自定义函数,最后调用完成后需关闭Matlab避免拖累系统。

三、测试结果

在同一计算机上进行相同计算任务,

按上文的思路,CVI使用原方法完成50*245000个循环,耗时100s左右。

Matlab环境下运行(也是两重循环),耗时60s

Matlab改为单循环时,耗时0.0648s

CVI与Matlab进行混合编程后,耗时不足2s。

由上可知,混合编程成功地优化了功能,体现了混合编程的优越性。


待改进之处

后续打算对另外两种调用方法,以及通过修改Matlab注册码使用ActiveX服务三个方面进行研究,并尽快完善本文。


参考资料

刘君华等,《基于LabWindows/CVI的虚拟仪器设计》,电子工业出版社

收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。
img
img

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

1715886367094)]

如果你需要这些资料,可以戳这里获取

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人

都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 22
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值