☰
STC8H高级PWM实战:互补输出、死区控制与多通道配置详解
2026/9/28 16:25:29 网站建设 项目流程

1. 为什么STC8H的高级PWM值得单独拿出来讲

如果你之前只用过STC89C52或者STC15系列做过PWM调光、调速,第一次接触STC8H的高级PWM模块,大概率会有点懵。STC8H系列里带“高级PWM”外设的型号(比如STC8H8K64U、STC8H1K28等),它的PWM模块跟传统单片机那种“一个定时器配一个比较寄存器”完全不是一个量级的东西。它更像是一台小型电机控制专用外设:支持互补输出、死区插入、多通道同步、刹车保护、编码器接口,甚至能做三相无刷电机的六路驱动。

我最初拿STC8H做的是一个直流有刷电机的调速项目,本来想着随便配个PWM就完事了,结果发现客户要求半桥驱动上下管不能直通,必须加死区。用普通PWM靠软件延时插死区,波形抖得厉害,后来换成高级PWM的硬件死区,波形干净得像示波器自带的标准信号。从那以后,我基本把STC8H的高级PWM当成了一个独立课题来研究。

这篇内容适合三类人看:第一类是从STC15/STC8A迁移过来,发现寄存器对不上的老玩家;第二类是做电机驱动、电源变换、逆变器,需要互补和死区的工程师;第三类是想用一颗几块钱的国产MCU替代专用PWM控制器做多路输出的朋友。我会把互补输出、死区控制、多通道配置这三块拆开讲透,寄存器怎么算、坑在哪里、示波器上看到什么波形算对,全部按我实际调试的过程来写。

2. 高级PWM模块的整体架构与设计思路

2.1 它和普通PWM到底差在哪

普通PWM的本质就是一个计数器加一个比较值,计数值小于比较值时输出高,大于时输出低。STC8H的高级PWM保留了这套逻辑,但把它扩展成了一个“时基+多通道+互补+死区+刹车”的完整系统。你可以把它想象成一个交响乐团:时基单元是指挥,负责打拍子;各个PWM通道是乐手,按指挥的节奏演奏;互补输出是成对的乐手,一个出声另一个就必须闭嘴;死区就是两个乐手切换时留出的那一点点静默时间,防止声音撞在一起。

具体到寄存器层面,STC8H高级PWM的核心模块包括:

  • PWMA时基单元:包含ARR(自动重装载寄存器)、CNTR(计数器)、PSCR(预分频器),决定PWM的频率。
  • PWMA通道单元:每个通道有CCR(捕获比较寄存器)、CCMR(模式寄存器)、CCER(使能寄存器),决定占空比和输出极性。
  • 死区发生器:DTR寄存器,为互补通道对插入死区时间。
  • 刹车单元:BRK寄存器,外部故障信号触发时快速封锁输出。
  • 自动重装载预装载:ARPE位,决定ARR写入是立即生效还是等更新事件。

这套架构跟STM32的高级定时器TIM1/TIM8非常相似,但STC8H的寄存器命名和位定义有自己的风格,不能直接照搬STM32的代码。我见过有人把STM32的PWM初始化代码改个名字就往STC8H上套,结果波形死活出不来,原因就是STC8H的使能位和极性控制位分布不一样。

2.2 为什么选高级PWM而不是软件模拟

有人会问,我用定时器中断翻转IO口也能出PWM,为什么要用高级PWM?这个问题我在早期也纠结过。软件模拟PWM的优点是灵活,任何IO都能用;缺点是占CPU、频率上不去、占空比精度受中断响应影响。我实测过,用STC8H的24MHz主频,定时器中断翻转IO,PWM频率做到10kHz时CPU已经占了将近40%的时间,而且占空比最小步进只能到1/100左右,再细就抖了。

高级PWM是纯硬件输出,CPU只需要初始化一次,之后完全不参与。频率可以做到几百kHz,占空比精度取决于ARR的位数,16位ARR能做到1/65536的调节精度。更重要的是,互补输出和死区控制是硬件完成的,软件模拟根本做不到纳秒级的死区精度。所以只要你的项目涉及半桥、全桥、三相逆变,高级PWM是唯一靠谱的选择。

2.3 多通道配置的两种典型场景

STC8H的高级PWM通常有4个通道(PWMA的PWM1P/PWM1N到PWM4P/PWM4N),每个通道都可以独立配置。多通道配置有两种典型用法:

第一种是多路独立输出,比如同时控制四路LED调光或者四路风扇调速,每个通道频率相同但占空比独立。这种场景下四个通道共用一个时基,ARR决定频率,各自的CCR决定占空比。

第二种是互补对输出,比如H桥的两个上管和下管,或者三相逆变器的三对桥臂。这种场景下通道1P和1N是一对,2P和2N是一对,硬件自动保证两者不会同时导通,并且可以插入死区。

我做的项目里,三相无刷电机驱动用的是第二种,三对互补通道加中心对齐模式,波形对称性很好。而一个多路温控风扇的项目用的是第一种,四路独立PWM,频率统一设在25kHz,避开了风扇的音频噪声频段。

3. 互补输出与死区控制的核心细节

3.1 互补输出的硬件逻辑

互补输出的意思很简单:PWM1P输出高的时候,PWM1N输出低;PWM1P输出低的时候,PWM1N输出高。这两个信号在硬件上是互斥的,不会同时为高。但“互斥”不等于“安全”,因为MOS管关断需要时间,如果PWM1P刚变低、PWM1N立刻变高,上管还没完全关断下管就导通了,电源直接短路,这就是常说的“直通”或“ Shoot-through”。

STC8H的互补输出通过CCER寄存器里的CC1P和CC1NP位分别控制PWM1P和PWM1N的极性。注意这两个位是独立控制的,不是简单的取反关系。你可以把两个都设成高有效,也可以设成一个高有效一个低有效,具体取决于你的驱动电路是高端驱动还是低端驱动。我一般用IR2104这类半桥驱动芯片,输入信号是高有效,所以PWM1P和PWM1N都设成高有效,芯片内部自己会做互斥。

这里有个容易踩的坑:STC8H的互补输出使能位是CCER寄存器里的CC1E和CC1NE。CC1E控制PWM1P,CC1NE控制PWM1N。如果你只使能了CC1E没使能CC1NE,那PWM1N根本不会输出,示波器上只有一路波形。我刚开始调的时候以为互补是自动的,结果找了半天才发现是使能位没开。

3.2 死区时间的计算与寄存器配置

死区时间是互补输出里最关键的参数。太短了起不到防直通的作用,太长了会损失有效占空比、增加谐波失真。死区时间的具体数值取决于MOS管的关断时间和驱动电路的延时,一般取100ns到1us之间。我用的IRF3205加IR2104组合,实测死区设在300ns左右比较合适。

STC8H的死区时间由DTR寄存器配置,它把死区时间分成几个档位,通过DTCFG位选择。具体计算公式是:

死区时间 = (DTCFG值 + 1) × Tpwm_clk

其中Tpwm_clk是PWM时钟周期。假设PWM时钟是24MHz,那一个时钟周期约41.7ns。如果DTCFG设为6,死区时间就是(6+1)×41.7≈292ns,接近300ns。

但这里有个细节:STC8H的DTR寄存器还分死区预分频,可以进一步放大死区时间。如果你的PWM时钟很快但需要较长的死区,就要用预分频。我一般先把PWM时钟设在24MHz,然后根据需要的死区时间反推DTCFG值。比如需要500ns死区,500/41.7≈12,DTCFG设11即可。

实测的时候一定要用示波器看两路波形的死区,不能只看代码算出来的值。因为驱动芯片本身也有延时,PCB走线也有延时,最终到MOS管栅极的死区可能跟寄存器算出来的差几十纳秒。我习惯在示波器上同时抓PWM1P和PWM1N,看两个下降沿和上升沿之间的时间差,调到既不直通又不明显损失占空比为止。

3.3 死区插入的时机与波形分析

死区插入的时机有两种:一种是在互补对的切换沿都插入,另一种是只在其中一个沿插入。STC8H默认是在两个沿都插入死区,这样最安全。但有些应用里,比如LLC谐振变换器,可能只需要在特定沿插入死区,这时候就要仔细看寄存器的手册说明。

我用示波器抓过一组典型的互补波形:PWM1P从高变低后,PWM1N延迟约300ns才从低变高;PWM1N从高变低后,PWM1P也延迟约300ns才从低变高。两路波形在切换点都有一个明显的“死区平台”,两路都是低电平。这个平台就是死区,它保证了上下管不会同时导通。

如果示波器上看到两路波形有重叠,也就是一路还没完全变低另一路就开始变高,那说明死区没生效或者太短。这时候要检查DTR寄存器是否真的写进去了,以及CCER的互补使能位是否打开。我遇到过一次死区不生效的情况,查了半天发现是DTR寄存器写在了PWM使能之后,而STC8H要求死区配置必须在PWM输出使能之前完成。这个顺序问题手册里写得不显眼,但实际调试中很容易忽略。

3.4 刹车保护与故障封锁

刹车功能是高级PWM的另一个安全特性。当外部故障信号(比如过流比较器输出)触发时,刹车单元会立即封锁PWM输出,让所有通道进入安全状态。STC8H的刹车输入可以映射到特定引脚,触发后PWM输出被强制拉低或拉高,具体取决于寄存器配置。

我在电机驱动项目里一定会用刹车功能。过流信号从比较器出来接到刹车引脚,一旦电流超过阈值,PWM立刻封锁,比软件中断快得多。软件中断从触发到执行封锁至少要几个微秒,而硬件刹车是纳秒级的。对于MOS管来说,几微秒的过流就可能炸管,所以硬件刹车是保命的东西。

刹车触发后,PWM输出会被封锁,但计数器还在跑。要恢复输出,需要清除刹车标志并重新使能输出。我一般会在刹车中断里做故障记录,然后等故障排除后手动恢复。注意刹车标志的清除顺序,先清标志再重新使能,否则可能清不掉。

4. 多通道配置的实操过程

4.1 时基单元的参数计算

多通道配置的第一步是确定时基参数。STC8H高级PWM的PWM频率计算公式是:

PWM频率 = 系统时钟 / (PSCR预分频 + 1) / (ARR + 1)

假设系统时钟24MHz,我想要20kHz的PWM频率,ARR设成16位最大值65535,那预分频就是:

24000000 / 20000 / 65536 ≈ 0.018

这个值小于1,说明不需要预分频,PSCR设0即可。然后反算ARR:

ARR = 24000000 / 20000 - 1 = 1199

所以PSCR=0,ARR=1199,PWM频率正好20kHz。ARR是16位的,1199远小于65535,说明占空比精度还有很大余量。如果我要更高的占空比精度,可以把PSCR设大,让ARR更大。比如PSCR设11,ARR就是(24000000/12/20000)-1=99,精度反而降低了。所以预分频和ARR的取舍要看具体需求:要频率准就用小预分频,要占空比细就用大ARR。

我一般习惯把ARR设在1000到4000之间,这样占空比调节比较直观,比如ARR=1199时,CCR=600就是50%占空比。如果ARR太大,算占空比的时候容易算错。

4.2 四个通道的独立占空比配置

时基配好之后,四个通道的占空比分别由CCR1到CCR4决定。每个通道的CCR可以独立写,互不影响。但要注意CCR的预装载功能:如果CCMR里的OCxPE位使能了预装载,那CCR写入后不会立即生效,要等更新事件(UEV)才生效。这样做的目的是防止PWM周期中间改占空比导致波形不完整。

我一般会打开预装载,然后在更新中断里统一更新四个CCR。这样四个通道的占空比在同一时刻生效,不会出现某个通道先变另一个通道后变的情况。对于多路LED调光这种应用,人眼对同步性不敏感,不开预装载也没事。但对于三相电机驱动,三个通道的占空比必须同步更新,否则会产生转矩脉动。

配置四个通道的代码大概长这样:

// 使能PWM1P到PWM4P输出 PWMA_CCER1 = 0x55; // 通道1和2使能,高有效 PWMA_CCER2 = 0x55; // 通道3和4使能,高有效 // 设置四个通道的占空比 PWMA_CCR1 = 300; // 通道1占空比25% PWMA_CCR2 = 600; // 通道2占空比50% PWMA_CCR3 = 900; // 通道3占空比75% PWMA_CCR4 = 1199; // 通道4占空比100% // 使能预装载 PWMA_CCMR1 |= 0x08; PWMA_CCMR2 |= 0x08; PWMA_CCMR3 |= 0x08; PWMA_CCMR4 |= 0x08; // 使能主输出 PWMA_BKR = 0x80;

这段代码里,CCER1和CCER2的0x55是二进制01010101,表示通道1到4的PWMxP都使能且高有效。BKR的0x80是使能主输出,这个位不置1的话所有通道都不会输出。我见过有人配了半天通道就是不输出,最后发现是BKR没开。

4.3 互补通道对的配置差异

如果要用互补输出,配置就跟独立输出不一样了。以通道1为例,需要同时使能CC1E和CC1NE,并且配置死区。代码大概是这样:

// 通道1互补输出 PWMA_CCER1 |= 0x01; // 使能PWM1P PWMA_CCER1 |= 0x04; // 使能PWM1N PWMA_CCER1 &= ~0x02; // PWM1P高有效 PWMA_CCER1 &= ~0x08; // PWM1N高有效 // 死区配置 PWMA_DTR = 0x06; // 死区时间约292ns PWMA_BKR = 0x80; // 使能主输出

注意CCER1的位定义:bit0是CC1E,bit1是CC1P,bit2是CC1NE,bit3是CC1NP。所以0x01是使能PWM1P,0x04是使能PWM1N,0x02和0x08分别是极性位,清零表示高有效。

互补输出和独立输出不能混用在同一个通道上。如果你把通道1配成互补,通道2配成独立,这是可以的,因为每个通道的CCER位是独立的。但时基是共用的,所以所有通道的频率必须相同。如果需要不同频率的PWM,就得用不同的定时器,STC8H的高级PWM只有一个时基,做不到多频率输出。

4.4 中心对齐模式与边沿对齐模式的选择

STC8H高级PWM支持边沿对齐和中心对齐两种模式。边沿对齐就是计数器从0数到ARR然后归零,PWM波形是左对齐的。中心对齐是计数器从0数到ARR再数回0,PWM波形是对称的。

边沿对齐适合普通调光调速,配置简单,频率计算直观。中心对齐适合电机驱动和逆变器,因为对称波形的高次谐波更少,对电机的噪声和损耗都更小。我用中心对齐做三相驱动时,相电压波形明显比边沿对齐干净,电流纹波也小一些。

中心对齐模式下,PWM频率的计算公式变成:

PWM频率 = 系统时钟 / (PSCR + 1) / (2 × ARR)

因为计数器要上下数两次才是一个完整周期。所以同样的ARR,中心对齐的频率是边沿对齐的一半。配置的时候要注意这个2倍关系,别算错了频率。

中心对齐模式通过CR1寄存器的CMS位选择。CMS=00是边沿对齐,CMS=01是中心对齐模式1,CMS=10是中心对齐模式2,CMS=11是中心对齐模式3。模式1/2/3的区别在于比较中断的触发时机,一般用模式1就行。

5. 常见问题与排查技巧实录

5.1 PWM没有输出的排查顺序

PWM配好了但示波器上没波形,这是最常见的问题。我总结了一个排查顺序,按这个顺序查基本能解决90%的情况:

排查项检查内容常见问题
主输出使能BKR寄存器的MOE位忘记置1,所有通道都不输出
通道使能CCER的CCxE位只配了CCMR没配CCER
引脚映射端口配置寄存器PWM引脚没设成复用功能
时基使能CR1的CEN位计数器没启动
预装载CCMR的OCxPE位预装载开了但没触发更新
刹车状态BKR的刹车标志刹车触发后没清除

我遇到最多的是两个:一个是BKR的MOE没开,一个是引脚没设成复用。STC8H的PWM输出引脚默认是普通IO,必须通过PxM1/PxM0寄存器设成复用推挽输出。比如PWM1P在P1.0,就要把P1M1的bit0清零、P1M0的bit0置1。这个配置在手册的端口章节,不在PWM章节,所以容易漏。

5.2 死区不生效或波形异常的排查

死区不生效的表现是两路互补波形有重叠,或者死区时间跟设定值差很多。排查思路:

先确认DTR寄存器是否真的写进去了。STC8H的DTR寄存器有写保护,需要先解锁才能写。我一开始不知道,直接写DTR发现没反应,后来查手册才发现要先写0x55和0xAA到保护寄存器。

再确认死区配置的顺序。STC8H要求死区配置在PWM输出使能之前完成,如果先使能了输出再配死区,死区可能不生效。我现在的习惯是初始化的时候先配时基、再配通道、再配死区、最后开主输出,这个顺序最稳。

最后用示波器实测死区时间。如果实测值跟计算值差很多,可能是PWM时钟跟预期不一致。检查PSCR和系统时钟频率,确认PWM时钟到底是多少。我有一次系统时钟设的24MHz,但PSCR算错了,实际PWM时钟只有12MHz,死区时间翻倍了。

5.3 多通道同步更新的问题

四个通道独立输出时,如果占空比在运行中改变,可能会出现通道间不同步。比如通道1的CCR先写,通道2的CCR后写,两个通道的占空比变化不在同一时刻。对于LED调光无所谓,但对于电机驱动就会有问题。

解决办法是打开CCR预装载,然后在更新中断里统一更新。更新中断由UEV事件触发,发生在计数器归零(边沿对齐)或上下数到中间(中心对齐)的时候。在中断里一次性写四个CCR,下一个周期四个通道同时生效。

void PWMA_ISR() interrupt 26 { if (PWMA_SR1 & 0x01) { // 更新中断 PWMA_SR1 &= ~0x01; // 清标志 PWMA_CCR1 = new_duty1; PWMA_CCR2 = new_duty2; PWMA_CCR3 = new_duty3; PWMA_CCR4 = new_duty4; } }

注意中断号,STC8H的PWMA中断号是26,不是STM32的TIM1_UP。这个中断号在头文件里有定义,用的时候直接写数字或者用宏都行。

5.4 刹车误触发与恢复

刹车功能虽然安全,但也容易误触发。如果刹车引脚悬空或者受到干扰,可能会随机触发,导致PWM突然封锁。我在一个电机项目里遇到过刹车随机触发的问题,查了半天发现是刹车引脚没有上拉,环境噪声耦合进来触发了刹车。

解决办法是给刹车引脚加一个上拉电阻,或者在寄存器里使能内部上拉。另外刹车触发后要检查刹车标志,确认是真实故障还是误触发。如果是误触发,可以在软件里做滤波,连续检测到多次刹车才认为是真实故障。

刹车恢复的流程是:先排除故障源,然后清除刹车标志,再重新使能主输出。注意清除刹车标志和重新使能的顺序,先清标志再使能,否则可能清不掉。我一般会在刹车中断里置一个故障标志,主循环检测到故障标志后做处理,处理完再恢复PWM。

5.5 高频PWM下的MOS管发热问题

PWM频率越高,MOS管的开关损耗越大,发热越严重。我做过一个测试,同样的电机和负载,PWM频率从10kHz升到20kHz,MOS管温度从40度升到65度。所以PWM频率不是越高越好,要权衡噪声和损耗。

对于有刷电机,10kHz到16kHz比较合适,高于16kHz人耳听不到啸叫,但损耗也可接受。对于无刷电机,20kHz到30kHz比较常见,因为无刷电机的电感小,电流纹波大,需要更高的频率来平滑电流。但频率越高,死区时间占的比例越大,有效占空比损失越多。我一般会把死区设在200ns到500ns之间,根据MOS管的开关速度调整。

另外MOS管的栅极驱动电阻也会影响发热。电阻太大,开关速度慢,开关损耗大;电阻太小,开关速度快,但可能引起振荡。我一般先用10欧姆试,然后用示波器看栅极波形,如果上升沿有振荡就加大电阻,如果上升沿太慢就减小电阻。

6. 从寄存器到波形的完整调试记录

6.1 一个三相驱动的实际配置案例

我拿一个实际的三相无刷电机驱动项目来完整走一遍配置流程。硬件是STC8H8K64U,系统时钟24MHz,MOS管用IRF3205,驱动芯片IR2104,目标PWM频率20kHz,中心对齐模式,死区300ns。

第一步,配置时基。中心对齐模式下,PWM频率=24MHz/(PSCR+1)/(2×ARR)。设PSCR=0,ARR=599,则频率=24M/1/1198≈20.03kHz,接近20kHz。ARR=599意味着占空比精度是1/600,对于电机驱动够用了。

第二步,配置三个互补通道。通道1、2、3分别对应三相的U、V、W。每个通道都要使能P和N,配置死区。CCER1配置通道1和2,CCER2配置通道3。

PWMA_CCER1 = 0x11; // 通道1和2的P使能,高有效 PWMA_CCER1 |= 0x44; // 通道1和2的N使能,高有效 PWMA_CCER2 = 0x01; // 通道3的P使能 PWMA_CCER2 |= 0x04; // 通道3的N使能

第三步,配置死区。DTR寄存器设0x06,死区约292ns。

第四步,配置中心对齐模式。CR1寄存器的CMS位设01。

PWMA_CR1 |= 0x20; // CMS=01,中心对齐模式1

第五步,使能主输出和计数器。

PWMA_BKR = 0x80; // 使能主输出 PWMA_CR1 |= 0x01; // 启动计数器

第六步,在更新中断里更新三个CCR,实现SVPWM算法。

这套配置跑下来,示波器上三对互补波形很干净,死区稳定在300ns左右,电机运转平稳,电流纹波比边沿对齐模式小很多。

6.2 示波器实测波形分析

调试的时候我习惯用示波器抓几组关键波形。第一组是单对互补波形,看死区是否正常。第二组是三对波形的相位关系,看是否相差120度。第三组是相电压波形,看中心对齐的对称性。

单对互补波形上,PWM1P和PWM1N在切换点都有死区平台,两路都是低电平。死区时间用光标测量,跟设定值误差在10%以内算正常。如果误差太大,检查PWM时钟和DTR配置。

三对波形的相位关系,通道1超前通道2约120度,通道2超前通道3约120度。如果相位不对,检查CCR的初始值和更新时机。SVPWM算法里三个CCR是实时计算的,相位关系由算法保证。

相电压波形是PWM1P减去PWM1N的等效波形,中心对齐模式下应该是对称的梯形波。如果波形不对称,检查CMS模式是否配错,或者ARR值是否在上下数的时候被改了。

6.3 性能实测与优化方向

这套配置在24MHz主频下,PWM分辨率是1/600,频率20kHz,死区300ns。实测电机空载电流约0.3A,满载电流约2A,MOS管温度在满载运行10分钟后约55度,可以接受。

优化方向有几个:一是提高PWM频率到30kHz,进一步降低电流纹波,但MOS管温度会上升;二是减小死区到200ns,提高有效占空比,但需要确认MOS管不会直通;三是用DMA自动更新CCR,减轻CPU负担,但STC8H的DMA能不能触发PWM更新我还没试过,手册里没明确写。

我个人经验是,对于大多数中小功率电机驱动,20kHz频率加300ns死区是一个比较稳妥的起点。先在这个参数下把系统跑通,然后再根据实测的电流纹波和MOS管温度做微调。不要一上来就追求高频和窄死区,那样容易炸管。

7. 几个容易忽略的寄存器细节

7.1 预装载的双缓冲机制

STC8H的ARR和CCR都有预装载功能,但两者的预装载行为不一样。ARR的预装载由ARPE位控制,CCR的预装载由OCxPE位控制。ARPE使能后,写ARR不会立即生效,要等更新事件。OCxPE使能后,写CCR也不会立即生效,也要等更新事件。

这个双缓冲机制的好处是防止PWM周期中间改参数导致波形异常。但坏处是如果你不知道这个机制,改了ARR发现频率没变,会以为寄存器坏了。我一开始就踩过这个坑,后来养成了习惯:改ARR或CCR之后手动触发一次更新事件,或者等下一个更新中断。

手动触发更新事件的方法是置CR1的UG位,硬件会自动清零。这样不用等计数器跑完一个周期,参数立即生效。调试的时候很方便。

7.2 输出极性与驱动电路的匹配

PWM输出的极性要跟驱动电路匹配。IR2104这类半桥驱动芯片,输入高电平导通上管,输入低电平导通下管。所以PWM1P和PWM1N都设成高有效,芯片内部会做互斥。但有些驱动芯片是低有效的,比如某些光耦隔离驱动,输入低电平才导通。这时候就要把极性位设成低有效。

极性配错的后果是上下管同时导通,直接炸管。所以第一次上电的时候一定要用示波器看波形,确认极性对了再接功率级。我一般会先用低压小电流测试,确认波形没问题再上高压。

7.3 中断标志的清除时机

PWM中断有多个标志位:更新中断、捕获中断、刹车中断等。每个标志位都要在中断服务程序里手动清除,否则会反复进中断。清除方法是写1到对应的标志位,不是写0。这个跟很多单片机不一样,STC8H的中断标志是写1清零。

我见过有人写0清标志,结果中断一直进,程序跑飞了。所以清标志的时候一定要看手册,确认是写1清零还是写0清零。STC8H的PWM中断标志是写1清零,这个要记住。

8. 写在最后的实操体会

STC8H的高级PWM模块功能很强,但寄存器比较多,刚开始接触容易晕。我的建议是不要一上来就配三相六路,先从单路PWM输出开始,把时基和通道配通,看到波形了再加互补,再加死区,再加多通道。一步一步来,每步都用示波器验证,这样出了问题容易定位。

另外,STC8H的官方例程里有一些PWM的配置代码,但例程往往只覆盖基本功能,互补和死区的例子不多。我当初是照着STM32的高级定时器思路去理解STC8H的寄存器,发现很多概念是相通的,只是位定义和寄存器名字不同。如果你有STM32的基础,迁移过来会快很多。

最后分享一个我常用的调试技巧:把PWM输出接到一个RC低通滤波器上,用万用表测电容上的电压,这个电压就是PWM的平均值,也就是占空比乘以电源电压。这样不用示波器也能快速验证占空比对不对。RC的时间常数要远大于PWM周期,比如PWM频率20kHz,RC取10k加1uF,时间常数10ms,远大于50us的周期,滤波效果很好。这个方法在我没有示波器的时候帮了大忙,简单粗暴但有效。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询