引言:为什么无人机需要 "无感" 测速?
当你操控无人机悬停在百米高空时,你可能不会意识到:机身下方每个旋转的螺旋桨背后,都隐藏着一场每秒数十次的 "精密计算"—— 电机转速的实时检测与调节。无人机的稳定飞行、续航能力、响应速度,几乎都依赖于电机控制系统对转速的精准把控。
无刷外转子电机凭借高扭矩密度、结构紧凑等优势,成为消费级无人机的标配。但在寸土寸金的无人机机身内,传统霍尔传感器测速方案因增加重量、布线复杂等问题逐渐被 "无感测速" 取代。无感测速通过检测电机绕组的反电动势(Back EMF)实现转速测量,无需额外传感器,是轻量化、高可靠性的理想选择。
本文将以无人机常用的 2200KV 外转子无刷电机为例,从电机原理讲起,详细拆解无感过零检测的底层逻辑,手把手教你用 STM32 的内部比较器实现这一功能 —— 包括硬件电路设计、STM32 外设配置、嵌入式软件逻辑,甚至调试过程中的 "坑点" 与解决方案。全文贯穿大量实测数据与表格对比,确保即使是嵌入式新手也能看懂、会用。
第一章 无人机无刷外转子电机:为什么它是 "空中动力" 的首选?
1.1 外转子电机与内转子电机:结构决定性能
无人机电机的 "外转子" 与 "内转子" 并非原理差异,而是结构差异,但这一差异直接决定了其是否适合无人机场景。
| 对比项 | 外转子无刷电机(无人机常用) | 内转子无刷电机(工业常用) |
|---|---|---|
| 结构特点 | 转子包裹定子(外壳旋转) | 转子位于定子内部(中心轴旋转) |
| 重量分布 | 质量集中在外侧,转动惯量大 | 质量集中在中心,转动惯量小 |
| 扭矩特性 | 低转速、高扭矩(适合带动大螺旋桨) | 高转速、低扭矩(需配合减速器) |
| 转速范围 | 典型 3000-15000RPM(无人机用) | 典型 10000-50000RPM(如电动工具) |
| 尺寸形态 | 直径大、轴向短(如 2208 电机:直径 22mm,长度 8mm) | 直径小、轴向长 |
| 散热能力 | 转子直接接触空气,散热效率高 | 依赖外壳散热,效率较低 |
| 响应速度 | 较慢(转动惯量大,抗风干扰强) | 较快(适合快速启停) |
无人机为什么选外转子?
无人机需要带动直径 10-25cm 的螺旋桨,要求电机在中低转速下输出大扭矩(否则需减速齿轮,增加重量)。外转子结构的转动惯量大,能有效抵抗风阻带来的转速波动,提升悬停稳定性 —— 这也是为什么几乎所有消费级无人机(如大疆 Mavic 系列)都采用外转子电机。
1.2 无刷电机的 "电子换向":为什么需要测速?
无刷电机的旋转依赖定子绕组的 "有序通电",而通电顺序必须与转子位置严格匹配(否则会 "卡壳" 或反转)。因此,测速的本质是 "测位置"—— 通过转速计算推导转子实时位置,实现精准换向。
外转子无刷电机的换向逻辑与内转子一致,均为 "六步换向":控制器依次给三相绕组(U、V、W)通电,产生旋转磁场牵引转子转动。每一步对应 60 度电角度,完成 6 步后转子旋转 360 度电角度(机械角度 = 电角度 / 磁极对数,例如 2 对磁极电机,360 度电角度对应 90 度机械角度)。
| 换向步骤 | 导通绕组(以星形连接为例) | 对应转子位置(电角度) | 反电动势特征(非导通相) |
|---|---|---|---|
| 1 | U+ → V-(W 悬空) | 0°-60° | W 相反电动势过零点 |
| 2 | U+ → W-(V 悬空) | 60°-120° | V 相反电动势过零点 |
| 3 | V+ → W-(U 悬空) | 120°-180° | U 相反电动势过零点 |
| 4 | V+ → U-(W 悬空) | 180°-240° | W 相反电动势过零点 |
| 5 | W+ → U-(V 悬空) | 240°-300° | V 相反电动势过零点 |
| 6 | W+ → V-(U 悬空) | 300°-360° | U 相反电动势过零点 |
关键结论:每一步换向中,总有一相绕组处于 "悬空" 状态,其反电动势的过零点(与电源中点电压交叉的时刻)可直接用于判断转子位置,进而计算转速。这就是无感过零检测的核心原理。
1.3 无人机电机的关键参数:从 KV 值到磁极对数
选购无人机电机时,参数表中的 "2208 2200KV" 是什么意思?这些参数直接影响测速方案的设计:
| 参数 | 含义 | 对测速的影响 |
|---|---|---|
| KV 值 | 每伏电压对应的空载转速(RPM/V) | KV 值越高,相同电压下转速越高,反电动势过零点频率越高(对检测电路响应速度要求高) |
| 磁极对数(p) | 转子永磁体的 N/S 极对数(常见 2/4 对) | 计算转速时需用到(转速 = 60× 频率 /(p×6),因每转 6 个过零点) |
| 额定电压 | 典型 7.4V(2S 锂电池)、11.1V(3S) | 反电动势幅值与电压成正比(E=K×n,n=KV×U),影响信号采集电路设计 |
| 最大电流 | 典型 15-30A | 决定功率管选型,与测速电路无关但需考虑电磁干扰 |
以常见的 "2208 2200KV 2 对磁极" 电机为例:
- 3S 锂电池(11.1V)供电时,空载转速≈2200×11.1=24420RPM(实际带载约 18000-22000RPM);
- 每转产生的过零点数量 = 6(六步换向),因此过零点频率 = 24420RPM ÷ 60 ×6=2442Hz(约 2.4kHz);
- 这意味着 STM32 需要在约 0.4ms 内完成一次过零点检测与换向判断。
第二章 无感过零检测的底层逻辑:反电动势里藏着 "速度密码"
2.1 反电动势(Back EMF):电机自己 "告诉" 你转速
当电机转子旋转时,永磁体切割定子绕组,会在绕组中产生感应电动势,其方向与供电电压相反 —— 这就是反电动势(E)。它的特性是无感测速的核心:
- 幅值与转速成正比:E = K_e × n(K_e 为电机常数,n 为转速),转速越高,反电动势越大;
- 波形与电机类型匹配:BLDC 电机的反电动势为梯形波(外转子无人机电机多为 BLDC),PMSM 为正弦波;
- 过零点与转子位置强关联:反电动势过零点(与中点电压交叉的时刻)滞后转子磁极中心 60 度电角度,是换向的关键参考点。
下图为 BLDC 电机三相反电动势波形(简化):
plaintext
U相
|\ /| /|
| \ / | / |
| \ / | / |
| \/ | / |
| /\ | / |
| / \ | / |
| / \ |/ |
|/ \| |
------------------------------------ 中点电压(Vcc/2)
/| |\ /|
/ | | \ / |
/ | | \ / |
/ | | \/ |
/ | | /\ |
/ | | / \ |
/ | | / \ |
/ | |/ \|
V相 W相
重要观察:在任意时刻,总有一相绕组的反电动势处于过零点附近(对应表 1 中的换向步骤),这一特性让我们可以通过检测过零点实现位置与转速测量。
2.2 过零点检测的 "黄金法则":如何从噪声中找到信号
反电动势信号非常微弱(低速时可能 < 1V),且容易被功率管开关噪声、电机振动等干扰。有效的过零检测需遵循以下原则:
| 检测原则 | 具体实现 | 目的 |
|---|---|---|
| 仅检测悬空相 | 每次换向时,只采集未通电的那一相(如步骤 1 检测 W 相) | 避免导通相的大电流干扰 |
| 以中点电压为基准 | 将反电动势与电源中点电压(Vcc/2)比较,交叉时刻即为过零点 | 中点电压是稳定的参考基准 |
| 硬件滤波先行 | 用 RC 电路过滤高频噪声(截止频率 10-50kHz) | 减少软件处理压力 |
| 软件去抖验证 | 连续多次检测到过零点才确认(如连续 3 个采样周期) | 避免单次干扰误判 |
为什么是中点电压?
无刷电机多采用星形连接,三相绕组的公共端即为中点,但该中点通常不引出(为减少接线)。因此,实际电路中需通过电阻分压模拟中点电压(Vmid = Vcc/2),作为反电动势比较的基准。
2.3 从过零点到转速:数学公式背后的计算逻辑
转速计算的核心是测量相邻两个过零点的时间间隔(Δt),再结合电机磁极对数换算转速。
公式推导:
- 每两个相邻过零点对应 60 度电角度(因六步换向,每步 60 度);
- 360 度电角度对应机械角度 = 360°/p(p 为磁极对数);
- 60 度电角度对应的机械角度 = 60°/p;
- 转速 n(RPM,转 / 分钟)的计算公式:n=360°60°/p×Δt60×1000=p×Δt10000(Δt 单位为毫秒 ms,60/Δt 是每秒的机械角度变化,乘以 60 转为分钟)
实例计算:
某无人机电机为 2 对磁极(p=2),检测到相邻过零点间隔 Δt=5ms:
n = 10000/(2×5) = 1000 RPM
若 Δt=1ms(高转速):
n = 10000/(2×1) = 5000 RPM
第三章 STM32 内部比较器:为什么它比外部电路更适合无人机?
3.1 内部比较器 vs 外部比较器:无人机场景的 "轻量化" 选择
检测反电动势过零点需要将反电动势信号与中点电压比较,这一功能可通过外部比较器(如 LMV7219)或 STM32 内部比较器实现。在无人机场景中,内部比较器优势显著:
| 方案 | 优势 | 劣势 | 无人机适用性 |
|---|---|---|---|
| 外部比较器 | 响应速度快(可达 100ns)、抗干扰强 | 增加 PCB 面积、重量(约 0.5g)、成本(约 1 元) | ★★☆☆☆(不适合轻量化需求) |
| STM32 内部比较器 | 无额外硬件、节省空间、重量轻 | 响应速度稍慢(典型 1-5us)、受 MCU 电源噪声影响 | ★★★★★(完美匹配轻量化) |
关键数据:消费级无人机对重量极其敏感 —— 每增加 1g 重量,续航可能减少 5-10 秒。使用内部比较器可省去外部芯片、电阻、电容等元件,直接减少 0.3-0.8g 重量,这是决定性优势。
3.2 STM32 比较器的工作原理:从输入到中断
STM32(如 F103、F405、G070 等系列)内置 1-4 个比较器(COMP),本质是模拟电压比较器:
- 输入:两个模拟通道(INP 正输入端,INN 负输入端);
- 输出:数字信号(当 INP > INN 时输出高电平,否则低电平);
- 触发:可配置上升沿、下降沿或双边沿触发中断,精准捕获过零点。
下图为 STM32 比较器的简化框图:
plaintext
+--------+
| |
INP ----->| COMP |-----> 输出电平
| |
INN ----->| |-----> 中断触发
+--------+
^
|
内部参考电压
(可选)
适合无人机的 STM32 型号:
- 入门级:STM32F103C8T6(2 个比较器,性价比高);
- 中高端:STM32G070CBT6(4 个比较器,低功耗,适合电池供电);
- 高端:STM32F405RGT6(高速比较器,适合高 KV 电机)。
3.3 内部比较器的关键参数:能否满足无人机电机需求?
无人机电机的过零点信号频率通常在 1-10kHz(对应转速 1000-10000RPM,2 对磁极),STM32 内部比较器的参数完全覆盖这一范围:
| 参数 | 典型值(STM32G070) | 无人机电机需求 | 是否满足 |
|---|---|---|---|
| 响应时间 | 1.2us(5V 供电) | >0.1ms(10kHz 信号周期 100us) | 满足(1.2us << 100us) |
| 输入电压范围 | 0-3.6V(VDD=3.3V 时) | 反电动势信号经分压后 0-3V | 满足 |
| 共模抑制比 | 60dB@1kHz | 需抑制电源噪声 | 满足 |
| 电源电压范围 | 2.0-3.6V | 无人机常用 3.3V 供电 | 满足 |
| 工作电流 | 50uA(典型) | 低功耗需求(电池供电) | 满足 |
结论:STM32 内部比较器的响应速度、输入范围等参数完全满足无人机电机的过零检测需求,是轻量化方案的理想选择。
第四章 硬件电路设计:从电机到 STM32 的 "信号之路"
4.1 整体电路框架:无人机电调的核心模块
无人机电调(电子调速器)的核心功能是:接收飞控的 PWM 信号→驱动电机旋转→检测转速并反馈。其电路框架包括:
| 模块 | 功能 | 与测速相关的设计要点 |
|---|---|---|
| 电源模块 | 将锂电池电压(7.4-25.2V)转为 3.3V(给 STM32 供电) | 输出纹波 < 50mV(否则干扰比较器) |
| 三相驱动模块 | 由 6 个 MOS 管组成 H 桥,控制电机三相绕组通断 | 选择低导通电阻的 MOS 管(减少发热) |
| 反电动势采集模块 | 从电机绕组提取反电动势信号 | 高精度分压、低通滤波(关键模块) |
| 中点电压生成模块 | 产生 Vmid=Vcc/2,作为比较基准 | 电压稳定性(±1% 以内) |
| STM32 核心模块 | 处理信号、控制换向、计算转速 | 比较器引脚与 GPIO 分配 |
| 保护模块 | 过流、过压、堵转保护 | 过流检测需避免干扰反电动势信号 |
电路设计原则:所有与反电动势采集相关的路径(从电机到 STM32 比较器输入)必须短、直、粗,减少噪声耦合。
4.2 三相驱动电路:MOS 管选型与栅极驱动
驱动电路是电调的 "功率核心",其设计直接影响反电动势信号的纯净度。
三相 H 桥电路(简化):
plaintext
+Vbat
|
├── Q1(上桥U)──┬── U相 ──┬── Q4(下桥U)── GND
| | |
├── Q2(上桥V)──┼── V相 ──┼── Q5(下桥V)── GND
| | |
└── Q3(上桥W)──┴── W相 ──┴── Q6(下桥W)── GND
|
反电动势采集点(U/V/W相)
MOS 管选型(以 20A 电调为例):
| 参数 | 推荐值 | 选型举例 |
|---|---|---|
| 耐压(VDS) | ≥30V(耐受锂电池峰值电压) | AON7400(30V/50A) |
| 导通电阻(RDS (on)) | <10mΩ(减少发热) | SI2302(不适合,电阻太大) |
| 栅极电荷(Qg) | <30nC(降低驱动难度) | FDS8880(28nC) |
栅极驱动芯片:
为避免 STM32 直接驱动 MOS 管导致的开关速度慢、发热大问题,需增加栅极驱动芯片(如 IR2104):
- 功能:提供足够的栅极电流(>1A),实现上下桥臂的互锁保护;
- 优势:加快 MOS 管开关速度,减少开关噪声对反电动势信号的干扰。
4.3 反电动势采集电路:如何 "干净" 地提取信号?
反电动势信号从电机绕组引出后,需经过分压、滤波才能送入 STM32 比较器,这是整个电路设计的 "灵魂"。
采集电路原理图(以 U 相为例):
plaintext
U相绕组 ──┬── R1(100kΩ)──┬── C1(100nF)── GND
| |
└── R2(100kΩ)──┘── 比较器INP(STM32 PA0)
(R1与R2组成1:2分压,C1为低通滤波电容)
关键元件参数计算:
-
分压电阻(R1、R2):
电机最大反电动势≈0.8×Vbat(满载时),以 3S 锂电池(12.6V)为例,最大反电动势≈10V。需分压至 STM32 耐受电压(3.3V),因此分压比 = 3.3V/10V≈1:3。选择 R1=200kΩ,R2=100kΩ(分压比 1:3,实际输出≈3.3V@10V 输入)。
-
电阻精度选 1%(确保分压比稳定),功率≥0.125W。
-
滤波电容(C1):
- 截止频率 f_c = 1/(2πRC),取 R=R1//R2≈66.7kΩ,C=100nF,f_c = 1/(2×3.14×66.7kΩ×100nF)≈24Hz?(错误!实际应保留过零点信号,截止频率需高于信号频率 10 倍以上)正确计算:电机最高过零点频率≈10kHz,因此 f_c 应≥100kHz。取 C=1nF,则 f_c=1/(2×3.14×66.7kΩ×1nF)≈2400Hz(仍低)。
-
最终选择 C=100pF,f_c=24kHz(满足 10kHz 信号通过)。
布线注意事项:
- 采集线(从电机到分压电阻)需短于 5cm,且远离功率线(如 MOS 管驱动线);
- 滤波电容 C1 需紧贴 STM32 的比较器输入引脚,形成 "RC 就近滤波";
- 分压电阻的接地端需与 STM32 的 GND 直接相连(避免地环路噪声)。
4.4 中点电压生成电路:稳定的 "基准线"
中点电压(Vmid)是反电动势比较的基准,其稳定性直接影响过零检测精度。
生成电路(两种方案对比):
方案 电路 优势 劣势 推荐场景 电阻分压 R3(10kΩ)与 R4(10kΩ)串联分压 3.3V,输出 1.65V 简单、低成本 受 3.3V 电源纹波影响大 电源纹波小的场景 基准源 + 运放 用 TL431 生成 2.5V 基准,经运放跟随输出 1.65V 稳定性高(±1%) 增加成本和重量 高精度需求场景 无人机推荐方案:电阻分压 + RC 滤波(因重量优先)
plaintext
3.3V ──┬── R3(10kΩ)──┬── C2(10uF)── GND | | └── R4(10kΩ)──┘── 比较器INN(STM32 PA1)- R3、R4 选 1% 精度的金属膜电阻,确保分压准确;
- C2(10uF 电解电容 + 100nF 陶瓷电容)滤除低频和高频纹波。
4.5 保护电路:避免电调 "炸机"
无人机飞行中可能遇到堵转、短路等故障,需设计保护电路:
- 过流保护:在 MOS 管下桥臂串联 0.005Ω 采样电阻,用运放放大电压(V=I×R),送入 STM32 ADC,超过阈值(如 25A)时关断电机;
- 过压保护:检测锂电池电压(经分压后),超过 4.3V / 节时限制功率;
- 堵转保护:若连续 50ms 未检测到过零点(转速为 0),关断电机。
第五章 STM32 软件设计:从寄存器配置到转速计算
5.1 开发环境与工具链:搭建 "无感测速" 开发平台
推荐工具:
工具 作用 优势 开发板 STM32F103C8T6 最小系统板 低成本(约 20 元),含必要外设 编译器 Keil MDK 5 或 STM32CubeIDE 前者适合新手,后者开源免费 调试器 ST-Link V2 支持在线调试、下载程序 示波器 100MHz 带宽(如 DS1054Z) 观察反电动势波形和比较器输出 电机测试台 固定电机,连接螺旋桨 模拟实际负载 软件库选择:
- 新手推荐:STM32Cube HAL 库(封装完善,无需深入寄存器);
- 进阶选择:标准外设库(STM32F1xx_StdPeriph_Lib);
- 极致优化:直接操作寄存器(适合资源受限场景)。
5.2 系统初始化:配置外设为 "过零检测" 做好准备
软件初始化的核心是配置 STM32 的比较器、定时器、GPIO 等外设,使其能捕获过零点并计时。
初始化步骤(HAL 库示例):
-
GPIO 配置:
- 电机三相驱动引脚(连接 MOS 管驱动芯片):推挽输出(如 PA8、PA9、PA10 等);
- 比较器输入引脚:模拟输入(如 PA0=INP,PA1=INN)。
c
运行
-
-
GPIO_InitTypeDef GPIO_InitStruct = {0}; // 比较器输入引脚(PA0、PA1) GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_ANALOG; GPIO_InitStruct.Pull = GPIO_NOPULL; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); // 电机驱动引脚(示例) GPIO_InitStruct.Pin = GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); -
比较器配置:
- 选择 INP=PA0(反电动势信号),INN=PA1(中点电压);
- 触发方式:双边沿触发(上升沿和下降沿均触发中断);
- 输出重定向:不重定向(仅用中断)。
c
运行
-
COMP_HandleTypeDef hcomp1; hcomp1.Instance = COMP1; hcomp1.Init.InvertingInput = COMP_INVERTINGINPUT_IO1; // INN=PA1 hcomp1.Init.NonInvertingInput = COMP_NONINVERTINGINPUT_IO0; // INP=PA0 hcomp1.Init.OutputPol = COMP_OUTPUTPOL_NONINVERTED; hcomp1.Init.Hysteresis = COMP_HYSTERESIS_LOW; // 低迟滞,提高灵敏度 hcomp1.Init.BlankingSrce = COMP_BLANKINGSRCE_NONE; // 无 blanking hcomp1.Init.Mode = COMP_MODE_HIGHSPEED; // 高速模式 hcomp1.Init.WindowMode = COMP_WINDOWMODE_DISABLE; hcomp1.Init.TriggerMode = COMP_TRIGGERMODE_IT_RISING_FALLING; // 双边沿中断 HAL_COMP_Init(&hcomp1); -
定时器配置:
- 用于测量过零点间隔 Δt,选择 16 位定时器(如 TIM2);
- 时钟频率 72MHz,分频后 1MHz(计数 1 次 = 1us)。
c
运行
-
TIM_HandleTypeDef htim2; htim2.Instance = TIM2; htim2.Init.Prescaler = 71; // 72MHz/(71+1)=1MHz htim2.Init.CounterMode = TIM_COUNTERMODE_UP; htim2.Init.Period = 65535; // 最大计数65535us(≈65ms) htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; HAL_TIM_Base_Init(&htim2); HAL_TIM_Base_Start(&htim2); // 启动定时器计数 -
中断配置:
- 使能比较器中断,优先级高于普通任务(确保及时响应)。
c
运行
-
HAL_NVIC_SetPriority(COMP_IRQn, 0, 0); // 最高优先级 HAL_NVIC_EnableIRQ(COMP_IRQn);
5.3 电机启动流程:无感电机的 "先迈哪只脚" 难题
无感电机在静止时反电动势为 0,无法检测过零点,因此需要特殊的启动流程(开环启动→闭环切换):
| 启动阶段 | 目的 | 实现方法 | 持续时间 |
|---|---|---|---|
| 预定位 | 让转子转到已知位置 | 给某一相绕组通直流电(如 U+→V-),持续 100ms | 100ms |
| 开环加速 | 按固定频率换向,逐步提高转速 | 从低频率(如 10Hz)开始,每步增加 5% 频率,直到转速足够高(反电动势可检测) | 500-1000ms |
| 闭环切换 | 从开环换向转为基于过零点的闭环换向 | 检测到连续 3 个有效过零点后,切换为无感模式 | 瞬时 |
预定位代码示例:
c
运行
void motor_preposition(void) {
// U相导通,V相反向导通,W相截止(锁定转子到0度电角度)
HAL_GPIO_WritePin(GPIOA, U_HIGH_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, V_LOW_Pin, GPIO_PIN_SET);
HAL_GPIO_WritePin(GPIOA, U_LOW_Pin | V_HIGH_Pin | W_HIGH_Pin | W_LOW_Pin, GPIO_PIN_RESET);
HAL_Delay(100); // 持续100ms,确保转子到位
}
开环加速代码示例:
c
运行
uint8_t current_step = 0; // 0-5,对应六步换向
uint32_t commutation_interval = 100000; // 初始换向间隔100ms(10Hz)
void open_loop_commutation(void) {
static uint32_t last_commutation_time = 0;
uint32_t current_time = HAL_GetTick();
if (current_time - last_commutation_time > commutation_interval / 1000) {
// 执行换向(切换到下一步)
switch_step(current_step);
current_step = (current_step + 1) % 6;
// 逐步缩短换向间隔(提高频率)
commutation_interval = commutation_interval * 0.95; // 每次减少5%
if (commutation_interval < 1000) { // 最低间隔1ms(1000Hz)
is_open_loop = 0; // 切换到闭环模式
}
last_commutation_time = current_time;
}
}
5.4 过零点检测与中断处理:捕获 "速度信号" 的关键时刻
当电机转速足够高(通常 > 500RPM),反电动势信号可被检测,此时进入闭环模式,通过比较器中断处理过零点。
中断服务函数逻辑:
- 记录当前定时器值(计算 Δt);
- 判断过零点类型(上升沿 / 下降沿),验证是否与当前换向步骤匹配;
- 计算转速并更新 PID 控制器;
- 延迟 30 度电角度后执行换向(过零点滞后磁极中心 60 度,需延迟 30 度到换向点)。
代码示例:
c
运行
uint32_t last_zero_cross_time = 0; // 上一次过零点时间(us)
uint32_t zero_cross_interval = 0; // 过零点间隔(us)
uint8_t valid_zero_cross_count = 0; // 有效过零点计数
void COMP_IRQHandler(void) {
if (__HAL_COMP_GET_FLAG(&hcomp1, COMP_FLAG_IT_RISING) != RESET) {
__HAL_COMP_CLEAR_FLAG(&hcomp1, COMP_FLAG_IT_RISING);
process_zero_crossing(1); // 上升沿过零点
}
if (__HAL_COMP_GET_FLAG(&hcomp1, COMP_FLAG_IT_FALLING) != RESET) {
__HAL_COMP_CLEAR_FLAG(&hcomp1, COMP_FLAG_IT_FALLING);
process_zero_crossing(0); // 下降沿过零点
}
}
void process_zero_crossing(uint8_t edge) {
uint32_t current_time = TIM2->CNT; // 获取当前定时器值(us)
// 计算时间间隔(处理定时器溢出)
if (current_time >= last_zero_cross_time) {
zero_cross_interval = current_time - last_zero_cross_time;
} else {
zero_cross_interval = (65535 - last_zero_cross_time) + current_time;
}
last_zero_cross_time = current_time;
// 验证过零点是否与当前步骤匹配(根据换向逻辑)
if (is_valid_zero_cross(edge, current_step)) {
valid_zero_cross_count++;
if (valid_zero_cross_count >= 3) { // 连续3次有效,确认进入闭环
is_open_loop = 0;
// 计算转速(p=2对磁极)
motor_speed = 10000000 / (2 * zero_cross_interval); // RPM(1e7=10^7)
// 计算换向延迟时间(30度电角度 = 间隔的一半)
commutation_delay = zero_cross_interval / 2;
// 启动延迟换向定时器
start_commutation_timer(commutation_delay);
}
} else {
valid_zero_cross_count = 0; // 无效则清零
}
}
5.5 转速计算与 PID 控制:让电机 "听话" 的核心
测速的最终目的是实现转速闭环控制 —— 通过飞控发送的目标转速(PWM 信号,通常 50-400Hz,1000-2000us 脉宽)与实际转速的偏差,调节电机输出。
转速计算函数:
c
运行
uint16_t get_motor_speed(void) {
// 平滑处理:取最近3次转速的平均值,减少波动
static uint16_t speed_buffer[3] = {0};
static uint8_t buffer_idx = 0;
speed_buffer[buffer_idx] = motor_speed;
buffer_idx = (buffer_idx + 1) % 3;
return (speed_buffer[0] + speed_buffer[1] + speed_buffer[2]) / 3;
}
PID 控制器实现:
c
运行
typedef struct {
float kp; // 比例系数
float ki; // 积分系数
float kd; // 微分系数
int16_t target; // 目标转速
int16_t current; // 当前转速
int16_t error; // 误差
int16_t integral; // 积分项
int16_t derivative; // 微分项
int16_t output; // 输出(PWM占空比)
} PID_HandleTypeDef;
void pid_update(PID_HandleTypeDef *pid) {
pid->current = get_motor_speed();
pid->error = pid->target - pid->current;
// 积分限幅,避免饱和
pid->integral += pid->error;
if (pid->integral > 1000) pid->integral = 1000;
if (pid->integral < -1000) pid->integral = -1000;
// 微分项(当前误差-上一次误差)
static int16_t last_error = 0;
pid->derivative = pid->error - last_error;
last_error = pid->error;
// 计算输出(PWM占空比,范围0-1000)
pid->output = pid->kp * pid->error + pid->ki * pid->integral + pid->kd * pid->derivative;
if (pid->output > 1000) pid->output = 1000;
if (pid->output < 0) pid->output = 0;
}
飞控信号解析(PWM 输入):
c
运行
// 用定时器输入捕获解析飞控PWM信号(1000-2000us对应0-100%油门)
void pwm_input_callback(uint32_t pulse_width) {
// 转换为目标转速(例如:1000us→1000RPM,2000us→10000RPM)
pid.target = 1000 + (pulse_width - 1000) * 9; // 线性映射
}
第六章 调试与优化:解决无感测速的 "坑点"
6.1 常见问题与解决方案:从波形到代码的排查
即使电路和代码正确,实际调试中仍可能遇到各种问题,以下是无人机无感测速的典型 "坑点" 及解决方法:
| 问题 | 现象 | 可能原因 | 解决方案 |
|---|---|---|---|
| 启动失败,电机抖动 | 电机嗡嗡响但不转 | 预定位时间不足或电流不够 | 延长预定位时间至 200ms,增加启动阶段占空比 |
| 过零点误判 | 转速跳变,电机异响 | 反电动势信号噪声大 | 增加滤波电容(如 220pF),软件增加 3 次连续检测验证 |
| 低速时转速不准 | 低于 1000RPM 时波动大 | 反电动势信号弱,比较器灵敏度不足 | 降低比较器迟滞(COMP_HYSTERESIS_LOW),优化中点电压精度 |
| 高速时丢步 | 超过 15000RPM 后失控 | 比较器响应速度不够,中断处理延迟 | 改用高速比较器模式,简化中断服务函数(只做计时,不做复杂计算) |
| 换向时刻偏差 | 效率低,电机发热严重 | 过零点到换向的延迟计算错误 | 用示波器测量实际延迟,修正延迟时间(如从 30 度电角度调整为 25 度) |
示波器调试技巧:
- 通道 1:反电动势信号(经分压后);
- 通道 2:中点电压 Vmid;
- 通道 3:比较器输出(或 STM32 的 LED 引脚,检测中断触发);
- 观察通道 1 与通道 2 的交叉点是否与通道 3 的跳变时刻一致,判断过零检测是否准确。
6.2 参数优化:让 PID 控制更 "丝滑"
PID 参数直接影响电机的稳定性和响应速度,需根据电机特性调整:
| 参数 | 作用 | 调试方法 | 无人机推荐值(2200KV 电机) |
|---|---|---|---|
| Kp(比例) | 快速响应误差 | 从 0 开始增加,直到出现轻微震荡 | 0.5-1.0 |
| Ki(积分) | 消除静态误差 | 缓慢增加,避免超调 | 0.01-0.1 |
| Kd(微分) | 抑制震荡 | 少量增加,减少响应时间 | 0.1-0.5 |
调试步骤:
- 先将 Ki、Kd 设为 0,增加 Kp 至电机能跟随目标转速但略有震荡;
- 增加 Ki 至静态误差消除(目标转速与实际转速差 < 5%);
- 增加 Kd 至震荡消失,响应速度加快。
6.3 电磁兼容性(EMC)优化:减少无人机内部干扰
无人机内部电机、电调、飞控、GPS 等设备密集,电磁干扰严重,需从硬件和软件两方面优化:
| 优化方向 | 具体措施 |
|---|---|
| 硬件布线 | 功率线(电机线)与信号线(反电动势采集线)分开布线,避免平行;电源输入端增加共模电感和 X/Y 电容;STM32 芯片下方铺接地平面,减少辐射干扰 |
| 软件滤波 | 在反电动势采样后增加软件低通滤波(如一阶 RC 滤波算法);转速计算采用滑动平均(取 5-10 次平均值);中断服务函数中禁止嵌套中断,避免干扰 |
| 接地处理 | 采用单点接地(所有 GND 汇总到电源地);电机外壳接地,减少辐射 |
第七章 实战案例:2200KV 外转子电机的无感测速实现
7.1 硬件清单与搭建步骤
核心元件清单:
| 元件 | 型号 / 规格 | 数量 | 作用 |
|---|---|---|---|
| 电机 | 2208 2200KV 2 对磁极 | 1 | 无人机动力电机 |
| 电调主控 | STM32F103C8T6 | 1 | 核心控制芯片 |
| MOS 管 | AON7400(30V/50A) | 6 | 三相驱动 |
| 驱动芯片 | IR2104 | 3 | 驱动 MOS 管 |
| 分压电阻 | 100kΩ 1%、200kΩ 1% | 各 3 | 反电动势分压 |
| 滤波电容 | 100pF、100nF、10uF | 若干 | 信号与电源滤波 |
| 锂电池 | 3S 11.1V 2200mAh | 1 | 供电 |
| 示波器探头 | 10:1 高压探头 | 2 | 测量反电动势 |
搭建步骤:
- 按第四章电路设计绘制 PCB(或用洞洞板搭建);
- 焊接元件(先焊 STM32 最小系统,再焊驱动电路,最后焊采集电路);
- 检查焊接(重点:MOS 管极性、电阻阻值、电容容量);
- 连接电机、锂电池、示波器(注意探头接地与电调地共地)。
7.2 软件烧录与调试流程
调试步骤:
- 烧录初始化程序,用万用表测量中点电压是否为 1.65V±0.02V;
- 烧录预定位程序,观察电机是否能稳定停在固定位置(可用手转动验证);
- 烧录开环启动程序,逐步提高转速,用示波器观察反电动势波形是否为梯形波;
- 开启闭环模式,观察比较器输出是否在反电动势与中点电压交叉时跳变;
- 发送不同 PWM 信号(模拟飞控指令),验证电机转速是否能线性跟随。
实测数据(3S 电池供电,空载):
| 飞控 PWM 脉宽(us) | 目标转速(RPM) | 实测转速(RPM) | 误差(%) | 过零点频率(Hz) |
|---|---|---|---|---|
| 1000(最低) | 1000 | 980 | 2.0 | 100 |
| 1500(中间) | 5500 | 5420 | 1.5 | 550 |
| 2000(最高) | 10000 | 9850 | 1.5 | 1000 |
波形验证:
- 反电动势过零点与比较器输出跳变时刻的偏差 < 5us,满足精度要求;
- 转速稳定时,相邻过零点间隔的波动 < 3%,说明测速稳定。
7.3 飞行测试:从地面到空中的验证
地面调试通过后,需进行飞行测试(建议先在安全场地悬停):
| 测试项目 | 测试方法 | 合格标准 |
|---|---|---|
| 悬停稳定性 | 悬停 1 分钟,观察无人机是否漂移 | 水平漂移 < 1 米 |
| 响应速度 | 快速推杆 / 拉杆,观察电机转速变化 | 转速从 5000→8000RPM 的时间 < 0.5 秒 |
| 续航时间 | 满电状态下悬停至低电量报警 | 续航≥8 分钟(2200mAh 电池) |
| 抗干扰能力 | 靠近 Wi-Fi 路由器、高压线等干扰源 | 无明显抖动或失控 |
优化建议:
- 飞行中若出现轻微抖动,可增加转速平滑的窗口大小(如从 3 次平均改为 5 次);
- 若续航不足,检查电机效率(可能是换向时刻偏差,需重新校准延迟时间)。
第八章 技术进阶:从基础到高端的无感测速方案
8.1 多比较器复用:三相信号的分时检测
STM32 的比较器数量有限(如 F103 只有 2 个),而电机有三相绕组,需分时复用比较器:
| 方案 | 原理 | 优势 | 实现难度 |
|---|---|---|---|
| 模拟开关切换 | 用 CD4051 等模拟开关切换三相信号到比较器输入 | 硬件简单 | 中等(需控制开关时序) |
| 比较器输入重映射 | 利用 STM32 比较器的输入重映射功能(如 COMP1 可切换多个输入引脚) | 无额外硬件 | 高(需深入理解外设映射) |
推荐方案:比较器输入重映射(以 STM32G070 为例,其 COMP1 可切换 4 个输入引脚),通过软件动态切换检测的相序,配合换向步骤实现三相信号的分时检测。
8.2 滑模观测器:提升低速测速精度的高级算法
传统反电动势过零检测在低速时精度下降,滑模观测器通过数学模型估算反电动势,可实现全转速范围的高精度测速:
- 原理:基于电机的状态方程,构建包含反电动势的观测模型,通过反馈修正误差;
- 优势:低速(<500RPM)仍能准确估算转速,抗噪声能力强;
- 实现:需在 STM32 中运行复杂的浮点运算(建议用带 FPU 的型号,如 F4 系列)。
算法框架:
plaintext
// 简化的滑模观测器伪代码
void sliding_mode_observer(void) {
// 测量三相电流、电压
i_u = get_current(U相);
i_v = get_current(V相);
u_u = get_voltage(U相);
u_v = get_voltage(V相);
// 估算电流(基于电机模型)
i_u_hat = L * di/dt + R * i_u + e_u; // e_u为估算反电动势
i_v_hat = L * di/dt + R * i_v + e_v;
// 计算滑模面(电流误差)
s = (i_u - i_u_hat) + (i_v - i_v_hat);
// 切换函数(修正反电动势估算值)
if (s > 0) {
e_u_hat += K;
e_v_hat += K;
} else {
e_u_hat -= K;
e_v_hat -= K;
}
// 从反电动势估算转速和位置
speed_hat = sqrt(e_u_hat² + e_v_hat²) / K_e;
position_hat = atan2(e_v_hat, e_u_hat);
}
8.3 FOC(磁场定向控制):从六步换向到正弦驱动
进阶的无人机电调已开始采用 FOC 控制,相比传统六步换向,其优势在于:
| 指标 | 六步换向 | FOC 控制 |
|---|---|---|
| 扭矩脉动 | 5-15% | <1% |
| 效率 | 85-90% | 90-95% |
| 噪音 | 中高 | 低 |
| 复杂度 | 低 | 高 |
FOC 控制需精确的转子位置信息(通过无感测速提供),结合 STM32 的高级定时器(如 TIM1)生成正弦波 PWM,实现更平滑的驱动。
结语:无感测速 —— 无人机轻量化的必然选择
从拆解外转子电机的结构,到推导反电动势过零检测的公式;从设计分压滤波电路,到用 STM32 比较器捕获每一个过零点;从调试启动抖动的 "坑",到最终实现稳定飞行 —— 无感测速技术的每一步都体现了 "用智慧替代硬件" 的工程思想。
对于无人机而言,去掉 3 个霍尔传感器换来的不仅是 0.5g 的重量减轻,更是可靠性的提升(减少了 3 个潜在故障点)。而 STM32 内部比较器的巧妙应用,让这一切在低成本下成为可能。
未来,随着电机制造工艺的进步和控制算法的优化,无感测速的精度和稳定性将进一步提升,甚至可能完全替代有传感器方案。但无论技术如何发展,理解 "反电动势过零点" 这一核心原理,始终是掌握无感控制的关键。
2852

被折叠的 条评论
为什么被折叠?



