使用MATLAB/Simulink点亮STM32开发板LED灯

使用MATLAB/Simulink点亮STM32开发板LED灯-笔记

一、STM32CubeMX新建工程

1. 打开 STM32CubeMX 软件,点击"新建工程",选择中对应的型号

2. RCC 设置,选择 HSE(外部高速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)

开启 LSE(外部低速时钟) 为 Crystal/Ceramic Resonator(晶振/陶瓷谐振器)

3. 配置调试模式
非常重要的一步,否则会造成第一次烧录程序后续无法识别调试器

SYS 设置,选择 Debug 为 Serial Wire

4.配置所需要的输入和输出引脚

根据电路板硬件的实际情况配置LED灯引脚

5.选择时钟

HCLK (MHz)输入框中,改为频率为 72MHz,自动计算时钟分配。

6.工程文件的输出

输入项目名和项目路径和选择应用的 IDE 开发环境 MDK-ARM V5

7.工程文件代码生成

每个外设生成独立的 '.c/.h' 文件

不勾:所有初始化代码都生成在 main.c

勾选:初始化代码生成在对应的外设文件。 如 GPIO 初始化代码生成在 gpio.c 中。

8.点击 GENERATE CODE 生成代码

9.打开MDK-ARM V5 进行编译,无错误 无警告

打开MATLAB 的 Simulink (动态系统和嵌入式系统的多领域模拟和基于模型的设计工具)

在Simulink 新建 空白模型

similink库中的Stateflow下拉框选择"Chart",拖到右侧空白框中。改名为"LED_STate"。

双击"Chart"进入里面的内容,拖动"状态"组件。后续作为状态转移。

在状态框中写入如下代码并状态与状态之间相连

after:after函数函数就是经过多长时间再到下一个状态,相当于延时

通过"建模"下的"符号窗格" 看到三个名称的状态有感叹是提示没有定义。

通过单击每个符号名称的类型进行修改,led_output 改为"Output Data"。

也可以通过选择符号名称右键-> 检查

属性检查器可查看属性信息

led_output 类型改为"uint8"

其他两个符号 改为"Parameter Data"类型。

类型设置完成后 无感叹号提示。

以上操作也可以通过汇总的方式查看,通过模块资源管理器。

"HIGH"和" LOW"两个符号的Value值改成 "1"和"0"

返回上一层"Chart"。

在模型界面上单击输入"Output"。

修改Output信号名称为"LEDOutput"。

更新我们所设计的模型

为了方便观察和所设计的模型是否正常,在LED_STate增加"Scope"示波器,可以看到示波器正常输出高低电平。

在APP下的标签"Embedded oder"生成程序代码。

从下图中可以看出 编译不通过,下方有"建议的操作",选择第一项弹出配置参数。

配置参数修改三个地方如下图所示。

修改完成后,继续点击"编译"。

可以看到右侧已经生成代码文件

生成的代码 .c和.h 保存路径如下图的提示。

三、MDK导入生成的代码

在Groups增加新的文件夹,名称为SimulinkCode

在Files项目下"Add Files..."导入Simulink生成的.c文件

增加.h头文件的引用路径

首先这个模型生成的初始化"untitled_initialize"是空的,我们可以不调用,但是后面如果模型比较大了,或者说初始化函数中有文件的话,这个是必须要调。

untitled_step()函数是我们Simulink生成的状态机,需要在main.c中while循环添加。

我们现在这个untitled_step()函数是在while中一直跑的,这样是没有固定的运行周期的。但是我们在模型仿真的时候,定步长是固定,0.001的采样时间。所以我们需要给他一个周期。在中断文件下添加"BalancecarTaskcount"变量来计数。

接下来我们看看这个,控制LED亮灭调用stm32函数的"HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_SET);"直接给"1"或"0"就行,但是下面如图所示,这里是结构不方便使用,需要改成一个全局变量。

在Simulink中的代码接口下的"默认代码映射",下方就会弹出代码映射窗口。

单击"LEDOutpu"组件后在码映射窗口下选择"Outports",有一个"Output"选项。

右侧弹出"属性检查器"在Storage Class字符下,下拉框选择"ExportedGlobal"。

可以看到Simulink代码显示窗口 的LEDoutput原结构体的形式改为全局变量。

修改代码,编译通过

untitled.c

c 复制代码
/*
 * Academic License - for use in teaching, academic research, and meeting
 * course requirements at degree granting institutions only.  Not for
 * government, commercial, or other organizational use.
 *
 * File: untitled.c
 *
 * Code generated for Simulink model 'untitled'.
 *
 * Model version                  : 1.2
 * Simulink Coder version         : 9.8 (R2022b) 13-May-2022
 * C/C++ source code generated on : Fri May  3 15:00:42 2024
 *
 * Target selection: ert.tlc
 * Embedded hardware selection: Intel->x86-64 (Windows64)
 * Code generation objectives: Unspecified
 * Validation result: Not run
 */

#include "untitled.h"
#include "rtwtypes.h"

/* Named constants for Chart: '<Root>/LED_STate' */
#define untitled_IN_LED_OFF            ((uint8_T)1U)
#define untitled_IN_LED_ON             ((uint8_T)2U)

/* Exported block signals */
uint8_T LEDOutput;                     /* '<Root>/Output' */

/* Block states (default storage) */
DW_untitled_T untitled_DW;

/* Real-time model */
static RT_MODEL_untitled_T untitled_M_;
RT_MODEL_untitled_T *const untitled_M = &untitled_M_;

/* Model step function */
void untitled_step(void)
{
  /* Chart: '<Root>/LED_STate' */
  if (untitled_DW.temporalCounter_i1 < 511U) {
    untitled_DW.temporalCounter_i1++;
  }

  if (untitled_DW.is_active_c3_untitled == 0U) {
    untitled_DW.is_active_c3_untitled = 1U;
    untitled_DW.is_c3_untitled = untitled_IN_LED_ON;
    untitled_DW.temporalCounter_i1 = 0U;

    /* Outport: '<Root>/Output' */
    LEDOutput = 0U;
  } else if (untitled_DW.is_c3_untitled == untitled_IN_LED_OFF) {
    /* Outport: '<Root>/Output' */
    LEDOutput = 1U;
    if (untitled_DW.temporalCounter_i1 >= 500U) {
      untitled_DW.is_c3_untitled = untitled_IN_LED_ON;
      untitled_DW.temporalCounter_i1 = 0U;

      /* Outport: '<Root>/Output' */
      LEDOutput = 0U;
    }
  } else {
    /* Outport: '<Root>/Output' */
    /* case IN_LED_ON: */
    LEDOutput = 0U;
    if (untitled_DW.temporalCounter_i1 >= 500U) {
      untitled_DW.is_c3_untitled = untitled_IN_LED_OFF;
      untitled_DW.temporalCounter_i1 = 0U;

      /* Outport: '<Root>/Output' */
      LEDOutput = 1U;
    }
  }

  /* End of Chart: '<Root>/LED_STate' */
}

/* Model initialize function */
void untitled_initialize(void)
{
  /* (no initialization code required) */
}

/* Model terminate function */
void untitled_terminate(void)
{
  /* (no terminate code required) */
}

/*
 * File trailer for generated code.
 *
 * [EOF]
 */
相关推荐
sponge'39 分钟前
opencv学习笔记2:卷积、均值滤波、中值滤波
笔记·python·opencv·学习
ljt27249606613 小时前
Compose笔记(二十六)--DatePicker
笔记·android jetpack
早日退休!!!3 小时前
性能优化笔记
笔记·性能优化
love530love4 小时前
【PyCharm必会基础】正确移除解释器及虚拟环境(以 Poetry 为例 )
开发语言·ide·windows·笔记·python·pycharm
江山如画,佳人北望5 小时前
stm32-c8t6实现语音识别(LD3320)
stm32·单片机·嵌入式硬件
wangxinwei20005 小时前
stm32_LAN8720驱动
stm32·单片机·嵌入式硬件
小胖同学~5 小时前
Linux--vsFTP配置篇
stm32·单片机·嵌入式硬件
普宁彭于晏5 小时前
元素水平垂直居中的方法
前端·css·笔记·css3
m0_637146936 小时前
计算机网络基础总结:TCP/IP 模型、TCP vs UDP、DNS 查询过程
笔记·tcp/ip·计算机网络
Lester_11016 小时前
嵌入式学习笔记 - freeRTOS vTaskPlaceOnEventList()函数解析
笔记·学习