概述
最近在做信号处理相关的功能,首先在matlab上做仿真,之后使用c/c++实现,然后尝试使用Matlab Coder做转换功能。
参考:
基于MATLAB Coder将matlab代码转换成C代码
官网视频讲解
matlab调用c/c++代码
特此感谢!
一、概念及开发流程
MATLAB Coder可以从MATLAB代码生成独立的、可读性强、可移植的C/C++代码。
通俗地说,就是将写好的matlab功能模块代码转换为c/c++代码,然后我们在此基础上进行改进。
本文开发环境:Win10 64、VS2015、Matlab R2016A。
开发流程:使用MATLAB Coder产生C代码的3个步骤:
- 开发实现特定算法功能的MATLAB代码及其测试文件
- 检查MATLAB代码的兼容性,确保MATLAB代码中的语句都能被转换成C代码(有些matlab代码语句并不能生成c/c++代码,例如matlab中的imread、imshow、plot等函数)
- 利用MATLAB Coder生成c/c++代码,并在VS2015中验证。
二、实践测试
参考的文章中给出了功能模块代码与测试代码分离的思想,因此本文借鉴这种思想,进行实践测试。
当然功能模块a.m文件可以作为b.m文件的调用,在编译时两个都要选中进行编译(可以理解为依赖),不过本文暂时不涉及该功能的实现。
2.1 Matlab功能模块代码及其测试代码
myfft.m
对输入的数据去除直流分量并进行FFT。其中,%#codegen用来防止出现警告错误
%#codegen
function B = myfft(v1,N)
v1=v1 - mean(v1);
B = fft(v1,N);
test_main.m
产生数据集并测试
f=100; %信号频率Hz
Fs=1000; %采样频率
N=256; %采样点数
t=(0:N-1)/Fs; %采样时间s
S=1000*sin(2*pi*f*t)+20*randn(size(t)); %信号采样值
%B = meanVal(S,N)
B = myfft(S,N);
f =((-N/2):(N/2-1))*Fs/N;
plot(abs(B))
title('Amplitude Spectrum of S')
xlabel('f (Hz)')
ylabel('|P1(f)|')
matlab输出:
f = (N-1)Fs/N = 261000/256=100Hz。
2.2 利用MATLAB Coder生成c/c++代码
-
在命令窗口,输入
mex -setup
,选中一个存在的编译器,笔者这里自带了一个c编译器,读者也可以切换为c++编译器(输入mex -setup C++
)。
-
在命令窗口输入coder(图形界面),回车,弹出MATLAB Coder Project对话框(或在matlab软件的界面中点击
MatLab Coder
图标)。
(1)在Select模块中选择我们想要编译的功能模块myfft.m
(2)点击Next
上图红色方框处也可以继续添加功能模块的.m文件。
(3)点击Next,进入Define Input Types界面。输入test_main.m测试文件,点击Autodefine Input Types按钮,从而使得matlab能自动检测出功能模块函数的接口变量的维度和类型。
(4)点击Next,点击check for issues按钮。
(5)点击Next,点击Generate按钮,生成了C/C++代码。
生成成功后如下图,可以在lib文件下查看到该文件。
2.3 VS2015验证
利用VS2015在lib同级目录下的文件夹libvs中建立工程myfftprj,将所有的.c .h导入工程。
由于物理路径的关系,修改当前工程头文件路径即可。
我们发现工程中输入实例输入为空,因此根据test_main.m文件需要进行修改。
/*
* Arguments : double result[256]
* Return Type : void
*/
static void argInit_1x256_real_T(double result[256])
{
int idx1;
const double pi = 3.141592653589793;
const double Fs = 1000; //采样频率
/* Loop over the array to initialize each element. */
for (idx1 = 0; idx1 < 256; idx1++) {
/* Set the value of the array element.
Change this value to the value that the application requires. */
double t = idx1 / Fs;
result[idx1] = 100 * sin(2 * pi * 100 * t);;//argInit_real_T()
}
}
同时输入参数N也要进行适当修正,添加<stdio.h>
和getchar()等辅助打印函数。
这里需要注意的是,生成的c++代码输出变量是根据实际输出决定的一个结构体类型变量,我们要在理解该结构体的基础上进行调试及打印。
比如当输出复数时,类型为emxArray_creal_T
,当输出实数时,类型为emxArray_real_T
。
代码:
/* Include Files */
#include "../rt_nonfinite.h"
#include "../myfft.h"
#include "main.h"
#include "../myfft_terminate.h"
#include "../myfft_emxAPI.h"
#include "../myfft_initialize.h"
#include <stdio.h>
/* Function Definitions */
void printArr(emxArray_creal_T *arr, int size)
{
for (int i = 0; i < size; i++)
{
printf("%4d %8.4f %8.4f n", i, (arr->data[i]).re, (arr->data[i]).im);
//printf("%4d %8.4f n", i, arr->data[i]);
}
}
/* Function Declarations */
static void argInit_1x256_real_T(double result[256]);
static double argInit_real_T(void);
static void main_myfft(void);
/* Function Definitions */
/*
* Arguments : double result[256]
* Return Type : void
*/
static void argInit_1x256_real_T(double result[256])
{
int idx1;
const double pi = 3.141592653589793;
const double Fs = 1000; //采样频率
/* Loop over the array to initialize each element. */
for (idx1 = 0; idx1 < 256; idx1++) {
/* Set the value of the array element.
Change this value to the value that the application requires. */
double t = idx1 / Fs;
result[idx1] = 100 * sin(2 * pi * 100 * t);;//argInit_real_T()
}
}
/*
* Arguments : void
* Return Type : double
*/
static double argInit_real_T(void)
{
return 0.0;
}
/*
* Arguments : void
* Return Type : void
*/
static void main_myfft(void)
{
emxArray_creal_T *B;
double dv0[256];
emxInitArray_creal_T(&B, 2);
/* Initialize function 'myfft' input arguments. */
/* Initialize function input argument 'v1'. */
/* Call the entry-point 'myfft'. */
argInit_1x256_real_T(dv0);
myfft(dv0,256 , B); //argInit_real_T()
printArr(B, 256);
emxDestroyArray_creal_T(B);
}
/*
* Arguments : int argc
* const char * const argv[]
* Return Type : int
*/
int main(int argc, const char * const argv[])
{
(void)argc;
(void)argv;
/* Initialize the application.
You do not need to do this more than one time. */
myfft_initialize();
/* Invoke the entry-point functions.
You can call entry-point functions multiple times. */
main_myfft();
/* Terminate the application.
You do not need to do this more than one time. */
myfft_terminate();
getchar();
return 0;
}
输出:
三、Matlab小技巧
- 不以科学计数法显示(参考文章)
format short g
- c/c++生成.m文件的demo (参考 matlab调用c/c++代码)
#include "mex.h"
//使用MEX必须包含的头文件
void mexFunction(int nlhs, mxArray *plhs[],
int nrhs, const mxArray *prhs[]){
mexPrintf("hello worldn");
}
mex hello.c
hello %脚本运行
最后
以上就是秀丽大树为你收集整理的基于Matlab Coder将matlab代码转换成c代码的全部内容,希望文章能够帮你解决基于Matlab Coder将matlab代码转换成c代码所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复