你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【STM32C5教程】(7)TIM1 互补 PWM 输出实验

[复制链接]
HuangXF 发布时间:2026-10-21 13:37

1. 项目简介

1.1 实验目标

本实验在 NUCLEO-C542RC 开发板上,使用 STM32C542RCT6 的高级定时器 TIM1 的 CH1/CH1N 通道,通过 PA8 和 PB13 输出频率为 10 kHz、占空比为 50%、死区时间约为 500 ns 的互补 PWM 信号。

功能需求:

  • 使用 TIM1 的 CH1(PA8)和 CH1N(PB13)输出互补 PWM 信号
  • PWM 频率 10 kHz
  • 占空比 50%
  • 死区时间约 500 ns

开发板和 MCU 型号: NUCLEO-C542RC 开发板,搭载 STM32C542RCT6 MCU。

什互补 PWM? 两路信号呈互补关系:一路为高电平时,另一路为低电平。这种信号常用于半桥/全桥电机驱动电路,互补的两路分别驱动上下两个开关管。在切换边沿插入“死区时间”——两路都保持低电平的一小段空白——可以确保上下管不会同时导通,避免直通短路。

<br>

1.2 实验条件

硬件:

  • NUCLEO-C542RC 开发板
  • 支持数据传输的 USB Type-C 线(用于连接 ST-LINK 接口)
  • 示波器(用于观测 PA8 与 PB13 的输出波形)

软件:

  • STM32CubeMX2(用于引脚、时钟配置与代码生成)
  • VS Code + STM32Cube 插件(用于编译、烧录、调试)

<br>

2. 硬件说明

2.1 NUCLEO-C542RC 开发板

NUCLEO-C542RC 是 ST 基于 STM32C542RCT6 推出的 Nucleo-64 开发板。主要特性:

  • MCU:STM32C542RCT6,Arm Cortex-M33 内核,最高主频 144 MHz,256 KB Flash,64 KB RAM
  • 调试器:板载 STLINK-V3EC,支持大容量存储、虚拟串口和调试端口三种功能
  • 用户 LED:LD1,连接 PA5
  • 用户按键:B1,连接 PC13
  • 复位按键:B2
  • 扩展接口:Arduino Uno V3 和 ST morpho 连接器

本实验使用 PA8 和 PB13 输出 PWM,通过示波器观测,不使用板载 LED 或按键。

<br>

2.2 引脚说明

引脚 复用功能 说明
PA8 TIM1_CH1 互补 PWM 的主通道
PB13 TIM1_CH1N 互补 PWM 的互补通道

PA8(TIM1_CH1):配置为复用功能(AF1)、推挽输出,由 TIM1 通道 1 输出 PWM 波形。

PB13(TIM1_CH1N):配置为复用功能(AF1)、推挽输出,由 TIM1 通道 1 的互补通道输出互补 PWM 波形。

<br>

3. STM32CubeMX2 工程配置

3.1 新建工程

本实验采用 MCU 方式创建工程,即以芯片型号 STM32C542RC 为起点,而非开发板方式。

  1. 进入 MCU 选择界面 启动 STM32CubeMX2,在首页点击 MCU,进入芯片型号选择列表。
  2. 搜索并选中芯片 在 MCU name 输入框中输入 STM32C542RC(或完整型号 STM32C542RCT6),从筛选出的列表中选择对应型号。

image.png

  1. 填写项目信息 输入项目名称 TIM1_PWM_Comp 和项目保存路径。项目名称避免使用特殊字符,路径建议使用纯英文目录。

3.2 基础配置

工程创建后,软件自动进入 Pinout 视图。

时钟配置:本工程系统时钟配置为 144 MHz,APB1 分频系数为 1,TIM1 输入时钟为 144 MHz。

image.png

3.3 TIM1 配置

(1)配置 TIM1 通道 1 为 PWM Generation

在左侧外设列表中找到 Timers → TIM1,点击展开。在 Mode 区域中,将 Channel1 设置为 PWM Generation CH1 CH1N。

设置完成后,Pinout 视图中 PA8 自动分配为 TIM1_CH1,PB13 自动分配为 TIM1_CH1N。

image.png

(2)配置定时参数

在 TIM1 的 Parameter Settings 中设置:

参数 值 说明
Prescaler (PSC) 11 144 MHz ÷ 12 = 12 MHz
Counter Mode Up 向上计数
Counter Period (ARR) 1199 12 MHz ÷ 1200 = 10 kHz
auto-reload preload Enable 建议启用

PWM 频率计算:

PWM 频率 = TIM1时钟 / ((PSC + 1) × (ARR + 1))
= 144,000,000 / ((11 + 1) × (1199 + 1))
= 144,000,000 / (12 × 1200)
= 10,000 Hz = 10 kHz

image.png

(3)配置 PWM 通道

在 Channel1 的配置区域中:

参数 值 说明
Mode PWM1 PWM 模式 1
Pulse (CCR1) 600 占空比 50%
Output compare preload Enable 使能比较预装载
CH Polarity High 通道极性为高
CHN Polarity High 互补通道极性为高

占空比计算:

占空比 = Pulse / (ARR + 1) = Pulse / 100

占空比 = Pulse / (ARR + 1) = 600 / 1200 = 50%

image.png

(4)配置死区时间

切换到 Break and Dead Time management 标签页,配置死区:

参数 值 说明
Dead Time 72 死区计数
Automatic Output State Disable MOE 由软件启动
Off State Run Mode Disable —
Off State Idle Mode Disable —

死区时间计算:

DTS 时钟 = TIM1 时钟 / DTS 分频 = 144 MHz / 1 = 144 MHz
死区时间 = Dead Time 值 / DTS = 72 / 144 MHz = 0.5 µs = 500 ns

(5)确认引脚配置

回到 Pinout 视图,PA8 应显示为 TIM1_CH1,PB13 应显示为 TIM1_CH1N。

image.png

3.4 项目配置

  1. 点击 Project Settings,进入工程设置页面。
  2. 在 IDE Format 下拉选项中选择 CMake。
  3. 在 CMake Toolchain 下拉选项中选择 GCC。
  4. 确认配置无误后,点击 Generate Code。CubeMX2 会执行配置检查,如果没有错误,开始在指定路径下生成 CMake 工程文件。
  5. 生成完成后,项目路径下会出现标准 CMake 工程结构,包含 Core/、Drivers/、CMakeLists.txt 等。

image.png

4. 编程实现

4.1 实现思路

采用 “TIM1 硬件互补 PWM + 软件启动通道和计数器” 的方案:

mx_tim1_init() // CubeMX2 生成:10 kHz 时基、PWM1 模式、CH1/CH1N、
│ // PA8/PB13 复用、死区 500 ns
│
▼
HAL_TIM_OC_StartChannel(htim1, HAL_TIM_CHANNEL_1) // 启动 CH1,使能 CC1 和 MOE
│
▼
HAL_TIM_OC_StartChannel(htim1, HAL_TIM_CHANNEL_1N) // 启动 CH1N
│
▼
HAL_TIM_Start(htim1) // 启动计数器,PWM 开始输出
│
▼
主循环空闲:PWM 由硬件持续输出

两步启动 CubeMX2 中 Automatic Output State 设为 Disable,意味着主输出使能位(MOE)不会自动开启。MOE 必须由软件显式使能,否则 PA8 和 PB13 引脚一直无波形输出。HAL_TIM_OC_StartChannel() 在启动通道的同时会打开 MOE,HAL_TIM_Start() 则启动计数器。两者缺一不可。

先启动通道、后启动计数器的原因:让 MOE 先就位,计数器一开始走就能输出稳定波形,避免启动瞬间多出一个毛刺脉冲。

HAL2 与 HAL1 的差异:经典 HAL1 中使用单个函数 HAL_TIM_PWM_Start() 启动 PWM;CubeMX2 的 HAL2 改为两个函数分开操作——HAL_TIM_OC_StartChannel() 启动输出通道,HAL_TIM_Start() 启动计数器。

各步骤使用的 HAL 函数:

步骤 HAL 函数 作用
获取 TIM1 句柄 mx_tim1_gethandle() 返回 CubeMX 生成的 TIM1 句柄
启动输出通道 HAL_TIM_OC_StartChannel() 使能通道并开启 MOE
启动计数器 HAL_TIM_Start() 启动 TIM1 计数,PWM 开始输出

<br>

4.2 关键代码

在 VS Code 中打开生成的 CMake 工程,找到 Core/Src/main.c,添加以下代码。

(1)文件头部添加头文件

#include "main.h"
#include "mx_tim1.h"

<br>

(2)主函数

int main(void)
{
  if (mx_system_init() != SYSTEM_OK)
  {
    return (-1);
  }
  else
  {
    /*
      * You can start your application code here
      */
    /* TIM1_CH1 (PA8) and TIM1_CH1N (PB13) complementary PWM, deadtime
     * already configured by mx_tim1_init() (500 ns). The timer is
     * initialized but the counter and the output channels are not yet started.
     */
    hal_tim_handle_t *htim1 = mx_tim1_gethandle();

    /* Start the output channels: enables CC1/CC1N and the main output MOE. */
    if (HAL_TIM_OC_StartChannel(htim1, HAL_TIM_CHANNEL_1) != HAL_OK)
    {
      return (-1);
    }
    if (HAL_TIM_OC_StartChannel(htim1, HAL_TIM_CHANNEL_1N) != HAL_OK)
    {
      return (-1);
    }

    /* Start the TIM1 counter to generate the PWM at 10 kHz/50% duty. */
    if (HAL_TIM_Start(htim1) != HAL_OK)
    {
      return (-1);
    }

    while (1) {}
  }
}

代码说明:

  • mx_tim1_gethandle() 返回 CubeMX2 生成的 TIM1 句柄。
  • HAL_TIM_OC_StartChannel(htim1, HAL_TIM_CHANNEL_1) 启动主通道 CH1(PA8),同时使能主输出 MOE。
  • HAL_TIM_OC_StartChannel(htim1, HAL_TIM_CHANNEL_1N) 启动互补通道 CH1N(PB13)。
  • HAL_TIM_Start(htim1) 启动 TIM1 计数器。前两步只使能输出,不启动计数;第三步才真正开始产生 PWM。
  • 频率、占空比、死区等参数已在 mx_tim1_init() 中配置完成,main.c 无需重新设置。。

<br>

5. 编译烧录与运行测试

5.1 编译与烧录

  1. 打开工程:用 VS Code 打开 CubeMX2 生成的 CMake 工程文件夹(如 TIM1_PWM_Comp_cmake)。
  2. 编译:点击 VS Code 底部状态栏的 Build 按钮,或使用命令面板执行 CMake 构建。编译完成后,终端应输出 Build finished with exit code 0,无 error。
  3. 连接开发板:用支持数据传输的 USB Type-C 线连接 NUCLEO-C542RC 的 ST-LINK USB 口(CN1)。
  4. 确认设备识别:打开设备管理器,在“端口 (COM 和 LPT)”下应能看到 STLink COMx。
  5. 烧录:点击 VS Code 中的运行按钮,将固件下载到开发板。

image.png

image.png

<br>

5.2 运行与测试

烧录完成后,程序自动开始运行。用示波器两通道分别测量 PA8 和 PB13,观察波形:

  • 测试 1:频率 两路信号频率均为 10 kHz,周期 100 µs。
  • 测试 2:互补关系 CH1(PA8)与 CH1N(PB13)呈互补关系:当 PA8 为高电平时,PB13 为低电平;反之亦然。
  • 测试 3:占空比 两路信号的占空比均约 50%。
  • 测试 4:死区时间 在两路信号切换边沿处,可以观察到明显的死区间隔——两路同时为低电平的一段空白时间,约 500 ns。

image.png

image.png

测试结果: ☑ 编译通过,无错误 ☑ 烧录成功 ☑ 两路 PWM 频率均为 10 kHz ☑ 两路呈互补关系 ☑ 两路占空比均约 50% ☑ 切换边沿处死区时间约 500 ns 功能正常。

<br>

6. 小结

本实验通过 TIM1 的互补 PWM 输出实现了两路 10 kHz、50% 占空比、500 ns 死区的互补信号输出,掌握了 STM32C5 系列高级定时器互补 PWM 与死区时间的配置与使用方法。

核心逻辑可以概括为:“TIM1 硬件产生互补 PWM → 软件启动通道与计数器 → 输出带死区的互补波形”。

有两点需要注意:

第一,主输出 MOE 必须由软件使能。 CubeMX2 中 Automatic Output State 设为 Disable,意味着不会自动开启 MOE。必须调用 HAL_TIM_OC_StartChannel() 才能打开主输出,否则 PA8 和 PB13 一直无波形。

第二,启动 PWM 分两步。 先调用两次 HAL_TIM_OC_StartChannel() 启动 CH1 和 CH1N 两个通道,再调用 HAL_TIM_Start() 启动计数器。两步都完成后 PWM 才真正输出。

死区时间是互补 PWM 的核心参数,由 DTS 采样时钟和 Dead Time 寄存器的值共同决定。本实验取 DTS = 144 MHz、Dead Time = 72,得到 500 ns 的死区。如需调整,可按公式 死区 = Dead Time / DTS 反推。

版权声明:

Copyright by [email]ai4mcu@qq.com[/email] 2026 Crated:2026-10

image.png
赞 收藏 评论0 发布时间:2026-10-21 13:37

举报

0个回答

所属标签

相似技术帖

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版