人生如逆旅,我亦是行人。
今天分享一个在 MATLAB
上生成C算法文件,并将其移植到 keil5
上,运行至 STM32
单片机,一个很有用的方法。
MATLAB
的软件(注意:matlab
安装路径不可以有空格的问题)Keil IDE
开发环境STM32CubeMX
STM32H750VBT6
开发板需要移植的头文件路径:F:\MATLAB\extern\include
(在我们安装的 MATLAB 软件的文件夹的路径下)
filter.m
(滤波算法)脚本文件
%% 滑动平均滤波
function y=averaging_filter(x)
persistent buffer;
if isempty(buffer)
buffer = zeros(16,1); %每次平均采样16个采样值,每挪动一次,求16次采样值
end
y=zeros(size(x),class(x));
for i = 1:numel(x)
buffer(2:end)=buffer(1:end-1);
buffer(1) = x(i);
y(i) = sum(buffer)/numel(buffer);
end
type averaging_filter
%%%%%%%%%%%%% 第1步:噪声波形 %%%%%%%%%%%%%%%
v = 0:0.00614:2*pi;
x = sin(v) + 0.3*rand(1,numel(v));
plot(x,'red');
fid=fopen('F:\MATLAB\bin\data.c','wt'); %写入文件路径
for i=1:1:1024 %MATLAB的下标是从1开始的
fprintf(fid,'%f,\n',x(i));
end
%%%%%%%%%%%% 第2步:生成 mex 函数,先在 matlab 上测试下 %%%%%
% codegen :命令会检查 matlab 函数是否适用于代码生成,并生成 MEX 函数
codegen averaging_filter -args {x} %将滑动平均滤波的脚本文件专门生成一个mex函数供我们使用
%%%%%%%%%%% 第3步:在 MATLAB 中运行 MEX 函数
y = averaging_filter_mex(x);
hold on;
plot(y,'blue');
% grid on %限制作用,在幕布中加了一些网格线
% axis square %限制作用
%%%%%%%%%% 第4步:生成C代码 %%%%%%%%%%%%%
codegen -config coder.config('lib') averaging_filter -args {x}
其中红色表示的原始的噪声波形,会带有很多的毛刺,数据干扰较大;而蓝色表示的则是经过滑动平均滤波之后的波形,变得则相对平滑了一些。
可以看出其滤波的效果还是十分不错的。
上述展示的是利用 MATLAB
编写滤波算法,并显示出它的效果,接下来我们学习如何将它移植到 Keil
中,并运行到我们的单片机上。
STM32CubeMX
新建一个工程,可以参考:STM32H750VBT6的DSP使用的学习——基于CubeMXF:\MATLAB\extern\include
,将里面所有的内容复制到我们新建的 Include
文件夹中F:\MATLAB\bin\
codegen\lib\averaging_filter
,将其全部复制到我们新建的 MATLAB
文件夹中:STM32H7
的最小系统板:STM32H750VBT6
,对串口进行重定向:#include "stdarg.h"
#define CONSOLEBUF_SIZE 256
static char Uart_buf[CONSOLEBUF_SIZE];
void PrintfDebugUart(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
int length = vsnprintf(Uart_buf, sizeof(Uart_buf) - 1, fmt, args);
va_end(args);
HAL_UART_Transmit(&huart1, (uint8_t *)&Uart_buf, length, 0xffff);
}
注:这样就可以直接调用 PrintfDebugUart
进行串口打印。
main.c
文件中添加滤波函数的头文件:#include "averaging_filter.h"
#include "averaging_filter_initialize.h"
输入数组中的元素就是我们之前生成的 data.c
中的数据;输出数组直接全部初始化为零即可。
接下来在 main 函数中添加:
/* USER CODE BEGIN 2 */
averaging_filter_initialize(); //滤波函数初始化
averaging_filter(inputdata,outputdata); //对原始噪声函数进行滤波
for(int i=0; i<1024; i++)
{
PrintfDebugUart("%f\r\n",inputdata[i]);
}
for(int i=0; i<1024; i++)
{
PrintfDebugUart("%f\r\n",outputdata[i]);
}
/* USER CODE END 2 */
编译,烧录:
烧录方式是直接的固件的烧录,其他烧录都可以:
利用串口打印结果,并接收打印数据:
最后利用 excel
表格对数据进行整理,绘制波形图:
注: 蓝色表示的是原始的数据;红色的表示经过滑动平均滤波算法之后的数据,相对变得平滑了许多。
以上就是本篇博文的分享内容,如果对你有帮助的话,麻烦帮忙点个小赞,谢谢!!!