
简介基于STM32F103C8T6单片机实现的三相SPWM逆变电源设计资料包面向电力电子、嵌入式开发及硬件设计学习者涵盖从原理图、PCB到软件源码的完整工程链。包内包含用Altium Designer打开的电路图与PCB文件、Keil5工程源码含stm32f10x_tim.c等定时器与ADC配置、PDF版电路图、元件清单Excel、硬件结构框图和程序流程图文档以及参考论文和实物图便于对照理解三相逆变桥驱动、SPWM波生成和采样反馈等关键环节。整个压缩包共385个文件约30.42MB主要文件类型包括C语言源码、头文件、Altium Designer工程文件pcbdoc/schdoc、PDF文档、Word说明及编译生成的hex、axf文件等目录结构清晰适合完整复盘或二次开发。目前已有4344人学习下载。资料从方案设计、硬件布局到软件调试均有覆盖可直接用于毕业设计、课程项目或逆变电源产品预研省去从零搭建工程和查阅芯片手册的耗时。1. 为什么是STM32F103C8T6做三相SPWM逆变电源这份资料解决什么问题收到这份“基于STM32F103C8T6单片机设计的三相SPWM逆变电源AD原理图PCB软件源码文档资料.zip”第一件事不是解压双击而是先问一句它到底帮你省掉了哪段路。这类项目的本质是用一片64KB Flash、20KB RAM的Cortex-M3芯片输出三组带死区的互补SPWM脉冲驱动三相全桥逆变器再经LC滤波得到三相正弦交流电。它覆盖了从AD原理图、PCB布局到Keil软件源码和说明文档的完整闭环适合做UPS、电机驱动、实验室三相电源的入门原型。值不值得照抄取决于你是否搞懂了背后的选型逻辑、死区时间、载波频率这几个要命参数。2. 三相SPWM生成原理与定时器选型查表法、引脚映射与死区参数2.1 SPWM的两种生成方式软件查表法与硬件PWM比较SPWM的本质是“正弦波与三角载波比较”输出脉宽按正弦规律变化的PWM脉冲。常见做法有两种一种是在定时器中断里实时算正弦值并更新占空比另一种是提前算好一张正弦表中断里只做查表赋值。实时计算占用CPU太多而且三角函数在Cortex-M3上跑起来开销不小查表法用空间换时间中断里只有三次数组读取和三次寄存器赋值20kHz中断频率下对72MHz主频来说毫无压力。查表法的另一个好处是波形可预期。载波20kHz、基波50Hz时载波比正好是400每个工频周期有400个PWM周期。把正弦表做成400点每个PWM周期推进一点基波频率精确等于50Hz。如果表点数和PWM周期数对不上波形会引入次谐波这是SPWM里最容易忽略的坑。下面用Python生成三相独立的400点CCR表直接输出成C数组import math FS 20000 # PWM载波频率20kHz F_OUT 50 # 基波频率50Hz N FS // F_OUT # 400点每工频周期推进1点 M 0.90 # 调制比留一点死区损耗余量 def make_table(shift_rad): tbl [] for i in range(N): duty 0.5 0.5 * M * math.sin(2 * math.pi * i / N shift_rad) ccr int(duty * 1799) # 对应ARR1799 ccr max(0, min(1799, ccr)) tbl.append(ccr) return tbl for name, shift in [(A相, 0), (B相, -2 * math.pi / 3), (C相, 2 * math.pi / 3)]: print(f// {name}相位偏移 {math.degrees(shift):.0f}°) tbl make_table(shift) for i in range(0, N, 8): print(, .join(str(x) for x in tbl[i:i8]) ,) print()这段代码里N必须等于FS除以F_OUT也就是400。这样CCR表每50μs推进一点20ms走完一整圈50Hz精确成立。调制比0.9意味着占空比在0.05到0.95之间摆动留出的10%余量是为了给死区和下管最小导通时间腾空间。如果调制比拉到0.98CCR接近ARR下管可能没有足够时间完成关断炸管风险急剧上升。实际工程里我一般不用实时计算直接用查表。STM32F103C8T6的Flash写满这三张表也只占2400字节左右完全够用。如果你想把表尺寸压小也可以只存一相表另外两相用定点小数索引加插值但代码复杂度上去了收益却不大。新手阶段建议老老实实放三张独立表出错时好排查。2.2 STM32F103C8T6引脚功能分配TIM1的6路互补输出怎么接三相全桥需要6个开关管也就是三组半桥。STM32F103C8T6里只有TIM1和TIM8是高级定时器支持互补输出和硬件死区插入而C8T6没有TIM8所以只能用TIM1。这是选型上“没得选”但又刚好够用的地方。TIM1在APB2总线上时钟72MHz足够做20kHz甚至更高频率的SPWM。默认映射下TIM1_CH1、CH2、CH3分别在PA8、PA9、PA10互补输出CH1N、CH2N、CH3N分别在PB13、PB14、PB15。这正好组成三组互补驱动信号PA8/PB13驱动A相半桥PA9/PB14驱动B相PA10/PB15驱动C相。引脚分配表如下功能引脚说明TIM1_CH1 / CH1NPA8 / PB13A相上桥臂 / 下桥臂TIM1_CH2 / CH2NPA9 / PB14B相上桥臂 / 下桥臂TIM1_CH3 / CH3NPA10 / PB15C相上桥臂 / 下桥臂TIM1_BKINPB12刹车信号急停用引脚映射时有个细节如果你想用重映射把CH1N挪到PA7反而会和其他外设打架建议直接用默认映射。PA8/PA9/PA10上桥臂接高端驱动的HINPB13/PB14/PB15下桥臂接LIN。市面上常见的IR2103、IR2110这类自举半桥驱动芯片正好吃这一组互补信号。别把CH和CHN接反否则上下管逻辑颠倒轻则波形乱重则直通炸管。上电前用万用表蜂鸣档核对一下PA8到驱动器HIN、PB13到LIN的走线是值得养成的习惯。2.3 死区时间怎么设从功率管参数到DTG寄存器死区的作用是防止同一桥臂上下管在切换瞬间同时导通。任何一个功率管都有开通延迟和关断延迟栅极驱动芯片也有传播延迟如果上管还没完全关断、下管就开始导通母线电压直接短路几微秒就能炸管。死区时间至少要大于“上管关断延迟最大值减去下管开通延迟最小值”实际工程中再留一倍余量。以常见的IRFP460 MOSFET为例关断延迟典型值60ns到180ns栅极电阻加到10Ω以上后关断更慢取1μs死区是稳妥的。如果换IGBT关断有拖尾电流死区一般取2μs到3μs。STM32的死区时间由TIM1_BDTR寄存器的DTG字段控制Tdts等于1/72MHz约13.9ns。这里有个很多人踩过的分段坑DTG不是线性映射的超过127就得换公式DTG范围死区时间计算公式例子0 ~ 0x7FDTG[7:0] × TdtsDTG72得到1μs0x80 ~ 0xBF(64 DTG[5:0]) × 2 × TdtsDTG128得到1.78μs0xC0 ~ 0xDF(32 DTG[4:0]) × 8 × TdtsDTG192得到3.56μs0xE0 ~ 0xFF(32 DTG[4:0]) × 16 × TdtsDTG224得到7.1μs标准库代码里直接把TIM_BDTRInitStructure.TIM_DeadTime设成72对应1μs死区。如果你要2μsDTG应该是144但它落在0x80到0xBF区间公式变成(64 144 - 128) × 2 × 13.9ns 2.22μs不是精确的2μs。这也是为什么很多老工程师说“死区寄存器写个数很容易写对很难”。建议先确定目标死区再反推DTG落在哪个区间不要直接拿微秒数乘以72。3. 在AD里搭最小系统与电源树原理图到PCB的第一步3.1 从STM32F103C8T6最小系统板原理图抄出的5个必接引脚网上大量“STM32F103C8T6最小系统板”的原理图核心就是五件事VBAT、BOOT0、NRST、VDDA和去耦电容。VBAT必须接3.3V否则备份域寄存器无法工作BOOT0要经10kΩ下拉到GND确保上电从Flash启动而不是进ISPNRST上拉10kΩ并并联0.1μF电容到地防止复位引脚被干扰。VDDA和VSSA是模拟电源不能直接并到VDD上完事一般用磁珠隔离后再加1μF滤波电容这直接影响到ADC采样和内部参考电压的稳定性。晶振也是最小系统里容易翻车的一环。内部HSI只有8MHz虽然可以PLL倍频到72MHz但精度不够SPWM载波会跟着漂导致基波频率不稳定。做逆变电源必须外接8MHz晶振配两个20pF负载电容。还有一个细节STM32F103C8T6的OSC_IN和OSC_OUT引脚如果不用外部晶振必须接地或悬空不能接普通IO。资料包里如果给你的是“最小系统板原理图”而不是“最小系统驱动”完整图这部分就是你要自己补的功课。去耦电容不要只放一个100nF了事。每个VDD/VSS引脚旁边都放一个100nF靠近引脚放置然后在电源入口再放一个10μF钽电容。很多人PCB打样回来程序跑飞、SPWM随机丢脉冲查到最后就是去耦电容离引脚太远高频噪声直接灌进MCU电源。这是看着小、影响大的细节。3.2 电源树与AD原理图怎么生成PCB位号、封装与网络标号先把电源树理清再动手画原理图。三相逆变电源的电源树一般是输入直流母线比如48V验证平台先经过母线电容一路进三相全桥功率级另一路经过Buck降压到5V再经AMS1117降到3.3V给MCU。控制电源和功率母线之间要有明显的分区不要让3.3V的走线贴着母线的高频开关回路走。栅极驱动芯片的供电低压验证平台可以直接从5V取但上桥臂要靠自举电容供电下桥臂直接给VCC就行。在AD里从原理图生成PCB前有三件事必须做。第一Tools菜单下Annotate统一编号检查位号有没有重复很多从网上拼来的原理图位号是乱的生成PCB时网络会串。第二检查封装STM32F103C8T6是LQFP48别画成TQFP48两者的焊盘尺寸和引脚间距不同焊上去虚焊很难查。第三检查网络标号三对互补PWM的标号别标反A相CH1和CH1N必须成对出现。AD里原理图生成PCB的路径是Design → Update PCB Document但前提是你在PCB文件里已经设置了足够大的板框和原点。如果工程是“AD好几个原理图”拼在一起的每个原理图页都要检查是否有悬空网络悬空网络在PCB里表现为飞线乱飘很容易被忽略。我一般会在生成PCB后先按网络分类打开PCB面板看GND网络有没有意外连接到功率地。3.3 PCB布局与多边形填充功率地、信号地与螺丝孔三相逆变器的PCB布局核心是“功率回路短、控制回路远”。第一层先放母线电容和三个半桥母线电容要尽可能靠近每个半桥的直流输入端形成低感抗回路第二层放栅极驱动芯片驱动芯片要靠近对应的MOS管栅极栅极走线越短开关振铃越小第三层才是MCU和信号电路离功率区至少隔开一段距离。功率地和控制地在很多方案里是分开的最后在母线电容负极处单点连接。这样做是为了避免功率地线上的大电流瞬变耦合进模拟地。如果你在原理图里把GND网络直接连成一片PCB上所有地都短在一起示波器看输出电压时会有明显的高频毛刺。AD里做GND铺铜用Polygon Pour注意设置网络间距我一般把GND铜皮到其他网络的距离设为0.3mm铺铜方式选Hatched方便焊接和散热。散热和固定孔也要提前规划。M3螺丝孔在PCB上一般是过孔3.2mm、焊环外径不小于5mm如果用M2螺丝孔径2.1mm、焊环外径不小于3.2mm。螺丝孔不要放在功率走线中间否则会切断铜皮载流路径。散热方面如果MOS管用的是TO-220封装建议引脚间距和散热器位置在布局阶段就确定不然画完板发现散热器顶住电容只能重画。4. 软件落地在Keil下建立工程并让TIM1输出三相互补SPWM4.1 在Keil下建立STM32F103C8T6标准库工程模板拿到源码包后第一件事是建立工程模板确认能编译、能下载再动SPWM代码。常见做法是用标准外设库V3.5配合CMSIS和启动文件。C8T6属于中密度产品启动文件必须选startup_stm32f10x_md.s选错启动文件的话程序一跑就进HardFault。工程目录我习惯这样组织Project/ ├── User/ │ ├── main.c │ └── stm32f10x_it.c ├── Core/ │ ├── startup_stm32f10x_md.s │ ├── core_cm3.c │ └── system_stm32f10x.c ├── Periph/ │ ├── inc/ │ │ ├── stm32f10x_gpio.h │ │ ├── stm32f10x_tim.h │ │ └── stm32f10x_rcc.h │ └── src/ │ ├── stm32f10x_gpio.c │ ├── stm32f10x_tim.c │ └── stm32f10x_rcc.c └── Project.uvproj在Keil里新建工程时选STM32F103C8然后在C/C选项卡的Define里加上STM32F10X_MD和USE_STDPERIPH_DRIVER。前者告诉标准库你用的是中密度芯片后者让库函数实现真正生效。漏掉这两个宏是新手最常见的问题表现是编译报一堆undefined或者库函数里全是空壳。Flash Download设置里勾选Reset and Run下载完自动复位运行。工程模板建好后先写一个点灯程序确认GPIO和时钟没问题再接PWM。这样后面出的问题都能定位到外设配置而不是把工程环境问题和业务逻辑问题混成一锅粥。4.2 TIM1初始化20kHz载波、1μs死区与主要参数TIM1初始化是这套软件的核心参数全在代码里。PWM频率由72MHz分频决定PSC1ARR1799输出频率等于72MHz除以2再除以1800正好20kHz。20kHz高于人耳可闻范围变压器和电感不会发出刺耳啸叫是逆变电源的常用载波频率。#include stm32f10x_tim.h void TIM1_GPIO_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_AFIO, ENABLE); // 上桥臂PA8/PA9/PA10 复用推挽输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10; GPIO_InitStructure.GPIO_Mode GPIO_Mode_AF_PP; GPIO_InitStructure.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, GPIO_InitStructure); // 下桥臂PB13/PB14/PB15 复用推挽输出 GPIO_InitStructure.GPIO_Pin GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15; GPIO_Init(GPIOB, GPIO_InitStructure); } void TIM1_PWM_Config(void) { TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; TIM_OCInitTypeDef TIM_OCInitStructure; TIM_BDTRInitTypeDef TIM_BDTRInitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); // 72MHz / (11) 36MHzARR1799 → 20kHz TIM_TimeBaseStructure.TIM_Prescaler 1; TIM_TimeBaseStructure.TIM_CounterMode TIM_CounterMode_Up; TIM_TimeBaseStructure.TIM_Period 1799; TIM_TimeBaseStructure.TIM_ClockDivision 0; TIM_TimeBaseInit(TIM1, TIM_TimeBaseStructure); // 三通道比较输出均使能互补输出由硬件自动实现 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 900; // 初始占空比50% TIM_OCInitStructure.TIM_OCPolarity TIM_OCPolarity_High; TIM_OCInitStructure.TIM_OCNPolarity TIM_OCNPolarity_High; TIM_OCInitStructure.TIM_OCIdleState TIM_OCIdleState_Reset; TIM_OCInitStructure.TIM_OCNIdleState TIM_OCNIdleState_Reset; TIM_OC1Init(TIM1, TIM_OCInitStructure); TIM_OC2Init(TIM1, TIM_OCInitStructure); TIM_OC3Init(TIM1, TIM_OCInitStructure); // 死区1μsDTG 1μs / (1/72MHz) 72即0x48 TIM_BDTRInitStructure.TIM_OSSRState TIM_OSSRState_Enable; TIM_BDTRInitStructure.TIM_OSSIState TIM_OSSIState_Enable; TIM_BDTRInitStructure.TIM_LOCKLevel TIM_LOCKLevel_1; TIM_BDTRInitStructure.TIM_DeadTime 72; 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); TIM_Cmd(TIM1, ENABLE); TIM_CtrlPWMOutputs(TIM1, ENABLE); // 关键使能主输出MOE }最后那行TIM_CtrlPWMOutputs是高级定时器特有的步骤。TIM1必须在使能后额外打开主输出开关否则6个引脚全部无输出。这个函数漏加了不会报错但你会发现示波器上什么都没有。所有用TIM1/TIM8做PWM的人都在这里挂过至少一次。TIM_OSSRState和TIM_OSSIState控制空闲时输出状态建议都设为Enable保证刹车信号触发后输出到确定电平。4.3 查表更新CCR三相独立表与更新中断PWM初始化完成后剩下的工作就是每50μs更新一次CCR。我不用DMA直接在TIM1更新中断里赋值。20kHz中断频率在72MHz主频下开销很低而且三相表独立逻辑清楚出问题好查。如果你以后想把这个方案推到100kHz载波再考虑DMA也来得及。#define SPWM_POINTS 400 extern const uint16_t spwm_a[SPWM_POINTS]; extern const uint16_t spwm_b[SPWM_POINTS]; extern const uint16_t spwm_c[SPWM_POINTS]; volatile uint16_t spwm_idx 0; void TIM1_UP_IRQHandler(void) { if (TIM_GetITStatus(TIM1, TIM_IT_Update) ! RESET) { TIM_ClearITPendingBit(TIM1, TIM_IT_Update); uint16_t i spwm_idx; TIM_SetCompare1(TIM1, spwm_a[i]); TIM_SetCompare2(TIM1, spwm_b[i]); TIM_SetCompare3(TIM1, spwm_c[i]); if (spwm_idx SPWM_POINTS) { spwm_idx 0; } } }这段代码里spwm_idx每个PWM周期加1加到400清零工频周期精确等于400除以20kHz等于20ms。三张表分别对应0°、-120°、120°相位互差120度由表本身保证不靠索引偏移避免了400不能被3整除的误差。如果你改了SPWM_POINTS必须保证它还是3的倍数吗不需要因为是三张独立表每个表自己转一圈就是360°任何点数都能工作。但点数会直接影响基波相位步进建议保持整数倍PWM周期数。调用这个中断前要配置NVIC并使能更新中断NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); NVIC_InitStructure.NVIC_IRQChannel TIM1_UP_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority 0; NVIC_InitStructure.NVIC_IRQChannelCmd ENABLE; NVIC_Init(NVIC_InitStructure); TIM_ITConfig(TIM1, TIM_IT_Update, ENABLE);到这里PA8/PA9/PA10和PB13/PB14/PB15上应该能看到三组互补SPWM波形了。先把示波器探头夹在PA8和PB13上如果看到两路反相且中间有一段同时为低的脉冲说明死区生效。再分别看另外两组确认三相互差120°后再接功率板这是整个调试过程中最关键的安全动作。5. 三相SPWM逆变电源避坑实录5个最容易翻车的场景5.1 一上电就炸管死区设置没生效现象控制板单独测试PWM波形正常一接功率板母线电压保险丝直接烧断MOS管炸裂。原因最常见的是主输出使能TIM_CtrlPWMOutputs没调用导致TIM1输出引脚全部处于无效电平驱动芯片上电瞬间输出不定态另一个原因是死区时间设得太小或者DTG落到了错误的分段区间实际死区只有几百纳秒。还有一种隐蔽场景你在BDTR里写了死区但后来又调用了TIM_OCInitStructure覆盖了输出极性把CH1N极性改成了反逻辑互补变成同相桥臂直通。解决先不接母线用示波器双通道同时看CH1和CH1N确认两路之间存在一个明显的“同时为低”的时间段。我习惯把死区时间调到1μs后在示波器上放大到2μs每格数一下两个下降沿之间有没有一格以上的间距。确认无误后再串一个白炽灯限流接母线电压白炽灯在短路时限制电流在正常工作时灯丝基本不亮这是低压验证阶段最便宜的保命手段。5.2 滤波后波形带刺栅极回路和吸收电容现象LC滤波后正弦波整体形状出来了但波形上有密密麻麻的高频毛刺示波器上看起来像正弦波上面长了一层“草”。原因这些毛刺通常来自MOS管开关瞬间的di/dt和dv/dt通过驱动回路或地平面耦合到输出端。栅极驱动走线过长、栅极电阻太小、母线电容离半桥太远三个因素至少占一个。还有可能是你示波器探头的地线夹太长测高频信号时探头本身就成了天线这种情况下波形毛刺是假的换短地弹簧探头再看。解决栅极电阻从10Ω起步如果毛刺严重可以加到22Ω甚至33Ω代价是开关损耗增加。在每个半桥的直流母线两端并一个100nF的CBB电容接在功率管的漏源之间吸收开关尖峰。滤波电感上并联一个RC吸收支路典型值10Ω和10nF串联能明显压低振铃。先改这三个地方再考虑加共模电感。5.3 STM32F103C8T6下载失败BOOT0与NRST的坑现象Keil里显示No target connected或者下载到一半校验失败有时候按几下复位能连上但成功率很低。原因BOOT0悬空导致上电时引脚电平不确定芯片可能进入ISP模式NRST被当作普通IO使用外部接了电容太大导致复位拉不起来还有可能是调试时PA15、PB3、PB4这些JTAG引脚被代码复用成PWM输出调试口被占程序跑起来后下载器掉线。解决BOOT0接10kΩ下拉到地NRST只做复位用不要省那个10kΩ上拉和0.1μF电容。如果已经因为代码复用调试口导致掉线按住开发板NRST不松点击Download后立刻松开趁芯片复位窗口期内把新程序烧进去。这个“按住复位下载”的土办法能救回九成被锁死的C8T6。如果还不行把BOOT0拉高进串口ISP用FlyMcu擦除整片Flash再拉回来。5.4 三相互差不是120°查表点数与相位偏移现象单相SPWM波形正常但三相互差角度不对比如A相和B相之间差了100°C相又差了140°负载电流明显不平衡。原因如果三相共用一张表、靠索引偏移实现相移而表点数不是3的倍数相位偏移就会产生累积误差。比如256点表256除以3约等于85.33取整后每相偏差0.5°三相加起来误差更大。另一个原因是PCB上三相输出顺序接错把B相和C相在端子上对调了波形本身没问题是人为接线问题。解决用三张独立表相位直接写死在表数据里从根上消除索引取整误差。接线前用万用表导通档确认驱动芯片输出到功率管栅极是一一对应关系。示波器上验证相序的方法是同时测A相和B相滤波前的桥臂中点对地波形看两个正弦包络过零点的间隔50Hz下120°对应约6.67ms前后误差不超过0.3ms就算正常。5.5 轻载电压偏高LC参数与假负载现象空载或轻载时输出电压比满载时高出一截甚至接近母线电压峰值负载电阻换大后电压继续往上飘。原因三相整流电容负载或纯电容滤波负载在空载时没有放电回路母线电容和滤波电容被充到峰值电压。还有一种情况是LC滤波器固有谐振点恰好落在低频段轻微激励就起振。很多逆变器标称输出220V结果空载一测电压飙到300多伏吓人一跳。解决输出端加假负载电阻Y型接法每相并一个几十瓦的功率电阻让输出始终有一个最小负载电流电压就被拉住了。假负载的功耗按输出功率的2%~3%选比如1kW逆变器配20W到30W。如果加了假负载电压仍偏高检查LC谐振频率保证谐振点远低于基波且远离载波通常取载波频率的二十分之一以下。6. 用双通道示波器验证三相SPWM从互补死区到效率初测6.1 先看死区再看相序双通道示波器验证三相SPWM顺序必须是“先单桥臂、再线电压、最后滤波输出”。单桥臂验证的是死区和互补逻辑CH1接PA8CH2接PB13两个通道都设成DC耦合触发选上升沿时基放到2μs。你应该看到两路方波完全反相且翻转沿之间有约1μs同时为低的平台。如果平台为零立刻断电查BDTR寄存器不要抱侥幸心理。这一步是整个系统上电前唯一能直观确认“不会炸管”的依据。确认死区后把探头移到A相桥臂中点上管源极与下管漏极连接点和B相桥臂中点做减法运算通道看线电压Uab波形。SPWM三相逆变器的线电压是带正负电平的阶梯波包络呈正弦变化。此时不要看毛刺只看包络形状是否连续、三组线电压幅值是否一致。用示波器的数学通道做Uab减去Ubc可以间接得到Uca的波形用来快速判断三相是否对称。滤波后测量才是最终结果在LC滤波电容两端测相电压波形应该是光滑的正弦波。低压48V母线、调制比0.9时滤波后线电压有效值在23V到27V区间低于这个范围说明调制比没生效高于这个范围说明空载泵升。用万用表真有效值档复核示波器的读数避免示波器平均模式骗了你。6.2 LC滤波参数与效率初测滤波参数的选取有一个很实用的顺序先定截止频率再反推LC值。截止频率取载波频率的十分之一到二十分之一20kHz载波对应1kHz到2kHz。常见组合是1mH电感加10μF CBB电容截止频率约1.6kHz对20kHz载波有约40dB的衰减对50Hz基波几乎无损耗。效率测试用最笨的办法直流输入侧串联万用表电流档测母线电流电压档测母线电压两者相乘得到输入功率输出侧接三相对称Y型电阻负载测相电压有效值代入公式3乘以电压平方除以负载电阻得到输出功率。两者相除就是效率。20kHz硬开关条件下MOSFET方案做到88%到94%是正常区间。如果低于85%检查死区是否过大、栅极电阻是否拖慢了开关速度、母线电容是否ESR过大。想再往上提就要研究SVPWM了它和SPWM的核心区别是用六个基本电压矢量合成目标矢量直流母线利用率能提高约15%代价是算法复杂度和死区补偿难度都上了一个台阶。我第一版做这套东西时最血泪的一条教训是不要相信死区寄存器里写了个数就万事大吉。后来养成习惯任何一次改板、改参数上电接母线之前先量三对互补波形确认无贯穿再接功率板。哪怕只换了一个电阻值也要重新量一遍。这个习惯让后面所有调试都顺了很多。如果你刚拿到这类资料包从最小系统板焊起到三相波形全出来中间最值得投入精力的就是死区和LC两个参数把它们吃透剩下的都是熟练活。希望帮到你。本文还有配套的精品资源点击获取