STM32 定时器(互补输出+刹车)

以下是一个基于STM32F103标准库实现的PWM互补输出+刹车功能的完整代码,使用高级定时器TIM1(支持互补输出和刹车功能)。代码包含详细注释和配置说明,适用于电机控制等场景。


🛠 完整代码实现(STM32F103标准库)

cpp 复制代码
#include "stm32f10x.h"

// 引脚定义
#define PWM_CH1_PIN     GPIO_Pin_8     // PA8: TIM1_CH1
#define PWM_CH1N_PIN    GPIO_Pin_13    // PB13: TIM1_CH1N
#define BRAKE_PIN       GPIO_Pin_12    // PB12: TIM1_BKIN

// 定时器配置参数
#define PWM_FREQ        20000          // PWM频率20kHz
#define DEAD_TIME       0x36           // 死区时间≈500ns (72MHz时钟)
#define DUTY_CYCLE      50             // 初始占空比50%

void TIM1_PWM_Brake_Init(void) 
{
    GPIO_InitTypeDef GPIO_InitStruct;
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStruct;
    TIM_OCInitTypeDef TIM_OCInitStruct;
    TIM_BDTRInitTypeDef TIM_BDTRStruct;

    // 1. 使能时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | 
                           RCC_APB2Periph_AFIO | RCC_APB2Periph_TIM1, ENABLE);

    // 2. 配置GPIO
    // PA8 (TIM1_CH1): 复用推挽输出
    GPIO_InitStruct.GPIO_Pin = PWM_CH1_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOA, &GPIO_InitStruct);

    // PB13 (TIM1_CH1N): 互补通道复用推挽输出
    GPIO_InitStruct.GPIO_Pin = PWM_CH1N_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    // PB12 (TIM1_BKIN): 浮空输入(刹车信号)
    GPIO_InitStruct.GPIO_Pin = BRAKE_PIN;
    GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    // 3. 定时器时基配置(20kHz PWM)
    TIM_TimeBaseStruct.TIM_Period = (SystemCoreClock / PWM_FREQ) - 1; // 自动重装载值
    TIM_TimeBaseStruct.TIM_Prescaler = 0;      // 无分频
    TIM_TimeBaseStruct.TIM_ClockDivision = 0;
    TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
    TIM_TimeBaseInit(TIM1, &TIM_TimeBaseStruct);

    // 4. PWM通道配置(互补输出)
    TIM_OCInitStruct.TIM_OCMode = TIM_OCMode_PWM1;        // PWM模式1
    TIM_OCInitStruct.TIM_OutputState = TIM_OutputState_Enable;
    TIM_OCInitStruct.TIM_OutputNState = TIM_OutputNState_Enable; // 互补通道使能
    TIM_OCInitStruct.TIM_OCPolarity = TIM_OCPolarity_High;       // 主通道高电平有效
    TIM_OCInitStruct.TIM_OCNPolarity = TIM_OCNPolarity_Low;    // 互补通道高低平有效
    TIM_OCInitStruct.TIM_OCIdleState = TIM_OCIdleState_Reset;    // 空闲时主通道低电平
    TIM_OCInitStruct.TIM_OCNIdleState = TIM_OCNIdleState_Set;  // 空闲时互补通道高电平
    TIM_OCInitStruct.TIM_Pulse = (TIM_TimeBaseStruct.TIM_Period * DUTY_CYCLE) / 100; // 占空比
    TIM_OC1Init(TIM1, &TIM_OCInitStruct);

    // 5. 死区与刹车配置
    TIM_BDTRStruct.TIM_OSSRState = TIM_OSSRState_Enable;
    TIM_BDTRStruct.TIM_OSSIState = TIM_OSSIState_Enable;
    TIM_BDTRStruct.TIM_LOCKLevel = TIM_LOCKLevel_1;
    TIM_BDTRStruct.TIM_DeadTime = DEAD_TIME;            // 死区时间
    TIM_BDTRStruct.TIM_Break = TIM_Break_Enable;        // 刹车功能使能
    TIM_BDTRStruct.TIM_BreakPolarity = TIM_BreakPolarity_High; // 高电平触发刹车
    TIM_BDTRStruct.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; // 自动恢复输出
    TIM_BDTRConfig(TIM1, &TIM_BDTRStruct);

    // 6. 启动定时器与PWM输出
    TIM_CtrlPWMOutputs(TIM1, ENABLE); // 关键!使能主输出
    TIM_Cmd(TIM1, ENABLE);             // 启动TIM1
}

int main(void) 
{

    // 初始化PWM互补输出+刹车
    TIM1_PWM_Brake_Init();

    while (1) 
    {
        // 主循环中可动态调整占空比
        // TIM_SetCompare1(TIM1, new_value); 
    }
}

🔍 关键配置说明

1. ​GPIO配置
  • 主通道(TIM1_CH1)​:PA8,复用推挽输出
  • 互补通道(TIM1_CH1N)​:PB13,复用推挽输出
  • 刹车引脚(TIM1_BKIN)​:PB12,浮空输入(高电平触发刹车)
2. ​PWM互补输出
  • 模式PWM1(CNT < CCRx时输出有效电平)
  • 极性:主/互补通道均高电平有效
  • 空闲状态 :刹车时强制拉低(TIM_OCIdleState_Reset
3. ​死区时间
  • 计算公式DeadTime = (DTG[7:0] + 1) * T_dts
    • 示例中0x36对应约500ns(72MHz时钟)
  • 作用:防止主/互补信号同时导通导致短路
4. ​刹车功能
  • 触发条件:PB12输入高电平时立即刹车
  • 行为
    • 主/互补通道输出空闲状态(低电平)
    • 自动恢复:当刹车信号消失后自动恢复PWM输出(TIM_AutomaticOutput_Enable

⚠️ 注意事项

  1. 时钟配置
    • 代码默认使用72MHz系统时钟,需在SystemInit()中配置PLL。
  2. 死区时间调整
    • 根据实际驱动电路调整DEAD_TIME值(参考数据手册DTG寄存器计算)。
  3. 占空比动态修改
    • while(1)中调用TIM_SetCompare1(TIM1, value)实时修改占空比。
  4. 调试工具
    • 用示波器观察PA8(主通道)和PB13(互补通道)的相位差和死区时间。
相关推荐
hateregiste2 小时前
国产数据库FlashDB移植到国产MCU GD32F103RC上的几点经验总结
单片机·嵌入式硬件
QQ5286211244 小时前
STM32F2/F4系列单片机解密和芯片应用介绍
stm32·单片机·嵌入式硬件·程序·pcb抄板
2006yu5 小时前
从零开始学习单片机17
单片机·嵌入式硬件·学习
智能物联实验室6 小时前
如何解决网关断网后时间不再统计的问题?无RTC子设备如何打通主网关的时间同步功能?
嵌入式硬件·网关·实时音视频·智能硬件
kaikaile19958 小时前
GY-BMP280压强传感器完整工程stm32控制
stm32·单片机·嵌入式硬件
智能物联实验室8 小时前
屏随人动+视觉魔方+多样主题+智能留言,涂鸦Wukong AI 2.0助力打造爆款带屏云台相机
图像处理·人工智能·嵌入式硬件·数码相机·智能硬件
lingzhilab13 小时前
零知开源——基于STM32F407VET6实现ULN2003AN驱动28BYJ-48步进电机控制系统
stm32·单片机·嵌入式硬件
JasmineX-114 小时前
直流电机驱动与TB6612
c语言·stm32·单片机·嵌入式硬件
hahaha60161 天前
模拟电路中什么时候适合使用电流传递信号,什么时候合适使用电压传递信号
stm32·单片机·嵌入式硬件