1. 从零开始搭建开发环境

第一次接触Simulink和STM32CubeMX联合开发时,我花了两天时间才把环境配置好。这里分享下最稳妥的环境搭建方案,避免大家走弯路。

必备软件清单

  • MATLAB R2020b或更新版本(Simulink已内置)
  • STM32CubeMX 6.0+
  • Keil MDK-ARM 5.30+
  • STM32-MAT/TARGET支持包

安装顺序很重要,建议先装MATLAB,再装STM32CubeMX。我在Windows 11上实测时发现,如果先装CubeMX,有时会导致MATLAB识别不到硬件支持包。安装STM32-MAT/TARGET时,记得勾选"Add to MATLAB path"选项,否则后续会报找不到S函数。

环境变量需要特别检查两个路径:

  1. MATLAB的STM32工具链路径(默认在C:\MATLAB\STM32-MAT)
  2. Keil的ARM编译器路径(通常在C:\Keil_v5\ARM\ARMCC\bin)

验证环境是否配置成功,可以在MATLAB命令窗口输入:

target = stm32.target

如果返回STM32硬件信息,说明工具链配置正确。

2. CubeMX基础配置详解

很多新手在CubeMX配置串口时容易忽略时钟树设置。以STM32F103C8T6为例,正确配置步骤如下:

  1. 在Pinout界面启用USART1
  2. Mode选择Asynchronous
  3. 波特率设为115200(与Simulink默认配置匹配)
  4. Word Length保持8bit
  5. 开启全局中断(NVIC Settings)

时钟树配置关键点

  • HCLK频率设置为72MHz(STM32F1系列最大值)
  • 确保APB2总线时钟与HCLK同步
  • USART1挂在APB2总线上,时钟需与总线一致

生成代码前务必检查Project Manager标签页:

  • Toolchain/IDE选择MDK-ARM V5
  • 勾选"Generate peripheral initialization as a pair of .c/.h files"
  • 取消勾选"Generate under root"(避免Keil工程结构混乱)

3. Simulink模型搭建实战

官方Demo虽然能用,但实际项目需要自定义模型。这里以发送"Hello World"为例:

  1. 新建Simulink空白模型
  2. 添加"STM32 Config"模块(从STM32 Target库)
  3. 拖入"Serial Transmit"模块
  4. 连接Constant模块(值设为'Hello'的ASCII码数组)

关键参数设置

  • Hardware Board选择STM32F103C8
  • Solver Type选择Fixed-step
  • System target file设为stm32.tlc
  • Sample time设为0.001(1ms周期)

有个坑我踩过三次:Simulink的串口缓冲区大小默认只有64字节。如果发送长数据,需要在Model Configuration Parameters的Hardware Implementation里修改Serial Buffer Size参数。

4. S函数问题终极解决方案

遇到"getBuffPtr未定义"错误时,官方Demo的解决方案并不完整。经过多次测试,我总结出更可靠的方法:

  1. 定位到MATLAB安装目录下的STM32-MAT/TARGET
  2. 将addSrc整个文件夹复制到项目目录
  3. 在Keil的Options for Target → C/C++ → Include Paths添加:
    • 项目目录\addSrc\inc
    • 项目目录\generated\Inc

对于自定义S函数,还需要修改stm32_main.c:

extern void getBuffPtr(void);
/* 在main()初始化部分添加 */
HAL_UART_Init(&huart1);
getBuffPtr();

如果仍然报错,检查Keil的Define标签页是否包含:

USE_HAL_DRIVER
STM32F103xB

5. Keil工程调试技巧

代码生成后,Keil工程自动生成在modelname_stm32文件夹。调试时注意:

  1. 首次编译前执行以下操作:

    • Project → Clean Target
    • 点击"Rebuild all target files"
  2. 下载配置:

    • Debug标签页选择ST-Link Debugger
    • 点击Settings → Flash Download
    • 勾选"Reset and Run"

常见下载错误处理

  • "No ST-Link detected":检查驱动是否安装(ST-LINK USB Driver)
  • "Flash timeout":尝试降低下载速度(从4MHz降到1MHz)
  • "Core is locked":按住板子复位键点击下载,松开复位键

串口调试建议使用Termite或Putty,设置与CubeMX一致的波特率。如果收不到数据,用逻辑分析仪检查USART_TX引脚是否有波形输出。

6. 性能优化与错误排查

自动生成的代码效率可能不高,可以通过以下方式优化:

  1. 在Simulink的Configuration Parameters → Code Generation

    • 选择Optimization level为Optimize for speed (O3)
    • 取消勾选"Support: floating-point numbers"
  2. 修改stm32f1xx_it.c中的USART1_IRQHandler:

void USART1_IRQHandler(void) {
  if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_RXNE)) {
    __HAL_UART_CLEAR_FLAG(&huart1, UART_FLAG_RXNE);
    // 添加自定义处理逻辑
  }
}

典型问题排查表

现象 可能原因 解决方案
数据乱码 波特率不匹配 检查CubeMX和上位机设置
只能发送一次 未启用连续发送 在Simulink添加While模块
接收数据丢失 缓冲区溢出 增大Serial Buffer Size
编译超时 杀毒软件拦截 关闭实时防护

7. 进阶应用:自定义协议实现

实际项目中往往需要实现自定义通信协议。以Modbus RTU为例:

  1. 在Simulink创建Subsystem封装协议处理逻辑
  2. 使用S-Function Builder创建协议解析器
  3. 在Model Callbacks → PostLoadFcn添加初始化代码:
function InitModbus()
    coder.extrinsic('loadlibrary');
    loadlibrary('modbus.dll', 'modbus.h');
end

协议测试时,建议先用Simulink的Data Inspector工具监控变量变化,再实际连接硬件。我在实现CRC校验时发现,自动生成的查表法比实时计算效率高10倍以上。

硬件连接方面,RS485模块需要额外配置:

  • 在CubeMX启用GPIO控制RE/DE引脚
  • 修改HAL_UART_Transmit函数为阻塞模式
  • 添加收发切换延迟(实测至少50us)
Logo

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

更多推荐