记录一下学习使用MATLAB设计的算法转换为可以在stm32上运行的C语言代码,并在keil中运行的学习过程
1.必要性
MATLAB提供了大量的数学函数库,支持矩阵运算、线性代数、统计分析、优化、信号处理、图像处理等,使得开发者能够轻松实现复杂的数学算法,而无需从零开始编写基础数学代码。在MATLAB中,算法的实现可以快速验证,通过执行代码立即获得反馈,极大提高了原型开发的效率。MATLAB的交互式环境使得开发者可以实时修改代码并调试,节省了大量的开发时间。
此外,MATLAB还可以生成C/C++代码,通过MATLAB Coder Toolbox将算法转换为嵌入式C代码,以直接部署到嵌入式硬件上,或者通过Simulink和Embedded Coder生成适用于嵌入式平台的高效代码。通过与Keil、Xilinx等开发工具的集成,可以将MATLAB中设计的算法直接应用于硬件,避免手动编写大量底层C代码的工作。
本文以使用MATLAB设计一个三阶巴特沃斯带通滤波器,并将该滤波器转换为C代码应用于HLEC-6448控制器为例,介绍使用MATLAB Coder Toolbox将Matlab算法转C代码的联合开发流程。
2.PC配置与必要环境
3.使用MATLAB设计巴特沃斯带通滤波器
3.1Matlab路径设置
新建“demo_file”作为文件保存路径 → 打开MATLAB → ①打开新文件夹 → ②找到“demo_file”路径 → ③确定
注意:文件名中不能有中文!不能有空格!如果后续脚本运行出现问题优先从此处排查!
将“demo_file”添加到MATLAB文件运行路径
3.2创建Matlab脚本文件
在编辑器中创建“butter_demo”和“butter_c”两个脚本文件,并保存至“demo_file”
3.3设计三阶巴特沃斯带通滤波器
在中“butter_demo”设计一个采样频率1000Hz,中心频率100Hz,带宽20Hz(即通带范围90~110Hz)的三阶巴特沃斯带通滤波器
3.4创建滤波器应用示例
创建包含50Hz,100Hz和150Hz三种不同频率成分的信号,使用所设计的三阶巴特沃斯带通滤波器进行滤波,观察滤波前和滤波后的波形
运行
绘制出的原始信号(上)和滤波后的信号(下)
3.5频谱分析
绘制傅里叶变换频谱图以分析滤波前和滤波后的信号中的频率成分,以此检验滤波器的滤波效果
运行后得到如下结果,原始信号中50Hz和150Hz两种频率成分的信号被基本滤除
4.使用MATLAB coder toolbox生成C代码
MATLAB coder toolbox是MATLAB官方提供的工具箱,它提供了自动化的代码生成流程,支持将MATLAB脚本、函数、Simulink模型等转换为C/C++代码,同时保留算法的精度和性能。
注意!在进行转换前,需要将所设计的脚本/函数/Simulink模型封装为输入/输出参数类型确定的函数。
4.1MATLAB算法封装至函数
以将上文设计的“butter_demo”封装到“butter_c”为例,函数的输入为待滤波的信号x,输出为滤波后的信号y,函数内部只需要保留和滤波操作相关的代码即可。
注意脚本中函数的命名②要和文件名①“butter_c”一致!
4.2打开MATLAB coder toolbox
请确保已正确安装MATLAB coder toolbox并打开
打开界面如下,①输入封装好的函数名称“butter_c”,并进行②下一步
4.3定义输入类型
在①输入执行语句,点击②将自动判断输入数据类型,可以看到已经识别了x的类型为double,尺寸为1×1000,③继续
4.4问题检查
MATLAB中绝大部分功能都是支持生成C代码的,但也有小部分是不支持的,这一步将检查所要转换的函数是否调用了不支持转换的部分
①开始检查,如果出现②显示的No issues detected则代表没有问题,继续后续步骤③
4.5代码生成
直接生成即可
5.C代码的使用
5.1所需文件
将MATLAB coder toolbox生成的C代码投入实际使用需要用到两部分的文件,第一部分来自我们创建的文件夹“demo_file”,在“4. step5”中生成的代码保存在路径“\demo_file\codegen\lib”下,将该路径下的所有文件复制到“matlab_butter”
第二部分来自MATLAB安装目录“MATLAB\R2021b\extern\include”,将该路径下的所有文件复制到文件夹“matlab_lib”
5.2将C代码加入MDK工程
然后将打包好的文件夹拖入MDK工程中,这里以HL_6448Controller_V0.4工程文件为例
并在keil中添加组“matlab_butter”和组“matlab_lib”。将“matlab_lib”中的所有“.h”添加到组“matlab_butter”中(这个文件夹中的头文件不用每次使用MATLAB转C代码都重新添加),将“matlab_butter”中的所有“.C”文件添加到组“matlab_butter”中(这个文件夹中的C文件在每次使用MATLAB coder toolbox后都需要从“\demo_file\codegen\lib”重新复制过来)
添加完成的状态
注意还要在keil的C/C++路径配置中添加“matlab_lib”和“matlab_butter”文件夹的路径
5.3添加头文件并编译
在主函数中包含"butter_c_initialize.h"和"butter_c.h"两个头文件
然后进行编译,不报错即可使用"butter_c.c"中的函数
5.4特别注意!
HLEC6448的RAM资源特别有限,在使用一些MATLAB生成的复杂算法时,虽然编译不报错,但一运行就触发Error_Handler。这是由于生成的C代码所定义的局部/零时变量太多,导致堆栈溢出!(如小波包变换等,要尤其尤其注意!)
因此,使用MATLAB算法生成的C代码时,要分配足够的堆栈空间!并特别关注debug界面sp指针的数值!避免堆栈溢出导致的错误!