简介:这是一份面向电机控制初学者、嵌入式工程师及课程设计人员的直流无刷电机驱动原理图,PDF图纸围绕STM32F103RCT6主控展开,可用于理解BLDC驱动板的主控、电源与功率级设计。图中包含ASM1117-3.3与XL2576S-5.0稳压电路、IR2101S栅极驱动配合IRF540N构成的三相H桥、霍尔接口、电流采样、MAX232串口电平转换、OLED及按键电位器交互等模块,并标出JTAG/SWD调试与PWM、方向、使能等信号,便于对照分析控制链路与功率回路。资源包共1个PDF文件,约925KB,适合直接查阅与打印。已有3343人学习,可作为无刷电机驱动入门、原理图识读和课程设计参考,帮助读者快速厘清供电分级、驱动时序与位置反馈之间的对应关系。
1. 拿到图先别焊:电源树和采样链才是这块板的分水岭
手上这份 STM32.SchDoc 打开第一眼是劝退的:A1 图幅,标题栏停在 2020/1/12,位号从 R1 排到 R83,末尾还挂着一串乱码的三相电压采样注释,明摆着是个半成品。多数人拿到直流无刷电机驱动原理图,第一反应是照着六个 IRF540NS 把三相桥抄下来,焊完就上电——这是最容易返工的顺序。真正决定这块板能不能转、转得稳的,是它上面那条从 XL7035 到 ASM1117 的三级电源树,以及 0.01Ω 采样电阻到 ADC 之间那条模拟链。三相桥只是执行机构,参数偏了顶多效率低;电源和采样错了,板子连自检都过不去。这份图适合已经能点亮 STM32、想迈过“电机真的转起来”这道坎的人,也适合手上有个驱动 Demo 但电流波形一直不干净的熟手。
2. 三级电源树拆解:XL7035 的 27K/2.4K 与两条低压轨
这块板的供电结构不复杂,但每一级的选型都有明确的账要算:外部直流从 P1 的 VCC 进来,先经 VR1(XL7035)降到 +15V,+15V 一路直接喂 IRS2101S 的驱动电源和 SGM8634 运放,另一路经 VR2(XL2576S-5.0)出 +5V,+5V 再经 VR3(ASM1117-3.3)出 +3.3V 给 MCU 和数字外设。三级串联,任何一级的余量没留够,后面全是连锁反应。
2.1 XL7035 反馈网络:27K 和 2.4K 是怎么定出来的
XL7035 是开关降压,内部反馈基准 1.25V,输出电压由 R9(27K)和 R11(2.4K)组成的分压网络决定。套公式算一遍就知道为什么是这两个值:
# XL7035 反馈网络验算:Vout = Vref * (1 + Rtop / Rbot) VREF = 1.25 # 芯片内部反馈基准,V R_TOP = 27_000 # R9,上分压电阻,Ω R_BOT = 2_400 # R11,下分压电阻,Ω vout = VREF * (1 + R_TOP / R_BOT) print(f"标称输出 = {vout:.2f} V") # 15.31 V # 反推:要精确落在 15.00V,下分压该取多少 target = 15.0 r_bot_need = R_TOP / (target / VREF - 1) print(f"要 15.00V,R11 应取 {r_bot_need:.0f} Ω") # 2446 Ω # 电阻误差对输出的影响:1% 和 5% 各算一遍 for tol in (0.01, 0.05): hi = VREF * (1 + R_TOP * (1 + tol) / (R_BOT * (1 - tol))) lo = VREF * (1 + R_TOP * (1 - tol) / (R_BOT * (1 + tol))) print(f"±{tol*100:.0f}% 电阻:{lo:.2f} ~ {hi:.2f} V")逻辑很直白:反馈脚维持 1.25V,流过上下分压电阻的电流相同,所以输出和电阻比值成线性。参数上要注意两点。第一,用 1% 精度电阻时输出落在 14.8~15.9V 之间,这个范围对后级是安全的——IRF540NS 的 Vgs 绝对最大值 ±20V,15V 出头还有余量;但如果贪便宜用 5% 电阻,上限能冲到 16.7V,再加上开关纹波尖峰,就贴着栅极氧化层的耐受边界跑了。第二,R11 取 2.4K 而不是 2.44K,是因为 E24 系列里没有 2.44K,2.4K 是最接近的标准值,误差 2.3%,落在 1% 电阻的调节余量内。想让输出更准,可以把 R9 换成 27K 加一个 100Ω 微调,或者直接把 R11 改成 2.4K 串 47Ω。
这里还埋着一个后面会用到的事实:+15V 既是驱动电源,也是运放电源。IRS2101S 的 VCC 推荐工作范围到 20V,15V 在中间偏上的位置,开关速度够但不算激进;IRF540NS 的 Rds(on) 规格是在 Vgs=10V 下测的,15V 驱动只会让导通电阻更低,代价是栅极电荷变大、dv/dt 更猛,这一点在第 3 章算开关损耗时会翻出来。
2.2 15V 到 5V 为什么必须用开关,5V 到 3.3V 却能容忍线性
很多人看到两级降压会觉得冗余,直接一颗 LDO 从 15V 降到 3.3V 不香吗?算一下耗散就知道这条路走不通:
# 线性方案 vs 开关方案的耗散估算,先算清楚再决定拓扑 rails = [ # 名称, 输入V, 输出V, 负载A, 封装热阻 °C/W ("15V->5V 线性", 15.0, 5.0, 0.50, 65), ("15V->5V 开关", 15.0, 5.0, 0.50, 65), ("5V->3.3V 线性", 5.0, 3.3, 0.20, 60), ] for name, vin, vout, iout, rth in rails: if "开关" in name: # 开关方案按 85% 效率折算,损耗主要来自开关和电感 p = vout * iout * (1 / 0.85 - 1) else: p = (vin - vout) * iout print(f"{name:12s} 耗散 {p:5.2f} W 温升约 {p * rth:6.1f} °C")跑出来的结果很能说明问题:15V 直降 5V 的线性方案在 500mA 负载下要烧掉 5W,TO-263 封装的热阻按 65°C/W 算,温升 325°C,芯片当场就没了;换成 XL2576S-5.0 这种开关方案,损耗降到 0.88W 左右,温升 57°C,加一小块覆铜就能压住。而 5V 到 3.3V 只有 1.7V 压差,200mA 下耗散 0.34W,温升 20°C,用 ASM1117 这种线性器件完全合理,还省了电感和纹波。
参数上有个容易忽略的边界:ASM1117-3.3 的 dropout 典型 1.1V、最大 1.3V,5V 输入时余量有 3.7V,随便怎么波动都够;但如果哪天把 5V 轨换成锂电池直接供(满电 4.2V、放到 3.6V),余量就只剩 0.3V,3.3V 输出会跟着输入一起塌。这份图的 5V 是开关稳压出来的,不存在这个问题,改板的时候别把这层关系拆了。
2.3 上电时序与去耦:C27 的 100uF 不是随手放的
三级串联的电源树有个天然的上电顺序:+15V 先建立,+5V 跟随,+3.3V 最后。这个顺序恰好构成一个风险窗口——+15V 到位时,IRS2101S 的 VCC 已经有电,输入级开始工作,而此时 MCU 还处在复位状态,HIN/LIN 两个引脚是浮空输入,电平不确定。如果两路输入同时被拉高,上下管直通,+15V 经两个 IRF540NS 直接对地短路,几十微秒就能把管子送走。第 5 章会专门讲这个坑,这里先记住结论:驱动输入必须有确定的下拉,不能指望 MCU 复位期间的电平。
去耦网络的配置决定了这套电源在开关瞬间还稳不稳。按图上的位号整理一份关键清单:
| 位号 | 容值 | 位置与作用 | 布局要求 |
|---|---|---|---|
| C27 | 100uF | ASM1117 输入储能,扛负载跳变 | 距 Vin 引脚 5mm 内 |
| C10 | 330uF | 5V 输出储能,配合 XL2576S 电感 | 靠电感的输出侧 |
| C28 / C11 | 100nF | 3.3V 高频去耦,每个 VDD 脚一个 | 与引脚同层,过孔就近 |
| C19 / C21 / C30 | 10uF/100V | 三相自举电容 | 紧贴 VB-VS 引脚 |
| C23 / C24 / C25 | 100nF | 采样运放电源旁路 | 距运放 V+ 引脚 3mm 内 |
| C13 / C14 / C26 | 100nF | 电流采样滤波 | 靠运放反馈网络 |
一个实操细节:STM32F103RCT6 是 LQFP64 封装,VDD 引脚分布在 19、32、48、64 四个位置,每个脚都要配 100nF,且过孔要打在焊盘和地平面之间而不是走一段线再接地。这份图上 C28、C11、C31、C32 这一组就是干这个的,画板时别为了省地方把它们合并成一个。
3. 三相桥与栅极驱动:IRS2101S 配 IRF540NS 的六个开关怎么定参
三相逆变部分由 U3、U4、U5 三片 IRS2101S 半桥驱动加 Q1~Q6 六个 IRF540NS 组成,每相上下各一只管子,下桥臂源极串 0.01Ω 采样电阻到地。拓扑是教科书标准结构,真正决定成败的是三个参数:自举电容多大、死区给多少、栅极电阻取几欧。这三个值这份图上都填了,但填得未必是最优解。
3.1 自举回路:10uF/100V 这个容值偏大了一个数量级
IRS2101S 是高低侧驱动,上管需要自举供电:+15V 经自举二极管(D4/D7/D10,SS310 肖特基)给自举电容(C19/C21/C30,10uF/100V)充电,电容跨接在 VB 和 VS 之间,为上管栅极提供浮地电源。容值该取多大,按栅极电荷反推:
# 自举电容选型:按 Qg 和允许压降反推最小容值 Qg = 71e-9 # IRF540NS 栅极总电荷,C(Vgs=10V 条件) Iq = 100e-6 # IRS2101S 静态工作电流,A fsw = 20e3 # 开关频率,Hz T = 1 / fsw for C in (100e-9, 470e-9, 1e-6, 10e-6): dV_qg = Qg / C # 每次开关转移电荷造成的跌落 dV_iq = Iq * T / C # 静态电流在周期内造成的跌落 print(f"C={C*1e6:6.2f}uF 单周期跌落 {dV_qg*1e3:6.2f} mV + {dV_iq*1e3:5.2f} mV")结果很清楚:1uF 时单周期跌落只有 71mV,10uF 时 7.1mV,两者都远小于允许值。也就是说,从“维持自举电压”这个目标看,10uF 是需求的 100 倍以上,属于过度设计。过大的代价在充电瞬间:上电时 10uF 从 0V 充到 15V,SS310 要承受的峰值电流受线路阻抗限制,插拔电源时反复冲击,肖特基结容易老化;更隐蔽的问题是,当上管长时间保持导通、下管不开关时,自举电容得不到刷新,只能靠 100uA 级静态电流慢慢放电,10uF 掉到 UVLO 门限(IRS2101S 约 8.6V)需要的时间比 1uF 长得多,这段“电压勉强够、驱动不足”的区间里,MOSFET 工作在放大区,发热量陡增,表现出来就是低速大扭矩工况莫名发烫。
我一般的做法是把自举电容换成 1uF/50V 的 X7R 陶瓷,VB 和 VS 之间再并一颗 100nF 高频旁路,自举二极管前串 10Ω 限流。这样既满足电荷需求,又把充电冲击压下去。当然,换成 1uF 之后要重新核对最小占空比——下管导通时间太短时自举电容来不及补满,这时候要么限制最小占空比,要么改成独立电源给上管驱动供电。
3.2 死区:IRS2101S 没有硬件互锁,全靠软件兜底
这是这份图最容易翻车的地方。IRS2101S 和 IR2101 同族,HIN 和 LIN 是两路完全独立的输入,内部既不做互锁,也没有可编程死区——两路同时为高,上下管就同时导通,+15V 经两个 IRF540NS 直接短路。IRF540NS 的脉冲电流能力 33A 以上,短路回路的电阻只有几十毫欧,电流上升速率极高,几十微秒内结温就冲过极限。
死区必须由定时器硬件产生,不能靠软件里if判断先后。按关断延时估算:IRF540NS 的 td(off) 典型 39ns、tf 典型 30ns,IRS2101S 的传输延时匹配在 ±50ns 量级,再算上驱动电阻造成的延迟,保守取 1us 足够覆盖。20kHz 下周期 50us,1us 死区相当于损失 2% 的占空比,换来的是管子不炸,这笔账很划算。
/* TIM1 互补 PWM + 硬件死区,中心对齐,20kHz @72MHz */ /* 关键:IRS2101S 无互锁,死区只能由 BDTR 产生,不能靠软件延时 */ TIM_TimeBaseInitTypeDef tb; TIM_OCInitTypeDef oc; TIM_BDTRInitTypeDef bdtr; RCC_APB2PeriphClockCmd(RCC_APB2Periph_TIM1, ENABLE); tb.TIM_Prescaler = 0; /* 72MHz 不分频 */ tb.TIM_CounterMode = TIM_CounterMode_CenterAligned1; tb.TIM_Period = 1800 - 1; /* 72M/(2*1800) = 20kHz */ tb.TIM_ClockDivision = TIM_CKD_DIV1; TIM_TimeBaseInit(TIM1, &tb); oc.TIM_OCMode = TIM_OCMode_PWM1; oc.TIM_OutputState = TIM_OutputState_Enable; oc.TIM_OutputNState = TIM_OutputNState_Enable; /* CH1N 等互补通道必须显式打开 */ oc.TIM_Pulse = 0; /* 上电占空比给 0,先别转 */ oc.TIM_OCPolarity = TIM_OCPolarity_High; oc.TIM_OCNPolarity = TIM_OCNPolarity_High; oc.TIM_OCIdleState = TIM_OCIdleState_Reset; /* 空闲态强制拉低,防直通 */ oc.TIM_OCNIdleState = TIM_OCNIdleState_Reset; TIM_OC1Init(TIM1, &oc); /* CH1 + CH1N */ TIM_OC2Init(TIM1, &oc); /* CH2 + CH2N */ TIM_OC3Init(TIM1, &oc); /* CH3 + CH3N */ bdtr.TIM_DeadTime = 72; /* 72 tick × 13.9ns ≈ 1.00us */ bdtr.TIM_Break = TIM_Break_Disable; bdtr.TIM_OSSRState = TIM_OSSRState_Enable; bdtr.TIM_OSSIState = TIM_OSSIState_Enable; bdtr.TIM_LOCKLevel = TIM_LOCKLevel_1; bdtr.TIM_AutomaticOutput = TIM_AutomaticOutput_Enable; TIM_BDTRConfig(TIM1, &bdtr); TIM_CtrlPWMOutputs(TIM1, ENABLE); TIM_Cmd(TIM1, ENABLE);参数说明要抠细。TIM_DeadTime 写 72 不是随手填的:死区发生器的输入时钟是 fCK_INT=72MHz,一个 tick 是 13.9ns,DTG[7:0] 小于 128 时死区时间等于 DTG 乘以这个 tick,所以 72 对应
本文还有配套的精品资源,点击获取