STM8S PWM互补输出加死区刹车配置指南

STM8S PWM互补输出加死区刹车配置指南

STM8S系列微控制器的高级控制定时器(TIM1)支持互补PWM输出、可编程死区时间和刹车功能,非常适合电机驱动、电源转换等应用。本文将详细介绍STM8S的PWM互补输出配置方法,包括死区时间和刹车功能的实现。

一、TIM1高级定时器概述

STM8S的TIM1定时器具有以下关键特性:

二、互补输出与死区时间原理

1. 互补输出结构

TIM1_CH1 ────▶ 主输出
               │
               ├───▶ CH1N (互补输出)
               │
TIM1_CH2 ────▶ 主输出
               │
               ├───▶ CH2N (互补输出)
               │
TIM1_CH3 ────▶ 主输出
               │
               ├───▶ CH3N (互补输出)

2. 死区时间作用

死区时间是在互补输出切换时插入的保护间隔,防止上下管同时导通造成短路:

理想波形:    ┌─────┐      ┌─────┐
           ──┘     └──────┘     └──

实际波形:    ┌──┐  ┌──┐      ┌──┐  ┌──┐
           ──┘  └──┘  └──────┘  └──┘  └──
               ↑    ↑       ↑    ↑
             死区  死区     死区  死区

3. 刹车功能

当检测到故障信号(如过流)时,刹车电路立即关闭所有PWM输出,保护功率器件。

三、寄存器配置详解

1. 关键寄存器

寄存器 功能描述 地址偏移
TIM1_CR1 控制寄存器1 0x00
TIM1_CR2 控制寄存器2 0x01
TIM1_SMCR 从模式控制寄存器 0x02
TIM1_ETR 外部触发寄存器 0x03
TIM1_IER 中断使能寄存器 0x04
TIM1_SR1 状态寄存器1 0x05
TIM1_SR2 状态寄存器2 0x06
TIM1_EGR 事件产生寄存器 0x07
TIM1_CCMR1 捕获/比较模式寄存器1 0x08
TIM1_CCMR2 捕获/比较模式寄存器2 0x09
TIM1_CCMR3 捕获/比较模式寄存器3 0x0A
TIM1_CCMR4 捕获/比较模式寄存器4 0x0B
TIM1_CCER1 捕获/比较使能寄存器1 0x0C
TIM1_CCER2 捕获/比较使能寄存器2 0x0D
TIM1_CNTRH 计数器高8位 0x0E
TIM1_CNTRL 计数器低8位 0x0F
TIM1_PSCRH 预分频器高8位 0x10
TIM1_PSCRL 预分频器低8位 0x11
TIM1_ARRH 自动重装载高8位 0x12
TIM1_ARRL 自动重装载低8位 0x13
TIM1_CCR1H 捕获/比较1高8位 0x14
TIM1_CCR1L 捕获/比较1低8位 0x15
TIM1_CCR2H 捕获/比较2高8位 0x16
TIM1_CCR2L 捕获/比较2低8位 0x17
TIM1_CCR3H 捕获/比较3高8位 0x18
TIM1_CCR3L 捕获/比较3低8位 0x19
TIM1_DTR 死区时间寄存器 0x1C
TIM1_BKR 刹车寄存器 0x1D
TIM1_OISR 输出空闲状态寄存器 0x1E

2. 死区时间计算

死区时间由TIM1_DTR寄存器控制:

死区时间 = (DTR[7:0] × t_TIM1_CLK)

其中t_TIM1_CLK是TIM1时钟周期

DTR[7:0] 死区时间 (t_TIM1_CLK单位)
0x00 0
0x01 1
0x02 2
0xFF 255

四、配置步骤与代码实现

1. 系统时钟配置

#include "stm8s.h"

void CLK_Config(void) {
    CLK_DeInit();
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz内部时钟
    CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);
}

2. GPIO配置

void GPIO_Config(void) {
    // 主输出通道
    GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST); // CH1 -> PC1
    GPIO_Init(GPIOC, GPIO_PIN_2, GPIO_MODE_OUT_PP_LOW_FAST); // CH2 -> PC2
    GPIO_Init(GPIOC, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST); // CH3 -> PC3
    
    // 互补输出通道
    GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST); // CH1N -> PC4
    GPIO_Init(GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST); // CH2N -> PC5
    GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST); // CH3N -> PC6
    
    // 刹车输入 (BKIN) - 使用PA4
    GPIO_Init(GPIOA, GPIO_PIN_4, GPIO_MODE_IN_FL_NO_IT);
}

3. TIM1 PWM互补输出配置

void TIM1_PWM_Complementary_Init(void) {
    // 1. 基本配置
    TIM1_TimeBaseInit(159, TIM1_COUNTERMODE_UP, 999, 0); 
    // 预分频159 (16MHz/(159+1)=100kHz)
    // 自动重载值999 (周期=10ms, 频率=100Hz)
    
    // 2. 通道1配置 (PWM模式1)
    TIM1_OC1Init(TIM1_OCMODE_PWM1, 
                 TIM1_OUTPUTSTATE_ENABLE, 
                 TIM1_OUTPUTNSTATE_ENABLE, 
                 500,  // 占空比50%
                 TIM1_OCPOLARITY_HIGH, 
                 TIM1_OCNPOLARITY_HIGH, 
                 TIM1_OCIDLESTATE_RESET, 
                 TIM1_OCNIDLESTATE_RESET);
    
    // 3. 通道2配置 (PWM模式1)
    TIM1_OC2Init(TIM1_OCMODE_PWM1, 
                 TIM1_OUTPUTSTATE_ENABLE, 
                 TIM1_OUTPUTNSTATE_ENABLE, 
                 300,  // 占空比30%
                 TIM1_OCPOLARITY_HIGH, 
                 TIM1_OCNPOLARITY_HIGH, 
                 TIM1_OCIDLESTATE_RESET, 
                 TIM1_OCNIDLESTATE_RESET);
    
    // 4. 通道3配置 (PWM模式1)
    TIM1_OC3Init(TIM1_OCMODE_PWM1, 
                 TIM1_OUTPUTSTATE_ENABLE, 
                 TIM1_OUTPUTNSTATE_ENABLE, 
                 700,  // 占空比70%
                 TIM1_OCPOLARITY_HIGH, 
                 TIM1_OCNPOLARITY_HIGH, 
                 TIM1_OCIDLESTATE_RESET, 
                 TIM1_OCNIDLESTATE_RESET);
    
    // 5. 死区时间配置 (2μs)
    // 系统时钟16MHz, TIM1时钟100kHz, 1个计数=10μs
    // 2μs ≈ 0.2个计数, 取DTR=2 (实际死区=2×10μs=20μs)
    TIM1_DeadTimeConfig(TIM1_DEADTIME_2); 
    // 或使用直接赋值: TIM1->DTR = 0x02;
    
    // 6. 刹车配置
    TIM1_BreakConfig(TIM1_BREAK_ENABLE, 
                    TIM1_BREAKPOLARITY_LOW, 
                    TIM1_AUTOMATICOUTPUT_ENABLE);
    
    // 7. 使能主输出
    TIM1_CtrlPWMOutputs(ENABLE);
    
    // 8. 启动定时器
    TIM1_Cmd(ENABLE);
}

4. 完整示例代码

#include "stm8s.h"

// 系统时钟配置
void CLK_Config(void) {
    CLK_DeInit();
    CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1); // 16MHz
    CLK_PeripheralClockConfig(CLK_PERIPHERAL_TIMER1, ENABLE);
}

// GPIO配置
void GPIO_Config(void) {
    // 主输出
    GPIO_Init(GPIOC, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST); // CH1
    GPIO_Init(GPIOC, GPIO_PIN_2, GPIO_MODE_OUT_PP_LOW_FAST); // CH2
    GPIO_Init(GPIOC, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST); // CH3
    
    // 互补输出
    GPIO_Init(GPIOC, GPIO_PIN_4, GPIO_MODE_OUT_PP_LOW_FAST); // CH1N
    GPIO_Init(GPIOC, GPIO_PIN_5, GPIO_MODE_OUT_PP_LOW_FAST); // CH2N
    GPIO_Init(GPIOC, GPIO_PIN_6, GPIO_MODE_OUT_PP_LOW_FAST); // CH3N
    
    // 刹车输入
    GPIO_Init(GPIOA, GPIO_PIN_4, GPIO_MODE_IN_FL_NO_IT);
}

// TIM1 PWM互补输出配置
void TIM1_PWM_Complementary_Init(void) {
    // 时基配置: 预分频159 (100kHz), 向上计数, ARR=999 (100Hz)
    TIM1_TimeBaseInit(159, TIM1_COUNTERMODE_UP, 999, 0);
    
    // 通道1: PWM模式1, 50%占空比
    TIM1_OC1Init(TIM1_OCMODE_PWM1, 
                 TIM1_OUTPUTSTATE_ENABLE, 
                 TIM1_OUTPUTNSTATE_ENABLE, 
                 500, 
                 TIM1_OCPOLARITY_HIGH, 
                 TIM1_OCNPOLARITY_HIGH, 
                 TIM1_OCIDLESTATE_RESET, 
                 TIM1_OCNIDLESTATE_RESET);
    
    // 通道2: PWM模式1, 30%占空比
    TIM1_OC2Init(TIM1_OCMODE_PWM1, 
                 TIM1_OUTPUTSTATE_ENABLE, 
                 TIM1_OUTPUTNSTATE_ENABLE, 
                 300, 
                 TIM1_OCPOLARITY_HIGH, 
                 TIM1_OCNPOLARITY_HIGH, 
                 TIM1_OCIDLESTATE_RESET, 
                 TIM1_OCNIDLESTATE_RESET);
    
    // 通道3: PWM模式1, 70%占空比
    TIM1_OC3Init(TIM1_OCMODE_PWM1, 
                 TIM1_OUTPUTSTATE_ENABLE, 
                 TIM1_OUTPUTNSTATE_ENABLE, 
                 700, 
                 TIM1_OCPOLARITY_HIGH, 
                 TIM1_OCNPOLARITY_HIGH, 
                 TIM1_OCIDLESTATE_RESET, 
                 TIM1_OCNIDLESTATE_RESET);
    
    // 死区时间: 2μs (DTR=2)
    TIM1->DTR = 0x02;  // 直接设置DTR寄存器
    
    // 刹车配置: 使能, 低电平有效, 自动输出使能
    TIM1->BKR = (uint8_t)0x8C;  // BKE=1, BKP=0, AOE=1, MOE=1
    
    // 使能主输出
    TIM1_CtrlPWMOutputs(ENABLE);
    
    // 启动定时器
    TIM1_Cmd(ENABLE);
}

// 主函数
void main(void) {
    CLK_Config();
    GPIO_Config();
    TIM1_PWM_Complementary_Init();
    
    while(1) {
        // 主循环中可动态更新占空比
        // 例如: TIM1_SetCompare1(600);  // 修改通道1占空比
    }
}

参考代码 stm8s PWM互补输出加死区刹车 www.youwenfan.com/contentcns/183126.html

五、死区时间与刹车功能详解

1. 死区时间配置

// 方法1: 使用库函数
TIM1_DeadTimeConfig(TIM1_DEADTIME_2); // 预定义值

// 方法2: 直接设置DTR寄存器
TIM1->DTR = 0x0F; // 15个计数周期的死区时间

预定义死区时间选项:

宏定义 死区时间 (t_TIM1_CLK)
TIM1_DEADTIME_0 0
TIM1_DEADTIME_1 1
TIM1_DEADTIME_2 2
TIM1_DEADTIME_15 15
TIM1_DEADTIME_64 64
TIM1_DEADTIME_128 128
TIM1_DEADTIME_192 192
TIM1_DEADTIME_254 254

2. 刹车功能配置

// 使能刹车功能
TIM1_BreakConfig(
    TIM1_BREAK_ENABLE,       // 使能刹车
    TIM1_BREAKPOLARITY_LOW,  // 低电平有效
    TIM1_AUTOMATICOUTPUT_ENABLE // 自动恢复输出
);

// 手动触发刹车
TIM1->BKR |= TIM1_BKR_BKE;  // 置位BKE位

刹车控制位:

六、应用场景与注意事项

1. 典型应用场景

2. 设计注意事项

  1. 死区时间选择

    • 过小:可能导致上下管直通
    • 过大:增加开关损耗,影响效率
    • 经验公式:死区时间 ≈ 功率管关断延迟 + 驱动电路延迟
  2. PCB布局

    • 功率回路尽量短
    • 模拟地/数字地分开
    • 去耦电容靠近MCU
  3. 热管理

    • 功率器件加散热片
    • 避免连续满负荷运行
    • 监测结温
  4. 保护功能

    • 过流保护(OCP)
    • 过压保护(OVP)
    • 欠压锁定(UVLO)
    • 过热保护(OTP)

七、调试与故障排除

1. 常见问题排查表

问题现象 可能原因 解决方案
无PWM输出 主输出未使能 检查TIM1_CtrlPWMOutputs(ENABLE)
  刹车激活 检查BKIN引脚状态,清除BKE位
  通道未使能 检查CCER寄存器的CCxE/CCxNE位
占空比不正确 ARR值错误 检查自动重装载值
  CCR值错误 检查捕获/比较寄存器
  预分频错误 检查PSC寄存器
死区时间异常 DTR值错误 检查死区时间寄存器
  时钟配置错误 检查系统时钟和预分频
互补输出不同步 配置不一致 检查所有通道的极性设置
  死区时间过大 减小DTR值
刹车不生效 配置错误 检查BKR寄存器配置
  引脚未连接 检查BKIN引脚连接

2. 示波器测量要点

  1. 使用双通道同时测量主输出和互补输出
  2. 观察死区时间是否符合预期
  3. 检查上升/下降时间
  4. 验证刹车功能响应时间
  5. 测量开关损耗和效率

八、高级应用

1. 中心对齐模式

// 配置为中心对齐模式1
TIM1->CR1 |= TIM1_CR1_CMS_CENTERALIGNED1;

中心对齐模式特点:

2. 故障处理回调函数

// 刹车中断服务函数
INTERRUPT_HANDLER(TIM1_BRK_IRQHandler, 6) {
    // 清除中断标志
    TIM1->SR1 &= ~TIM1_SR1_BIF;
    
    // 执行保护动作
    ShutdownSystem();
    
    // 记录故障信息
    LogFaultEvent();
}

3. 动态死区调整

// 根据温度调整死区时间
void AdjustDeadTimeByTemp(int8_t temp) {
    if(temp > 85) {
        TIM1->DTR = 0x0F; // 高温时增大死区
    } else {
        TIM1->DTR = 0x05; // 正常死区
    }
}

专注于matlab/simulink,电子电路,编程