尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

STM8S105高级定时器TIM1互补PWM输出配置与死区时间设置实战

STM8S105高级定时器TIM1互补PWM输出配置与死区时间设置实战 1. 项目概述从基础PWM到互补输出的跨越玩过STM8或者STM32的朋友对PWM脉冲宽度调制肯定不陌生。点个灯、驱动个舵机、让电机转起来PWM都是最基础也是最核心的技能。但当你需要驱动一个半桥或者全桥电路比如控制直流有刷电机的正反转或者驱动一个简单的逆变器时单路的PWM就力不从心了。这时候你需要的是两路在逻辑上完全相反、并且中间最好还能插入一段“安全空白区”的波形——这就是互补PWM输出。我最近在折腾一个基于STM8S105的小型电机驱动板核心需求就是用单片机直接产生带死区的互补PWM来驱动一个半桥MOS管。听起来好像高级定时器的标配功能但STM8的资源比STM32要紧张得多玩法也更“原始”一些需要更仔细地配置定时器的每一个寄存器。网上资料虽多但要么是STM32的要么只讲基础PWM关于STM8互补输出特别是如何精确配置死区时间讲得透彻的并不多。踩过几个坑后我把整个配置流程、原理和调试心得梳理出来如果你也在STM8上搞电机控制、电源转换或者任何需要互补信号的应用这篇笔记应该能帮你省下不少时间。简单说这个项目就是利用STM8S系列单片机以105为例的高级控制定时器1TIM1配置其两个通道如CH1和CH1N输出一对中心对齐或边沿对齐的互补PWM波并加入可编程的死区时间确保功率开关管不会因为同时导通而短路烧毁。整个过程不依赖CubeMXSTM8的CubeMX生态远不如STM32直接操作寄存器理解更深刻。2. 核心需求与硬件资源解析2.1 为什么需要互补PWM与死区时间想象一下控制一个半桥电路上管和下管是两个MOSFET。理想的开关逻辑是上管开时下管关下管开时上管关。如果用两个普通的GPIO输出反相的逻辑似乎也能实现。但在实际硬件中MOS管的开启和关闭都需要时间即上升时间和下降时间。如果“关断”命令和“开启”命令同时或几乎同时发出可能会出现一个管子还没完全关断另一个管子已经开始导通的情况这会在电源和地之间形成一条低阻通路产生巨大的瞬间电流也就是致命的“直通”或“穿通”现象结果往往是MOS管和驱动芯片一起炸掉。为了解决这个问题我们需要在两路互补的PWM信号之间插入一段两者都为低电平对于高电平有效的驱动而言的“空白区”这就是死区时间。在这段时间里确保一个管子已经完全关断后另一个管子才被允许开启。死区时间是硬件安全的关键通常需要根据你所使用的MOS管或IGBT的开关特性来微调一般在几十纳秒到几微秒之间。2.2 STM8S105的定时器家底STM8S105的资源对于8位机来说算是丰厚的但与STM32相比就需要精打细算。它有几个定时器TIM116位高级控制定时器。这是实现互补PWM输出的唯一选择。它功能最强支持向上、向下、中心对齐三种计数模式。多达4个独立的通道每个通道都可以配置为PWM输出OCx。每个通道都对应一个互补输出OCxN。内置可编程的死区时间发生器。刹车Break功能用于紧急关断PWM输出。TIM2/TIM316位通用定时器。它们有PWM输出功能但没有互补输出和死区发生器。适合做普通的单路PWM。TIM48位基本定时器。主要用于时基、延时。所以我们的目标很明确攻克TIM1。重点吃透它的计数模式、输出比较模式、互补输出使能和死区时间配置这几个关键部分。2.3 引脚分配与硬件连接以TIM1的通道1CH1和它的互补通道1CH1N为例在STM8S105K4T6这款常见的LQFP32封装芯片上TIM1_CH1对应PC1。TIM1_CH1N对应PC2。在你的原理图和PCB布局时务必把这两个引脚连接到你的半桥/全桥驱动芯片的输入脚上例如IR2104、IR2110的HIN和LIN。驱动芯片的输出再连接MOS管的栅极。切记单片机引脚不能直接驱动功率MOS管必须经过驱动芯片。同时驱动芯片的电源、自举电容等外围电路要严格按照数据手册设计这是硬件稳定的基础。3. 定时器1TIM1互补PWM配置详解这里我们以生成一个频率为10kHz死区时间为1us的互补PWM为例。假设系统主频fMASTER为16MHzHSI。3.1 定时器时钟与预分频设置首先TIM1的时钟来源于系统主频。我们需要计算计数频率。确定PWM频率fPWM10kHz 10000 Hz。选择计数模式对于电机控制中心对齐模式中央对齐PWM更常用因为它能减少谐波但理解原理可以从边沿对齐模式开始。这里我们先讲边沿对齐向上计数。计算自动重装载值ARR在边沿对齐模式下PWM频率fPWM fCK_PSC / (ARR 1)。其中fCK_PSC是经过预分频器后的定时器时钟。我们先设定预分频器PSC 0即不分频fCK_PSC fMASTER 16MHz。那么ARR fCK_PSC / fPWM - 1 16,000,000 / 10,000 - 1 1600 - 1 1599。ARR必须是0-65535之间的整数。1599完全合理。计算死区时间对应的计数值死区时间DT 1us 0.000001 s。定时器计数周期T_cnt 1 / fCK_PSC 1/16MHz 0.0625us。死区时间需要的计数个数DT_CNT DT / T_cnt 1us / 0.0625us 16。STM8 TIM1的死区时间发生器DTG有一个特定的编码格式我们需要将DT_CNT16转换成寄存器值。根据数据手册公式为当0 DT_CNT 127时DTG[7:0] DT_CNT。所以这里DTG 16。注意这里为了计算方便假设了PSC0。在实际项目中如果fMASTER很高计算出的ARR可能很小比如小于100导致PWM分辨率即占空比调节精度很低。这时可以适当增大PSC值提高ARR从而获得更高的分辨率。但要注意PSC增大会降低计数频率可能影响死区时间的最小步进。需要权衡。3.2 关键寄存器配置步骤代码级解析下面用类似C的伪代码展示核心配置流程我会穿插在IAR for STM8环境下的实操要点。#include stm8s.h void TIM1_PWM_Complementary_Init(void) { // 1. 使能TIM1的外设时钟在STM8中默认是开启的但好的习惯是确认一下 CLK-PCKENR1 | CLK_PCKENR1_TIM1; // 使能TIM1时钟 // 2. 配置GPIO引脚为推挽输出高速模式以驱动外部电路 GPIOC-DDR | GPIO_PIN_1 | GPIO_PIN_2; // PC1, PC2 设置为输出模式 GPIOC-CR1 | GPIO_PIN_1 | GPIO_PIN_2; // 推挽输出模式 GPIOC-CR2 | GPIO_PIN_1 | GPIO_PIN_2; // 输出速度高达10MHz // 3. 配置TIM1时基单元 TIM1-PSCRH 0; // 预分频器高位 (PSC0) TIM1-PSCRL 0; // 预分频器低位 TIM1-ARRH (1599 8) 0xFF; // 自动重装载值高位 TIM1-ARRL 1599 0xFF; // 自动重装载值低位 // 4. 配置通道1为PWM模式1向上计数时CNTCCR1为有效电平 // TIM1_CCMR1: OC1M[2:0] 110 (PWM模式1) TIM1-CCMR1 (TIM1-CCMR1 ~TIM1_CCMR_OCM) | (0x6 4); // 设置输出极性CH1高电平有效CH1N低电平有效这是互补的常见设置 // TIM1_CCER1: CC1P0 (高有效), CC1NP1 (低有效) TIM1-CCER1 (TIM1-CCER1 ~(TIM1_CCER1_CC1P | TIM1_CCER1_CC1NP)) | TIM1_CCER1_CC1NP; // 使能通道1主输出和互补输出 TIM1-CCER1 | TIM1_CCER1_CC1E | TIM1_CCER1_CC1NE; // 5. 配置死区时间 // 根据前面计算DTG 16。直接写入死区时间寄存器。 // TIM1_DTR: DTG[7:0] 16 TIM1-DTR 16; // 1us死区 // 6. 配置刹车和死区寄存器BDTR这是使能互补输出的关键 // MOE: 主输出使能必须置1才能输出PWM。 // OSSI: 输出空闲状态控制我们设为0关闭状态下输出无效电平。 // OSSR: 运行模式下输出空闲状态控制根据需求设置。 // 这里我们先简单使能MOE。 TIM1-BKR TIM1_BKR_MOE; // 7. 设置初始占空比通过捕获/比较寄存器CCR1 // 假设初始占空比为50%则 CCR1 ARR * 50% 1599 * 0.5 799.5 ≈ 800 TIM1-CCR1H (800 8) 0xFF; TIM1-CCR1L 800 0xFF; // 8. 启动定时器向上计数模式 TIM1-CR1 | TIM1_CR1_CEN; // 使能计数器 }关键点解析与避坑指南GPIO配置互补PWM输出引脚必须配置为推挽输出CR1置1并且为了快速响应建议开启高速模式CR2置1。如果配置为开漏输出波形幅度会不对。输出极性CC1P和CC1NP位控制极性。CC1P0表示CH1高电平有效即占空比期间输出高。CC1NP1表示CH1N低电平有效。这样配置后在死区时间以外CH1和CH1N的信号永远是反相的。这个组合可以根据你的驱动芯片逻辑需求调整。主输出使能MOE这是最大的一个坑TIM1_BKR寄存器中的MOE位不置1即使前面配置全对引脚上也没有任何波形输出。它相当于互补PWM输出的总开关。死区时间寄存器DTR直接写入计算好的值即可。STM8的死区时间发生器是硬件实现的插入的死区时间非常精确不受软件干扰。中心对齐模式如果需要中心对齐PWM只需修改TIM1_CR1寄存器的CMS位。例如设置为0x2中央对齐模式1先向下后向上计数。在中心对齐模式下PWM频率计算公式变为fPWM fCK_PSC / (2 * ARR)计算ARR时需要注意。4. 调试与波形观测实战代码写好了下载到芯片里怎么知道对不对呢示波器是必不可少的工具。4.1 连接与测量将示波器的两个探头分别连接到PC1CH1和PC2CH1N共地端接板子的地。触发模式可以设为边沿触发触发源选CH1。预期看到的波形两个频率同为10kHz的方波。两个波形相位相反。当CH1为高电平时CH1N为低电平反之亦然。在CH1的下降沿到CH1N的上升沿之间以及CH1N的下降沿到CH1的上升沿之间会有一段两个通道都为低电平假设你设置CH1N低有效的区域这就是死区时间。用示波器的光标功能测量这段间隔应该接近你设置的1us由于时钟精度和测量误差可能在0.9us-1.1us之间。4.2 常见问题与排查技巧完全没有波形输出检查MOE位十有八九是TIM1_BKR寄存器中的MOE位没有置1。用调试器单步执行或者直接在初始化后添加一句TIM1-BKR | TIM1_BKR_MOE;。检查GPIO配置确认DDR、CR1、CR2寄存器是否正确配置为输出模式。可以用一个简单的GPIO翻转程序先测试一下这两个引脚是否能正常输出高低电平。检查定时器使能确认TIM1_CR1的CEN位已置1。检查引脚复用STM8的引脚复用功能相对简单但也要确认没有其他外设比如别的定时器或串口占用了PC1和PC2。只有一路有波形另一路没有或常高/常低检查互补输出使能位确认TIM1_CCER1寄存器中的CC1NE位对于CH1N是否置1。检查输出极性位检查CC1P和CC1NP的设置是否符合预期。如果CC1NP设成了0高有效那么CH1N的波形就会和CH1同相这显然不对。可以尝试在运行时修改这两个位观察波形变化。检查死区时间是否过大如果你不小心把死区时间设置得比PWM的有效高电平时间还长那么互补通道可能永远没有机会输出有效电平看起来就像常低。检查DTR寄存器的值重新计算。死区时间测量值与设置值不符时钟源确认确认你的系统主频fMASTER是否真的是16MHz。如果用了外部晶振HSE或者分频了内部时钟HSIfCK_PSC会变需要重新计算。DTG计算公式死区时间DT (DTG[7:0]) * T_dtg。其中T_dtg可能是T_ck定时器时钟周期或其倍数具体取决于DTG[7:5]的值。我前面举例是DTG128的情况公式最简单。如果死区时间较长需要参考数据手册中DTG[7:5]对应的乘数表。务必仔细阅读参考手册中“TIM1 deadtime generation”这一节。PWM频率不对ARR和PSC计算错误这是最常见的原因。再核对一遍公式fPWM fMASTER / ((PSC1) * (ARR1))边沿对齐向上计数。中心对齐模式公式用错中心对齐模式下fPWM fMASTER / ((PSC1) * 2 * ARR)。系统时钟树配置错误在main函数初始化时是否配置了正确的时钟源和分频用示波器测量一个已知的定时器中断翻转的引脚可以反推出实际的系统时钟频率。5. 高级应用与优化思路基础功能调通后可以玩一些更高级的。5.1 动态调整占空比与死区在实际应用中比如电机调速需要动态改变PWM占空比。这很简单只需在运行中修改TIM1_CCR1寄存器的值即可。为了防止修改过程中产生毛刺对于STM8通常可以直接写因为16位寄存器写入是原子操作高8位和低8位分开写入但硬件有缓冲。更稳妥的做法是在PWM周期的一个特定点如下一个更新事件进行更新这可以通过使能预装载寄存器TIM1_CR1的ARPE位和设置TIM1_CCMR1中的OC1PE位来实现。动态调整死区时间比较少见但也可以实现直接修改TIM1_DTR寄存器即可。注意死区时间的改变可能会在下一个PWM周期生效具体时机需查手册。5.2 刹车Break功能的使用TIM1的刹车功能是一个重要的安全特性。你可以将一个外部信号比如过流检测电路的输出连接到特定的刹车输入引脚如TIM1_BKIN。当刹车信号有效时硬件会自动将PWM输出强制置为一个预设的安全状态通常都是无效电平比如CH1拉低CH1N拉高并且产生中断。这为系统提供了硬件级的保护响应速度远快于软件检测。配置刹车功能涉及TIM1_BKR刹车寄存器和TIM1_IER中断使能寄存器。需要设置刹车输入极性、刹车后输出状态通过OSSR和OSSI位控制以及使能刹车中断。这是一个值得深入研究的保护机制。5.3 从边沿对齐切换到中心对齐对于电机驱动和某些电源应用中心对齐PWM可以减少电流纹波和开关损耗。切换起来并不复杂停止定时器CEN0。修改TIM1_CR1寄存器的CMS[1:0]位。例如设置为0x2中央对齐模式1计数器先向下计数到0再向上计数到ARR如此反复。重新计算ARR值。因为频率公式变了。可能需要调整CR1中的DIR位方向位硬件在中心对齐模式下会自动管理方向通常不用管。重新使能定时器CEN1。用示波器观察中心对齐PWM的波形特点是每个PWM脉冲关于计数周期的中心点对称。折腾STM8的互补PWM输出是一个从“会用定时器”到“理解定时器内核”的很好跳板。它迫使你去读那些平时可能跳过的寄存器描述去计算时钟和计数关系去思考硬件安全机制。当你在示波器上第一次清晰地看到那两段完美的、中间带着一小段安全间隔的互补方波时那种成就感是调通一个LED呼吸灯无法比拟的。这份笔记里的代码和参数都是经过实际板子验证的你可以直接拿去作为骨架修改。最重要的是理解每个配置步骤背后的意图这样无论换到STM8的哪个型号或者未来升级到STM32的复杂定时器你都能快速抓住核心。
返回列表