STM32-MBD(1)Matlab2022/2023 安装 STM32 硬件支持包
STM32-MBD(1b)Matlab2025b 安装 STM32 硬件支持包
STM32-MBD(2)Simulink 模型部署入门:点灯
STM32-MBD(3)Simulink 模型部署之状态机:闪灯
STM32-MBD(4)Simulink 模型部署之状态机:开关控制
STM32-MBD(5)Simulink 模型开发之外部中断:开关控制
STM32-MBD(6)Simulink 模型开发之 PWM 输出
STM32-MBD(7)Simulink 模型开发之 定时器
STM32-MBD(8)Simulink 模型开发之 ADC 转换
STM32-MBD(9)Simulink 模型开发之串口通信
STM32-MBD(10)Simulink 模型开发之上位机
STM32-MBD(11)Simulink 模型开发之处理器在环仿真(PIL)


在基于 Simulink 的 STM32 Model-Based Design(MBD)开发中,定时中断是构建多任务系统、周期控制、实时调度的基础

在前期的 GPIO 点灯、按键输入实验中,系统仍处于“事件驱动 / 人工触发”阶段。而 TIM 定时中断实验 让系统进入 周期调度模式,通过本实验可以验证 硬件定时器 → Simulink Function-Call Subsystem 的完整链路,为后续 PWM、ADC 采样、FOC 控制环、多任务调度提供可信的时间基准。


1. 项目简介

1.1 项目内容

本文以 STM32G431 为目标平台,介绍如何使用 Simulink 构建 TIM 定时中断模型,并生成代码部署到 STM32 开发板运行,通过 LED 闪烁 这一可视化方式验证定时器调度的正确性。

youcans 本实验的目标是:

  • 使用 TIM1 产生 周期性定时中断;
  • 每次中断触发时,翻转一次 GPIO PA5(板载 LED) 状态;
  • 通过 LED 的稳定闪烁,验证:
    • 定时器中断是否按设定周期触发;
    • Simulink 模型中的时间语义是否被 MCU 正确执行。

1.2 软硬件条件

关于所需的软硬件条件和安装过程,详见 【STM32-MBD】(1)安装 Simulink STM32 硬件支持包
强烈建议安装相关软件时使用推荐版本。
请严格按照文中介绍的步骤安装和配置软件。

必需的硬件:

  • STM32 开发板(如:NUCLEO-G431RB 开发板,也可以选择其它 STM32 开发板,但需要安装对应的固件包)。
  • Micro-micro USB 数据线,或 USB Type-A 至 Micro-B 连接线缆,用于将STM32 Nucleo 板连接到 PC。

必需的软件:

  • STM32 开发工具(建议首先严格使用推荐版本跑通本文项目)

    • STM32CubeMX (推荐使用 V6.4.0)
    • STM32CubeProgrammer (推荐使用 V2.6.0)
    • STM32CubeIDE(或 Keil,MDK-ARM 等 IDE 工具)
    • STM32Cube_FW_G4 固件包(推荐采用 V1.5.0)
      如果使用其它 STM32 MCU,则需选择对应的固件包。例如使用 STM32F4 时则要选择STM32Cube_FW_F4_V1.26.0 固件包。
  • MATLAB/Simulink(本文使用 MATLAB R2022b,可以采用更新版本)

    • Simulink Coder:从 Simulink 模型、Stateflow 图和 MATLAB 函数生成并执行 C 和 C++ 代码,用于实时和非实时应用,包括仿真加速、快速原型构建和硬件在环测试
    • STM32 嵌入式硬件支持包,Embedded Coder Support Package for STMicroelectronics STM32 Processors,STM32 处理器的嵌入式硬件支持包

2. 用 STM32CubeMX 创建工程

2.1 基础配置

本例直接使用 STM32CubeMX 创建新的 STM32 工程。也可以从 Simulink 创建 STM32CubeMX 工程。

  1. 打开 STM32CubeMX。

  2. 选择 New Project(或Ctrl-N快捷键)新建工程,进入 New Project 界面。
    选择 STM32G431RB 作为目标 MCU(参考开发板的 MCU 型号)新建 CubeMX 工程,将工程保存为 “STM32G431_TIM01.ioc”。

  3. 自动转入 CubeMX 的 Pinout Configuration 视图,进行管脚配置:
    (1)选择 “System Core – SYS” 设置调试器类型,将 Debug 模式设为 “Serial Wire”。
    (2)选择 “System Core – SYS” 设置基础时钟源,将 Timebase Source 设为 “TIM2”——非常重要!
    注意:Timebase Source 默认为 “SysTick”,但在 STM32支持包中 “SysTick” 已经用作框架的基础时间功能,因此必须修改为 非"SysTick" 的其它定时器。否则在编译项目时会报错——非常重要!。

在这里插入图片描述


(3)选择 “System Core – RCC” 配置时钟模式,设置高速晶振为外部时钟,将 High Speed Clock (HSE) 设为 “Crystal/Ceramic Resonator”。

在这里插入图片描述


(4)选择 “System Core – GPIO” ,配置 GPIO 用于 LED 指示或按键触发。

  • 搜索 PA5 管脚(在 NUCLEO 开发板中 连接LD2 灯),将其设置为 GPIO_Output。
  • 搜索 PA9 管脚,将其设置为 GPIO_Output。
  • 可选地,搜索 PC13 管脚(在 NUCLEO 开发板中 连接蓝色用户按键 User Button),将其设置为 GPIO_EXTI13。

2.2 TIM 配置

  1. 启用并配置TIM1 :
    (1)选择 “引脚配置(Pinout & Configuration)”,从左侧下拉列表中选择 “Timers – TIM1 – TIM1 Mode and Configuration ” ,将时钟源设为内部时钟 “Clock Source: Internal Clock”。
    (2)配置 TIM 工作模式和参数。
Counter Settings
   Prescaler(PSC-16 bits value): 159
   Counter Mode: Up
   Counter Period(AutoReload Register-16 bits value): 999

在这里插入图片描述

(3)使能 NVIC 中断:
勾选 “TIM1 update interrupt and TIM16 global interrupt”。
在这里插入图片描述


2.3 项目配置

  1. 在 Clock Configuration 视图进行时钟配置。
    如下图所示,APB2 定时器时钟为160MHz(TIM1挂载在APB2总线上)。

在这里插入图片描述


  1. 点击菜单栏 “Project Manager” 进入工程配置界面,如下图所示。
    (1)在 Project Name 输入项目名称 “STM32G431_TIM01”。
    (2)在 Project 中勾选 “Do not generate the main()”,在生成代码时不生成 main.c 文件中的 main() 函数。
    (3)在 Toolchain/IDE 选择 IDE 工具为 “STM32CubeIDE”(也可以根据需要选择其它 IDE 工具 ),取消勾选 “Generate Under Root”。

在这里插入图片描述

(4)在 “Project Manager” 继续向下拉,“在 MCU and Firmware Package” 栏中,取消选中 “Use latest available version”,根据所安装的 G4 固件版本,选择 “STM32Cube FW_G4 V1.6.0”;
(5)如果固件包不是安装在默认路径,则要取消选中 “Use Default Firmware Location”,通过 Browse 选择固件包的安装路径。

在这里插入图片描述


(5)在 Code Generator 中,勾选 “Generate peripheral initialization as a pair of ‘.c/.h’ files per peripheral”,让每个外设生成独立的’.c/.h’文件。
在这里插入图片描述


(6)在 Advanced Settings 中,**将 “Driver Selector” 全部设置为 “LL”(默认为 “HAL”),为外设选择低级 (LL) 驱动——非常重要!** 否则编译会报错。

(7)在 Advanced Settings 中,将 “Generated Function Calls” 的 “Visibility(Static)” 勾选项全部取消,对所有外设初始化函数调用取消选择可见性(静态)。

在这里插入图片描述


  1. 完成以上配置后,使用快捷键 “CTL+S” 或点击 File–Save Project,保存 CubeMX 项目文件。
    注意:在 STM32CubeMX 中配置完成后,不要点击 “GENERATE CODE” 生成代码,而是直接保存项目文件 “STM32G431_TIM01.ioc”。

3. Simulink 仿真模型

3.1 模型任务与结构

开发任务:使用 TIM1 定时器,生成一个 1ms 的定时中断。
在以上 CubeMX配置下,APB2 Timer Clock = 160 MHz,PSC = 159 → Timer Counter Clock = (159+1)/160MHz= 1 MHz。设置 ARR = 999,则 UpdatePeriod= (999+1)/1MHz=1 ms。

[ TIM Module ] ──配置定时器
        │
[ Hardware Interrupt ] ──绑定 TIM1 Update ISR
        │
[ Triggered Subsystem ] ──中断服务逻辑(GPIO 翻转)

仿真模型使用 TIM模块负责计时,而以 Hardware Interrupt 模块作为中断服务程序的入口。


3.2 创建仿真模型

在 CubeMX 项目文件所在的路径(例如:“D:\SimulinkProjects\STM32G431_TIM01”)下新建 Simulink 仿真模型,注意 仿真模型 .slx 与 CubeMX 项目 .ioc 要保存在同一个目录下。

  1. 运行 MATLAB 软件,打开 Simulink。点击 “空白模型” 创建新的 Simulink 模型,保存到本项目路径下:STM32G431_TIM01.slx

  2. 在仿真模型中添加 TIM 定时器模块。
    (1)点击菜单栏的 “库浏览器” 打开库浏览器,展开 “Embedded Coder Support Package for STMicroelectronics STM32 Processors – STM32G4xx Based Boards”。选择 “Timer” 模块,将其拖动到右侧的模型。
    (2)设置 “Timer” 模块参数。如图所示,选择 Timer module 为 “TIM1”,并勾选 “Enable frequency input”,出现 输入端口 freq count 对应于 ARR。
    (3)添加一个 constant 模块,作为 TIM 定时器模块的输入。
    设置 ARR=999,即配置一个 1ms 的定时器:

Timer Clock = APB2 Timer Clock/(PSC+1) = 160MHz/(159+1) = 1 MHz
Update Period = (ARR + 1) / Timer Clock = (999+1)/1MHz = 1 ms

注意:TIM 模块不会自动生成中断服务函数,它只完成硬件配置与计数器控制。youcans

在这里插入图片描述

  1. 在仿真模型中添加 外部中断模块 Hardware Interrupt,作为 ISR 的入口。
    (1)从 “Embedded Coder Support Package for STMicroelectronics STM32 Processors – STM32G4xx Based Boards” 选择 “Hardware Interrupt” 模块,将其拖动到右侧的模型。
    (2)设置 “Hardware Interrupt” 参数。如图所示,选择 Interrupt group 为 “Timer(TIM)”,Interrupt name 为 “TIM1_UP_TIM16_IRQHandler”,Events to serve:TIM1 Update。
    该模块的作用是生成真实的 TIM1_UP_TIM16_IRQHandler,在 ISR 中清除 UIF 标志,调用 Simulink 的 function-call 调度点。如果没有这个模块,启用 Update Interrupt 会导致系统进入中断风暴并卡死。

  2. 创建一个 Triggered Subsystem 模块,模拟“中断服务函数(ISR)”的执行体。
    (1)点击菜单栏的 “库浏览器” 打开库浏览器,展开 “Simulink/Ports &Subsystems”。选择 “Triggered Subsystem” 模块,将其拖动到右侧的仿真模型。
    (2)双击进入 “Function-Call Subsystem” 模块,将触发器类型设置为:“上升沿”
    (3)子系统内部逻辑如下:

    • 使用 Unit Delay(boolean) 保存 LED 上一次状态
    • 使用 NOT 运算对状态取反
    • 将结果写入 GPIO PA9

逻辑关系可以抽象为:

state(k) = NOT(state(k-1))

每次 TIM1 Update 中断触发一次执行。

在这里插入图片描述


3.3 关联 Simulink 模型与 CubeMX 工程

  1. 在 Simulink 菜单选择 “建模” - “模型设置” (也可以用 CTRL+E),打开“配置参数”对话框。
    左侧边栏中选择“求解器”,如下图所示。
    (1)在右侧 “仿真时间” 设置为 “inf”。
    (2)在 “求解器选择” 选项设置类型为 “定步长”,“固定步长(基础采样时间)” 设为 “1e-3” 。
    (3)可选地,在 "任务和采样周期选项"下勾选:“将每个离散速率视为单独任务”和“自动处理数据传输的速率转换”。

  1. 在右侧 “硬件实现(Hardware board settings)” 配置 “Target hardware resources” ,关联 STM32CubeMX 工程文件。
    (1)检查 PC 与 STM32G431 开发板连接正常。 在 “Hardware board” 选项的下拉框中选择 “STM32G4xx Based”.
    注意:必须确保 PC 与 STM32G431 开发板连接正常,才能进行硬件配置。
    (2)点击 “Browse” 选择当前项目的目录,选择 CubeMX 创建的工程文件 “STM32G431_TIM01.ioc”。
    (3)点击 “Target hardware resources–Timers”,配置 Timer group 为 “Advanced Timers 1/8/20” ,勾选 “Show TIM1 configurations”,“Start timer during model initialization” 和 计数器溢出/更新事件 “Enable Update Interrupt”。可选地,勾选 触发事件 “Enable Trigger interrupt”(本实验中非必须)。

在这里插入图片描述


  1. 完成搭建仿真模型,保存为文件 STM32G431_TIM01.slx。注意仿真模型 .slx 与 CubeMX 项目 .ioc 要保存在相同的路径下。

3.4 STM32 代码生成与运行

  1. 用 USB连接线连接 PC 与 NUCLEO-G431RB 开发板。

  2. 在 Simulink 打开仿真模型 STM32G431_TIM01.slx。

  3. 在 “硬件(Hardware)” 窗口点击 “编译、部署和启动”(Ctrl+B 快捷键),就启动模型 STM32G431_TIM01 的编译过程,为模型生成代码,并加载到 NUCLEO-G431RB 开发板。
    模型编译过程的主要信息显示在 “诊断查看器” 中,编译摘要如下。

    ### 正在启动 STM32G431_TIM01 的编译过程
    ### 正在为 '模型特定' 文件夹结构生成代码和工件
    ### 正在将代码生成到编译文件夹中: C:\MATLAB\MBD_STM32G431\STM32G431_TIM01\STM32G431_TIM01_ert_rtw
    ### Invoking Target Language Compiler on STM32G431_TIM01.rtw
    ### Using System Target File: C:\MATLAB\R2023b\rtw\c\ert\ert.tlc
...
    ### 使用工具链: GNU Tools for ARM Embedded Processors
    ### 'C:\MATLAB\MBD_STM32G431\STM32G431_TIM01\STM32G431_TIM01_ert_rtw\STM32G431_TIM01.mk' 是最新的
    ### 正在编译 'STM32G431_TIM01': "C:\MATLAB\R2023b\bin\win64\gmake"  -f STM32G431_TIM01.mk all
...
    Download verified successfully
    ### Successful completion of build procedure for: STM32G431_TIM01
    ### 'STM32G431_TIM01' 的 Simulink 缓存工件是在 'C:\MATLAB\MBD_STM32G431\STM32G431_TIM01\STM32G431_TIM01.slxc' 中创建的。
youcans@qq.com 编译过程已成功完成
    
编译的顶层模型目标:
    
    模型               操作           重新编译原因     
    =========================================
    STM32G431_TIM01  代码已生成并完成编译。  生成的代码已过期。  
    
    编译了 1 个模型,共 1 个模型(0 个模型已经是最新的)
    编译持续时间: 0h 0m 16.48s

在这里插入图片描述


  1. 将生成的工程下载到 STM32 开发板并运行。
    在配置 PSC=159, ARR=500 时,TIM1 Update 周期约为 0.5ms。用示波器测试 PA9的输出信号,观测到方波周期 ≈ 1 ms,即500ms 翻转一次。

这表明:

  • TIM1 定时中断工作正常;
  • Simulink 中的时间设定已被 MCU 准确执行。

请添加图片描述


4. 中断计数分频调度实验

在实际嵌入式系统中,并不是每个周期任务都需要独立的硬件定时器。
更常见、也更工程化的做法是:

  • 用一个高频、稳定的硬件定时中断作为“系统节拍”,
  • 在中断服务逻辑中通过计数实现多个低频任务的调度。

例如,基础节拍:10 ms(100 Hz),快任务:每 10 ms 执行,慢任务:每 50 ms 执行。


4.1 实验目标

本实验展示如何在 Simulink MBD 下,用 TIM1 的 2 ms Update 中断,通过计数分频实现多周期 GPIO 控制。
TIM1 Update 中断周期:2 ms(500 Hz)
PA8:每次中断都翻转(2 ms 翻转),方波周期:4 ms(250 Hz)
PA9:每 5 次中断翻转一次(10 ms 翻转),方波周期:20 ms(50 Hz)

⚠️ 注意:“翻转周期”和“方波周期”不同,toggle 逻辑下的方波周期 = 2 × 翻转周期。


4.2 模型结构

本实验沿用上一节已验证成功的硬件中断架构:

TIM1 (ARR = 19992 ms)
        │
Hardware Interrupt (TIM1 Update)
        │
Function-Call Subsystem(中断调度子系统)
        │
 ┌─────────────┬─────────────┐
 │ PA8 快任务  │ PA9 慢任务  │
 └─────────────┴─────────────┘

其中:

  • TIM 模块:负责 定时
  • Hardware Interrupt 模块:负责 ISR 绑定与清中断
  • 子系统:负责 调度策略与业务逻辑

在这里插入图片描述

子系统内部设计:计数分频调度逻辑

  1. PA8:每次中断翻转(基准任务)
    PA8 作为“快任务”,逻辑为:state8(k) = NOT(state8(k−1))
    模块实现:Unit Delay(state8_z,初值 0)、Logical NOT、Digital Port Write(PA8)。
    每 2 ms 中断执行一次,因此:PA8 翻转周期 = 12 ms,PA8 方波周期 = 4 ms。

  2. PA9:基于 Counter Limited 的“每 5 次中断翻转一次”
    PA9 作为“慢任务”,采用 计数分频 实现。

在这里插入图片描述

实验波形与结果分析
示波器观测结果与理论完全一致,说明:

  • TIM1 硬件中断工作正常
  • Counter Limited 分频逻辑正确
  • Function-Call Subsystem 的中断调度可靠

youcans 将分频因子 5 改为 可调参数 N,可以在同一中断中实现不同周期的定时中断任务,构建 基于中断的多任务调度框架。

下图是 N=3 的波形:PA8 翻转周期 = 2 ms,P9 翻转周期 = 6ms。

在这里插入图片描述

(本节完)


版权声明:
youcans@qq.com 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/156362658)
Copyright@youcans 2025
Crated:2025-12

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐