• [MATLAB学习]:Matlab生成滑动平均滤波算法文件并移植到STM32单片机上运行——基于CubeMX


    前言

    人生如逆旅,我亦是行人。


    今天分享一个在 MATLAB 上生成C算法文件,并将其移植到 keil5上,运行至 STM32 单片机,一个很有用的方法。


    • 准备工作:

      • 已安装 MATLAB 的软件(注意:matlab 安装路径不可以有空格的问题)
      • Keil IDE 开发环境
      • STM32CubeMX
      • STM32H750VBT6 开发板
    • 需要移植的头文件路径:F:\MATLAB\extern\include(在我们安装的 MATLAB 软件的文件夹的路径下)
      在这里插入图片描述


    一、MATLAB 的生成算法脚本

    1、新建一个 filter.m (滤波算法)脚本文件

    在这里插入图片描述
    在这里插入图片描述

    • 编写 averaging_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
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 验证 .m 脚本文件的算法函数是否正常:

    在这里插入图片描述

    type averaging_filter
    
    • 1

    2、新建一个生成波形且可调用滤波函数的脚本文件

    在这里插入图片描述

    • 在编辑器中编写 wave.m 代码:

    在这里插入图片描述

    %%%%%%%%%%%%%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}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 编写完成代码后,点击运行:

    在这里插入图片描述
    在这里插入图片描述

    • data.c 中存储着噪声波形的数据

    在这里插入图片描述

    • 运行后,还会产生如下的波形图像:

      其中红色表示的原始的噪声波形,会带有很多的毛刺,数据干扰较大;而蓝色表示的则是经过滑动平均滤波之后的波形,变得则相对平滑了一些。

      可以看出其滤波的效果还是十分不错的。

    在这里插入图片描述

    上述展示的是利用 MATLAB 编写滤波算法,并显示出它的效果,接下来我们学习如何将它移植到 Keil 中,并运行到我们的单片机上。


    二、新建一个普通的 Keil 工程

    • 利用 STM32CubeMX 新建一个工程,可以参考:STM32H750VBT6的DSP使用的学习——基于CubeMX
    • 新建工程完成之后,找到我们的工程文件夹,再新建两个文件夹:
      在这里插入图片描述
    • 找到需要移植的头文件路径:F:\MATLAB\extern\include,将里面所有的内容复制到我们新建的 Include 文件夹中

    在这里插入图片描述

    • 同样,找到我们生成的滤波算法文件:F:\MATLAB\bin\ codegen\lib\averaging_filter,将其全部复制到我们新建的 MATLAB 文件夹中:

    在这里插入图片描述


    三、进行 KEIL 工程的配置

    在这里插入图片描述

    • 接下来,点击仙女棒图标,添加两个文件夹路径:

    在这里插入图片描述

    • 上述就差不多完成了整个移植的过程,接下来就是编写代码,调用我们生成的算法函数。

    四、编写代码

    • 因为我所使用的是 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);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    注:这样就可以直接调用 PrintfDebugUart 进行串口打印。

    • main.c 文件中添加滤波函数的头文件:
    #include "averaging_filter.h"
    #include "averaging_filter_initialize.h"
    
    • 1
    • 2
    • 定义两个数组:

    在这里插入图片描述
    在这里插入图片描述

    • 输入数组中的元素就是我们之前生成的 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 */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 编译,烧录:
      在这里插入图片描述

    • 烧录方式是直接的固件的烧录,其他烧录都可以:
      在这里插入图片描述


    五、实验结果

    • 利用串口打印结果,并接收打印数据:
      在这里插入图片描述

    • 最后利用 excel 表格对数据进行整理,绘制波形图:
      在这里插入图片描述

    注: 蓝色表示的是原始的数据;红色的表示经过滑动平均滤波算法之后的数据,相对变得平滑了许多。


    以上就是本篇博文的分享内容,如果对你有帮助的话,麻烦帮忙点个小赞,谢谢!!!

  • 相关阅读:
    【Hive】Hive元数据信息表详解
    云原生周报 | Kubernetes 1.25 重要更新;2022 国际开源节即将开启
    图像处理与计算机视觉--第五章-图像分割-自适应阈值分割
    python神经网络实现手写数字识别实验
    swig教程-指令文件《一》
    海外代理IP与VPN有何区别?哪个更好?
    使用lvs+nginx实现负载均衡
    云计算-虚拟化
    Requests 与接口请求构造
    OpenFOAM:并行区域划分理解(Domain Decomposition)
  • 原文地址:https://blog.csdn.net/WandZ123/article/details/125824206