Matlab代码导入STM32F103流程

软件准备

  • 安装MATLAB2019a,64位。
  • 下载安装JRE。STM32CubeMX 软件是基于 JAVA 环境运行的,所以需要安装 JRE (Java Runtime Environment)才能使用, 建议到官网下载最新版本JRE。

https://www.java.com/en/download/manual.jsp

  • 安装STM32-MAT/TARGET,我下载了STM32_MAT_TARGET_V4.4.2。(后来验证不要用这个版本,因为和其他软件版本不匹配,用5.6.0,下文有链接,否则会报错)

https://www.stmcu.com.cn/Designresource/detail/software/709508

STM32-MAT/TARGET 主要特性:

  • 用于STM32微控制器的Simulink应用程序配置
  • STM32配置通过STM32CubeMX完成
  • STM32的自动“ C”代码生成基于STM32Cube HAL库
  • 使用USART RTioStream的处理器循环(PIL, Processor In the Loop)
  • 报告:代码生成, 代码执行分析
  • STM32外设Simulink库模型

打开Matlab, 输入pathtool, 点击添加并包含子文件夹按钮, 找到D:\MATLAB\STM32-MAT\STM32路径加进去。
在这里插入图片描述

  • 安装STM32CubeMX,我下载了stm32cubemx-win_v6-5-0。

https://www.st.com/en/development-tools/stm32cubemx.html#overview

准备一个ST-LINK下载器,插在 JTAG/SWD 调试下载口。一般商家会送一个。我用的是ST-Link V2版本。
在这里插入图片描述

ST-Link是用于STM8和STM32微控制器的在线调试器和编程器,也是大家口中的下载器。
ST-Link具有SWIM、JTAG / SWD等通信接口,用于与STM8或STM32微控制器进行通信(各版本有差异)。
三种接口说明:
· SWIM:Single Wire Interface Module,单线接口模块。
· JTAG:Joint Test Action Group,联合测试工作组,是一种国际标准测试协议。
· SWD:Serial Wire Debugging,串行调试接口。
在这里插入图片描述

STM32CubeMX简介

在这里插入图片描述

STM32CubeMX是一个配置STM32代码的工具,它把很多东西封装的比较好,硬件抽象层、中间层、示例代码等,是 ST 意法半导体近几年来大力推荐的STM32 芯片图形化配置工具,目的就是为了方便开发者, 允许用户使用图形化向导生成C 初始化代码,可以大大减轻开发工作,时间和费用,提高开发效率。

32的三种开发模式
1.stm32能基于寄存器开发,就是和51单片机一样,直接对寄存器进行编程。基于寄存器编写的代码简练、执行效率高。但由于 STM32 微控制器的片上外设和寄存器数量太多,这种编程方式移植性差,寄存器名称记起来也很痛苦。
2.基于st官方的固件库进行开发。现在大部分stm32教程教的都是这种库函数开发,如正点原子,野火等。他相比寄存器开发更加简单,我们不需要记住每个寄存器的地址和名称,只要会调用ST官方封装好的库函数进行编程就可以了。
3.基于STM32cubemx进行开发,就是我们今天要给大家介绍的内容。STM32cubemx使用的是st官方新推出的HAL库,然后我们可以通过软件内设计好的图形化界面进行配置,软件自动生成生成配置代码,然后我们再在IDE上面codding。

STM32CubeMX特性

1.直观的选择 STM32 微控制器(MCU)和微处理器(MPU)。

2.丰富易用的图形化界面: -自动解决配置冲突 -具有参数约束动态验证的外设和中间件功能模式 -时钟树与配置的动态验证 -功耗预测

3.生成初始化代码工程,包含:EWARM、 MDK-ARM、 TureSTUDIO、 SW4STM32等。

4.针对部分MPU生成Linux设备树。

5.可独立运行在Windows、Linux和macOS上使用,或作为 Eclipse 插件使用。

配置STM32CUBEMX

打开STM32CUBEMX
在这里插入图片描述
在线安装固件库(HAL库),也可以选择离线安装。
在这里插入图片描述
在这里插入图片描述找到STM32F103ZET6。点击右上角的生成代码。注意先生成代码,再新建simulink,否则被覆盖了。

后续配置过程,详见:https://blog.csdn.net/woshigaowei5146/article/details/124815449?spm=1001.2014.3001.5502

配置SIMULINK

新建一个model文件(.slx)。注意:.ioc文件和.slx文件应在同一文件夹下。

点设置按钮。
在这里插入图片描述

固定步长,即“Fixed-step”,然后修改步长为1/10000,即0.1ms,也可以根据实际情况修改,默认为auto可能会导致程序运行时无法显示出效果。
在这里插入图片描述

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

SIMULINK对STM32F103进行点灯试验

注意:.ioc文件和.slx文件应在同一文件夹下。其他外设的应用可自行百度,资料还挺多。

在库中找到STM32 Config.

在这里插入图片描述

选择之前生成的ioc文件。在这里插入图片描述
拖入GPIO_Write.
在这里插入图片描述
在这里插入图片描述
拖入一个方波发生器。注意周期长一点,要不然肉眼看不出来。
在这里插入图片描述
Build成功编译之后。再次打开STM32CUBEMX生成代码,打开MDK。工程文件在MDK-ARM中。打开*.uvprojx。
在这里插入图片描述

模型生成的头文件路径(…\STM32\ParaRobot\ParaCompute\Inc)添加到环境配置.
在这里插入图片描述

注意要打开最新生成的文件。可以通过文件的时间区分。Simulink的代码更新后,Keil会自动更新代码。如下所示。
在这里插入图片描述
在main.c中添加头文件:#include “ParaCompute.h”
在main.c中添加:**.test2_initialize放在while(1)外面, *.step放在while(1)里面。

https://blog.csdn.net/u013288925/article/details/108179302

test2_initialize();
  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
    /* USER CODE END WHILE */
		
		test2_step();
		
    /* USER CODE BEGIN 3 */
  }

#include “test2.h”
#include "demo.h"是为了让main.c文件能够通过demo的头文件访问到demo.c的函数。因为在后面的代码中,main函数中要调用demo_step函数。
test2_initialize()
在while(1)循环之前先调用一下test2_initialize();初始化函数。
test2_step()
simulink的主题函数。

编译过后,就可以通过STLINK下载了。然后重启STM32,可看到LED的闪烁。

一般算法导入到STM32

前面验证了Simulink可以将算法生成.c文件,导入到STM32并可以控制GPIO等外设中。下来验证一般的.m文件算法导入到STM32中。

将原先的.m文件导入SIMULINK中,在库中找到matlab function。

注意:.ioc文件和.slx文件应在同一文件夹下
在这里插入图片描述
双击进行函数的编写,并设置输入输出,我这里用的6入6出。输入输出端口用In和Out模块。
在这里插入图片描述

SIMULINK的配置步骤如前所述。
生成后,在main函数中添加算法生成的函数。主要有两个:void ParaCompute_step(void)和void ParaCompute_initialize(void)。算法模块在void ParaCompute_step(void)中。

刚开始纠结于生成的void ParaCompute_step(void)没有输入输出参数。想了几种办法去添加输入输出参数,但是都没有奏效。后来看了https://zhuanlan.zhihu.com/p/141454827收到启发,可以直接在函数外部设置参数。【还是C语言基础不行(/ω\)】

在头部添加#include “ParaCompute.h”
在main外部定义输出参数:

double out_1=0;
double out_2=0;
double out_3=0;
double out_4=0;
double out_5=0;
double out_6=0;

在void ParaCompute_step(void)函数中找到输入输出参数结构体,在while(1)循环中添加输入参数的值,并调用void ParaCompute_step(void):

ParaCompute_U.Re_Px=2;
ParaCompute_U.Re_Py=2;
ParaCompute_U.Re_Pz=0;
ParaCompute_U.Re_alpha=0;
ParaCompute_U.Re_beta=0;
ParaCompute_U.Re_gamma=0;

ParaCompute_step();

out_1=ParaCompute_Y.M_1;
out_2=ParaCompute_Y.M_2;
out_3=ParaCompute_Y.M_3;
out_4=ParaCompute_Y.M_4;
out_5=ParaCompute_Y.M_5;
out_6=ParaCompute_Y.M_6;

最终,通过输入6个参数,得到6个double类型的输出参数。此方法应该可将所有Matlab的算法移植到STM32中

问题故障解决

  • The call to stm32_make_rtw_hook, during the before_make hook
    generated the …

    可能是版本匹配的问题(https://www.ilovematlab.cn/thread-490019-1-1.html)
    重新下载了mat_target_5.6.0:
    https://download.csdn.net/download/weixin_49000276/82623871

- simulink Error: Errors occurred - aborting
系统时钟不能用Systick,而需要指定其他不用的定时器;或者没有拖入STM32 Config.
参考:https://blog.csdn.net/weixin_43465590/article/details/113615711
在这里插入图片描述

- 未定义函数或变量
在这里插入图片描述
通过试验证明,这个可以不理,只要GPIO能正确配置就行。并不像其他博客所说的版本不匹配,也可能是我正好对了。

- class does not support code generation.

在生成SerialLink类的函数时,遇到问题: class does not support code generation.应该是调用了外部的函数,不支持生成C文件。

将函数放在myWrapper中,但是还是会出现问题:The extrinsic function is not available for standalone code generation.

function [Axis_1, Axis_2, Axis_3, Axis_4, Axis_5] = fcn(Tar_X, Tar_Y, Tar_Z)  
    coder.extrinsic('myWrapper');
    
	Axis_1 = zeros(size(1));
    Axis_2 = zeros(size(1));
    Axis_3 = zeros(size(1));
    Axis_4 = zeros(size(1));
    Axis_5 = zeros(size(1));
    
    [Axis_1,Axis_2,Axis_3,Axis_4,Axis_5] = myWrapper(Tar_X,Tar_Y,Tar_Z);
end

参考:
https://stackoverflow.com/questions/49381021/matlab-issue-with-simulink-does-not-support-code-generation
https://ww2.mathworks.cn/matlabcentral/answers/74770-is-there-any-way-to-disable-code-generation-in-simulink

- Function output cannot be an mxArray in this context. Consider preinitializing the output variable with a known type.

添加:Axis_1 = zeros(size(1));

参考:https://ww2.mathworks.cn/matlabcentral/answers/438184-how-to-solve-a-matlab-function-on-simulink-output-cannot-be-an-mxarray-in-this-context

- The extrinsic function is not available for standalone code generation.
验证了只写myWrapper(Tar_X,Tar_Y,Tar_Z);没有输出可以消除这个错误,但是没有达到目的。

Peter Corke Robotics Toolbox只能生成供simulink调用的模块,无法生成代码。

cg = CodeGenerator(myrobot2);
cg.geneverything();

https://ww2.mathworks.cn/matlabcentral/answers/660473-code-generated-blocks-for-seriallink-return-error-index-expression-out-of-bounds-peter-corke-rob

暂时没有找到解决办法,应该是外部函数只适用于模拟,但不适用于代码生成。考虑用Matlab2022版本试一下。哪位大神可以帮忙解决一下。

参考:https://blog.csdn.net/m0_46427461/article/details/124084542

参考

https://blog.csdn.net/weifengdq/article/details/109738385
https://blog.csdn.net/u010411288/article/details/91382302
https://blog.csdn.net/weixin_52071377/article/details/120811795
https://blog.csdn.net/qq_39751352/article/details/105860577

  • 7
    点赞
  • 82
    收藏
    觉得还不错? 一键收藏
  • 14
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值