如何使用STM32F429 定时器 TIM1 输出 PWM
STM32F429 的。
·
STM32F429 定时器 TIM1 输出 PWM 配置教程(基于标准库)
0、前言

1、时钟
一、TIM1 输出 PWM 原理
1. 定时器核心架构
STM32F429 的 TIM1 是高级定时器,支持向上/向下计数模式、互补 PWM 输出、死区插入和刹车功能,核心模块包括:
- 时基单元:由计数器(CNT)、自动重装载寄存器(ARR)、预分频器(PSC)组成,决定 PWM 频率/周期。
- 输出比较单元:通过比较计数器(CNT)值与捕获比较寄存器(CCR),控制输出电平翻转,改变CCR可实现占空比调节。在每个周期内,CNT从0开始计数到ARR(向上计数模式)。CCR的值小于ARR,大于0.
- 刹车和死区单元(BDTR):确保互补 PWM 输出时上下桥臂不会直通,提升功率电路安全性。
2. PWM 生成逻辑
- 频率计算:
f = TIM1输入时钟频率 / (PSC + 1) x (ARR + 1)
其中PSC是预分频值,ARR是自动重装载值(代码中为TIM1_PERIOD - 1)。
TIM1的输入时钟频率:挂载在APB2总线,STM32F429芯片的APB2总线最高频率为90MHz。TIM1输入频率一般会是APB2总线的2倍频:180MHz.
STM32F429的时钟系统详解请点此查看另一篇文章 - 占空比控制:
当计数器值小于等于 CCR 时输出有效电平(取决于PWM模式和极性配置),大于 CCR 时输出无效电平,有效电平持续时间决定占空比。改变CCR可实现占空比调节。
二、关键寄存器解析
1. 时基寄存器(TIMx_CR1、TIMx_PSC、TIMx_ARR)
- TIMx_CR1:配置计数模式(向上/向下)、使能预装载等。
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数 - TIMx_PSC:预分频器,将系统时钟分频为定时器时钟。
TIM_TimeBaseStructure.TIM_Prescaler = TIM1_PRESCALER - 1; // 预分频值 - TIMx_ARR:自动重装载值,决定 PWM 周期/频率。
TIM_TimeBaseStructure.TIM_Period = TIM1_PERIOD - 1; // 周期寄存器值
2. 输出比较寄存器(TIMx_CCMR1、TIMx_CCRx)
- TIMx_CCMR1:设置 PWM 模式(模式1/模式2)、输出极性等。 当CNT小于CCR时,PWM模式1输出有效电平,PWM2输出无效电平。有效电平指可以驱动功率电路MOS管或者IGBT导通的电平。输出极性即为配置有效电平为高电平(TIM_OCPolarity_High)或者低电平(TIM_OCPolarity_Low)。
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // 选择PWM模式 - TIMx_CCRx:比较值寄存器,决定占空比。
TIM_OCInitStructure.TIM_Pulse = TIM1_PERIOD / 2; // 50%占空比
3. 刹车和死区寄存器(TIMx_BDTR,Dead time generator)
- TIMx_BDTR:配置死区时间、刹车功能、输出使能等。
TIM_BDTRInitStructure.TIM_DeadTime = DEAD_TIME_VALUE; // 死区时间配置
三、硬件准备与 GPIO 配置(GPIO_Config 函数解析)
1. 引脚映射
| 引脚 | TIM1 功能 | 配置说明 |
|---|---|---|
| PE8 | TIM1_CH1N(互补通道1) | 复用 AF1,推挽输出,上拉 |
| PE9 | TIM1_CH1(主通道1) | 复用 AF1,推挽输出,上拉 |
| PE10 | TIM1_CH2N(互补通道2) | 复用 AF1,推挽输出,上拉 |
| PE11 | TIM1_CH2(主通道2) | 复用 AF1,推挽输出,上拉 |
2. 代码实现
void GPIO_Config(void) {
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOC, ENABLE); // 使能GPIO时钟
// 配置PE8-PE11为TIM1复用功能
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF; // 复用功能模式
GPIO_InitStructure.GPIO_AF = GPIO_AF_TIM1; // 映射到TIM1(AF1)
GPIO_Init(GPIOE, &GPIO_InitStructure);
}
四、TIM1 配置步骤(TIM1_Config 函数解析)
1. 时基单元初始化(决定 PWM 频率)
TIM_TimeBaseStructure.TIM_Period = TIM1_PERIOD - 1; // 自动重装载值(周期)
TIM_TimeBaseStructure.TIM_Prescaler = TIM1_PRESCALER - 1; // 预分频系数(0表示不分频)
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; // 向上计数模式
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
- 频率计算示例:若系统时钟为 168MHz,
TIM1_PRESCALER=1(预分频值0),TIM1_PERIOD=2000,则频率为168MHz / (1*2000) = 84kHz。
2. 输出比较配置(通道1与通道2)
通道1(主通道 + 互补通道)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1; // PWM模式1
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable; // 使能主输出
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable; // 使能互补输出
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High; // 主通道高有效
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_High; // 互补通道高有效(与主通道同相)
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
- PWM模式1特性:向上计数时,计数器≥CCR时输出有效电平,适用于需要后期高电平的场景。
通道2(配置为PWM模式2)
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2; // PWM模式2
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
- PWM模式2特性:向上计数时,计数器<CCR时输出有效电平,与通道1形成互补逻辑。
3. 死区与刹车配置(功率电路安全核心)
TIM_BDTRInitStructure.TIM_DeadTime = DEAD_TIME_VALUE; // 死区时间(单位:定时器周期)
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; // 使能自动输出
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
- 死区时间作用:避免上下桥臂同时导通,
DEAD_TIME_VALUE需根据功率器件开关速度调整(示例值为最小安全死区)。
4. 预装载与使能配置
TIM_ARRPreloadConfig(TIM1, ENABLE); // 使能自动重装载预装载
TIM_CtrlPWMOutputs(TIM1, ENABLE); // 高级定时器必须调用,开启PWM输出
TIM_Cmd(TIM1, ENABLE); // 启动定时器
五、波形关系与极性配置
1. 通道逻辑关系
| 通道 | 配置参数 | 输出波形特性 |
|---|---|---|
| CH1 | PWM模式1,高有效 | 计数器≥CCR时输出高电平 |
| CH1N | 互补通道,高有效 | 与CH1反相(通过极性配置实现) |
| CH2 | PWM模式2,高有效 | 计数器<CCR时输出高电平 |
| CH2N | 互补通道,高有效 | 与CH2反相,与CH1同相 |
2. 极性与模式配合
- 主通道极性(
TIM_OCPolarity_High):有效电平为高电平。 - 互补通道极性(
TIM_OCNPolarity_High):与主通道同相,需根据电路需求调整(如全桥驱动需反相时设为Low)。
六、应用场景与调试建议
1. 典型应用
- 全桥驱动电路:CH1/CH1N 控制上桥臂,CH2/CH2N 控制下桥臂,死区时间防止直通。
- 电机调速:通过修改
TIMx_CCRx(TIM_OCInitStructure.TIM_Pulse)调整占空比。
2. 调试工具
- 逻辑分析仪:抓取引脚波形,验证占空比和死区时间。
- 示波器:观测高频噪声,检查 GPIO 复用配置是否正确(AF1 对应 TIM1)。
3. 注意事项
- 死区时间计算:需根据公式
死区时间 = DEAD_TIME_VALUE × 定时器周期,确保不小于功率器件的开关延迟。 - 预分频值范围:
TIM1_PRESCALER最大为 65536,避免频率过低导致电机抖动。 - 极性匹配:若输出波形异常,检查
TIM_OCPolarity与TIM_OCNPolarity是否与硬件逻辑一致。
七、完整代码框架
#include "stm32f4xx.h"
// 宏定义
#define TIM1_PERIOD 2000 // 自动重装载值(决定周期)
#define TIM1_PRESCALER 1 // 预分频系数(1=不分频)
#define DEAD_TIME_VALUE 5 // 死区时间(定时器周期数)
// 核心函数
void GPIO_Config(void) { /* 见下文 */ }
void TIM1_Config(void) { /* 见下文 */ }
int main(void) {
GPIO_Config();
TIM1_Config();
while (1);
}
/**
* @brief 配置GPIO:PE8,PE9,PE10,PE11用于TIM1通道及互补输出;PC0,PC1用于PWM使能
*/
void GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/* 开启GPIOE和GPIOC时钟 */
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOE | RCC_AHB1Periph_GPIOC, ENABLE);
/* 配置PE8-PE11: AF mode, AF1(TIM1) */
GPIO_InitStructure.GPIO_Pin =
GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10 | GPIO_Pin_11;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_UP;
GPIO_Init(GPIOE, &GPIO_InitStructure);
/* 选择复用功能AF1: TIM1 */
GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_TIM1); // TIM1_CH1N
GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_TIM1); // TIM1_CH1
GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_TIM1); // TIM1_CH2N
GPIO_PinAFConfig(GPIOE, GPIO_PinSource11, GPIO_AF_TIM1); // TIM1_CH2
/* 配置PC0和PC1为普通推挽输出,用于PWM通道硬件电路的输出使能 */
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;
GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/**
* @brief 配置TIM1及其PWM输出:含通道1、2及其互补输出、死区插入
*/
void TIM1_Config(void)
{
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
TIM_OCInitTypeDef TIM_OCInitStructure;
TIM_BDTRInitTypeDef TIM_BDTRInitStructure;
/* 开启TIM1时钟 */
RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE);
/* 定时器基础配置 */
TIM_TimeBaseStructure.TIM_Period = TIM1_PERIOD - 1;
TIM_TimeBaseStructure.TIM_Prescaler = TIM1_PRESCALER - 1; // 预分频系数
TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1;
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;
TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStructure);
/* 配置TIM1 CH1 和 CH2 输出PWM */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM1;
TIM_OCInitStructure.TIM_OutputState = TIM_OutputState_Enable;
TIM_OCInitStructure.TIM_OutputNState = TIM_OutputNState_Enable;
TIM_OCInitStructure.TIM_Pulse = TIM1_PERIOD / 2; // 初始占空比50%
TIM_OCInitStructure.TIM_OCPolarity = TIM_OCPolarity_High;
TIM_OCInitStructure.TIM_OCNPolarity = TIM_OCNPolarity_Low;
TIM_OCInitStructure.TIM_OCIdleState = TIM_OCIdleState_Reset;
TIM_OCInitStructure.TIM_OCNIdleState = TIM_OCIdleState_Reset;
/* 配置通道1 */
TIM_OC1Init(TIM1, &TIM_OCInitStructure);
TIM_OC1PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* 配置通道2 */
TIM_OCInitStructure.TIM_OCMode = TIM_OCMode_PWM2;
TIM_OC2Init(TIM1, &TIM_OCInitStructure);
TIM_OC2PreloadConfig(TIM1, TIM_OCPreload_Enable);
/* 死区、刹车以及PWM输出使能配置 */
// 离散模式输出保持状态
TIM_BDTRInitStructure.TIM_OSSRState = TIM_OSSRState_Enable;
// 切换非重载时保持输出状态
TIM_BDTRInitStructure.TIM_OSSIState = TIM_OSSIState_Enable;
TIM_BDTRInitStructure.TIM_LOCKLevel = TIM_LOCKLevel_OFF;
// 死区时间:根据定时器时钟周期设定
TIM_BDTRInitStructure.TIM_DeadTime = DEAD_TIME_VALUE;
// 禁用刹车
TIM_BDTRInitStructure.TIM_Break = TIM_Break_Disable;
TIM_BDTRInitStructure.TIM_BreakPolarity = TIM_BreakPolarity_High;
TIM_BDTRInitStructure.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable;
TIM_BDTRConfig(TIM1, &TIM_BDTRInitStructure);
/* 使能TIM1的预装载寄存器 */
TIM_ARRPreloadConfig(TIM1, ENABLE);
/* 使能定时器 */
TIM_Cmd(TIM1, ENABLE);
/* 高级定时器必须调用此函数开启PWM输出 */
TIM_CtrlPWMOutputs(TIM1, ENABLE);
}
通过以上步骤,可实现 TIM1 输出具有互补关系的 PWM 波形,适用于需要高精度控制的功率驱动场景。配置时需结合硬件参数调整死区时间和占空比,确保系统稳定性和安全性。
更多推荐



所有评论(0)