☰
变频空调压缩机FOC控制算法详解与工程实践
2026/10/25 22:49:23 网站建设 项目流程

变频空调已经走进大多数家庭,而决定一台变频空调节能效果和舒适度的核心部件,就是压缩机电机控制系统。在家用空调电控方案里,FOC(Field Oriented Control,磁场定向控制)几乎成了中高端变频压缩机的标配方案,但网上能搜到的资料要么只讲理论推导,要么只贴一段流水账代码,很难把“算法原理”和“压缩机负载特性”完整串起来。

这篇文章会把 FOC 控制链路拆成 5 个核心算法:Clarke 变换、Park 变换、电流环 PI、SVPWM 以及无传感器位置估算,逐一解释原理、给出可运行的代码,最后落到变频空调压缩机启动、弱磁、采样调试这些工程场景。适合正在做变频空调电控、伺服驱动、无刷电机控制,或者刚开始学电机 FOC 的开发者阅读。

1. 认识变频空调压缩机与 FOC 控制

1.1 变频空调压缩机为什么难控制

空调压缩机的工作环境比较特殊,和普通工业伺服电机有很大区别。

  • 压缩机是密闭壳体,内部充满制冷剂,电机工作在高压、高温环境中,无法安装编码器、霍尔等位置传感器,只能做无位置传感器控制。
  • 启动时压缩腔内往往存在高压差,相当于带重载启动,启动失败容易引起整机过流或震动。
  • 压缩机负载具有强周期性,每个转子周期内气体压缩、排气、吸气的力矩都在波动,容易引起转速波动和噪音。
  • 为了适应不同制冷/制热需求,压缩机转速范围很宽,从十几赫兹到一百多赫兹,甚至更高。高转速下反电动势接近母线电压极限,必须考虑弱磁控制。

这些因素叠加在一起,决定了 FOC 是当前变频空调压缩机控制的主流技术路线。FOC 可以把定子电流分解为励磁分量和转矩分量,像控制直流电机一样控制交流电机,从而实现平滑调速、快速响应和高效运行。

1.2 FOC 能解决哪些具体问题

FOC 的本质是磁场定向。它把三相交流电机的定子电流分解到与转子磁极同步旋转的 dq 坐标系上:

  • d 轴电流(id)控制励磁磁场;
  • q 轴电流(iq)控制电磁转矩。

这样控制交流电机就变成了控制两个直流量,电流环可以用 PI 调节器实现无静差控制。相比传统的方波六步换向控制,FOC 的优势非常明显:

  • 转矩脉动小,压缩机噪音和震动明显降低;
  • 电流波形接近正弦,谐波小,逆变器和电机损耗低;
  • 启动和低速运行更平稳,能输出足够启动转矩;
  • 调速范围宽,可以覆盖低频制冷到高频强力制热全工况;
  • 配合弱磁算法,可以在母线电压受限时继续拉升转速。

简单来说,FOC 是用算法换硬件成本,通过电流采样和转子位置估算,用软件把交流电机控制出直流电机的性能。这正是变频空调电控工程师需要掌握它的原因。

1.3 5 大核心算法在整个 FOC 链路中的位置

FOC 的完整控制链路可以拆成如下流程:

  1. 采样三相电流;
  2. 通过 Clarke 变换把三相电流变换到两相静止坐标系;
  3. 通过 Park 变换把静止坐标系电流变换到旋转 dq 坐标系;
  4. d 轴和 q 轴电流环 PI 输出目标电压;
  5. 反 Park 变换得到静止坐标系电压;
  6. SVPWM 生成三相逆变器的占空比;
  7. 在无传感器方案中,通过 SMO 滑模观测器估算转子位置和转速,反馈给 Park 变换和速度环。

这 7 步中,最关键、也最常被单独拿出来讲的就是 Clarke 变换、Park 变换、电流环 PI、SVPWM 和位置估算这 5 部分。下面从第一个变换开始拆解。

2. 核心算法一:Clarke 变换

2.1 Clarke 变换的作用

三相电机的三相对称电流满足基尔霍夫电流定律,理论上只需要采样两相就能计算出第三相。但三相电流在空间上夹角相差 120 度,直接控制三个交流量不方便。Clarke 变换的作用,就是把三相静止坐标系(abc)下的电流变换到两相静止坐标系(αβ)下。

变换后得到两个互相垂直的交流分量,仍然随转子位置变化,但已经把三相加成了两维。这样可以减少后续 Park 变换的计算量,也让电流矢量的合成更直观。

Clarke 变换的常用公式如下,这里采用等幅值变换:

iα = ia iβ = (ia + 2 * ib) / √3

第三相电流通过 ic = -ia - ib 得到,不需要额外采样。

2.2 Clarke 变换代码实现

下面是一个标准的 Clarke 变换 C 语言实现。参数结构体保存变换结果,方便后续 Park 变换直接使用。

// 文件路径:user/foc/clarke.c typedef struct { float alpha; // α轴电流 float beta; // β轴电流 } AlphaBeta_t; typedef struct { float i1; // 第一相采样电流 float i2; // 第二相采样电流 } PhaseCurrent_t; AlphaBeta_t Clarke_Transform(PhaseCurrent_t cur) { AlphaBeta_t ab; // 等幅值Clarke变换 ab.alpha = cur.i1; ab.beta = (cur.i1 + 2.0f * cur.i2) * 0.57735027f; // 1/sqrt(3) return ab; }

如果选用等功率变换,变换系数会不同。在 FOC 控制中,只要反变换和 SVPWM 配合一致,等幅值变换更常用,因为它可以直接用母线电压计算调制比,工程师们习惯上更容易理解。

2.3 Clarke 变换的实际注意点

在实际空调驱动板调试时,Clarke 变换很容易踩三个坑。

第一个坑是电流采样噪声。压缩机的 PWM 载波频率通常在 8kHz 到 16kHz,采样点若落在 IGBT 开关动作瞬间,采样电流会叠加大量开关噪声。处理办法是在 PWM 载波顶点或底点采样,并适当加入硬件 RC 滤波或软件均值滤波。

第二个坑是采样增益不一致。三相电流采样电路上的采样电阻、运放放大倍数如果有偏差,会导致 αβ 轴电流不匹配,最终表现为电流环震荡。批量生产时需要做采样增益自校准。

第三个坑是只采集两相时,第三相电流由 ia+ib+ic=0 推算。这个假设只对电机中性点不接地的星形连接成立。对于空调压缩机 PMSM,这通常是成立的,但如果外接测试设备改变了回路,需要注意。

3. 核心算法二:Park 变换

3.1 为什么需要把静止坐标系变成旋转坐标系

Clarke 变换之后,αβ 轴电流仍然是交流量,会随转子电角度周期性变化。交流量在 PI 调节器里很难实现真正的无静差跟踪。Park 变换的核心作用,是把 αβ 轴交流量投影到随转子同步旋转的 dq 坐标系上,使电流变成直流量。

直流量有什么好处?最简单的一点是:可以用 PI 调节器直接控制它。d 轴分量和 q 轴分量解耦后,id 对应励磁分量,iq 对应转矩分量,控制逻辑变得清晰。

Park 正变换公式为:

id = iα * cos(θ) + iβ * sin(θ) iq = -iα * sin(θ) + iβ * cos(θ)

其中 θ 是转子电角度。在带编码器或霍尔传感器的方案中,θ 直接由传感器读取;在空调压缩机这种无位置传感器方案中,θ 由 SMO 滑模观测器等算法估算。

3.2 Park 变换代码实现

// 文件路径:user/foc/park.c typedef struct { float d; float q; } DQ_t; DQ_t Park_Transform(AlphaBeta_t ab, float theta) { DQ_t dq; float sin_t = sinf(theta); float cos_t = cosf(theta); dq.d = ab.alpha * cos_t + ab.beta * sin_t; dq.q = -ab.alpha * sin_t + ab.beta * cos_t; return dq; }

对应的反 Park 变换用于把电流环输出的 dq 轴电压转换为 αβ 轴电压,再交给 SVPWM:

AlphaBeta_t InversePark_Transform(float ud, float uq, float theta) { AlphaBeta_t uv; float sin_t = sinf(theta); float cos_t = cosf(theta); uv.alpha = ud * cos_t - uq * sin_t; uv.beta = ud * sin_t + uq * cos_t; return uv; }

3.3 Park 变换的工程细节

Park 变换看似简单,却是整个 FOC 里最容易出“方向性”错误的地方。

首先是角度符号问题。如果电机旋转方向定义不同,d/q 轴坐标轴的旋转方向也不同。工程上最常见的错误是:电机实际朝正向转,但估算角度朝反方向增长,导致 d/q 轴电流乱掉,电机发烫甚至失控。解决办法是在调试初期先用开环强拉确认相序和角度方向,再接闭环。

其次是角度精度。Park 变换对角度误差很敏感,角度误差过大时,id 和 iq 会出现耦合,电流环输出畸变。无传感器方案中,角度估算包含低通滤波和相位补偿环节,需要根据转速动态补偿角度滞后。

另一个值得说明的点是,在空调压缩机 FOC 中,有些方案会把 Park 变换和采样触发同步。因为电流采样和坐标变换必须在同一个 PWM 周期内完成,否则采样到的电流和角度不对应,计算出的 dq 电流会有相位偏差。

4. 核心算法三:电流环 PI 调节器

4.1 dq 轴双电流闭环结构

FOC 的电流环是内环,也是整个控制系统最重要的闭环。它一般由两个 PI 调节器组成:

  • d 轴电流环控制 id,让它跟随 id_ref;
  • q 轴电流环控制 iq,让它跟随 iq_ref。

在表贴式永磁同步电机中,id_ref 通常取 0,称为 id=0 控制。在空调压缩机常用的内置式永磁同步电机中,低速段可以使用 MTPA(最大转矩电流比)生成 id_ref,高速段则通过弱磁控制生成 id_ref。

电流环 PI 的输出是 dq 轴电压命令。它需要经过电压限幅处理,防止 SVPWM 进入过调制区导致电流失控。

4.2 PI 调节器的离散化实现

电机控制中,PI 调节器采用位置式或增量式实现都可以。下面是一个常用的位置式 PI 结构体,带积分限幅和输出限幅。

// 文件路径:user/foc/pi.c typedef struct { float kp; // 比例系数 float ki; // 积分系数 float integral; // 积分累加值 float integral_max; // 积分限幅 float out_max; // 输出上限 float out_min; // 输出下限 } PiCtrl_t; float Pi_Process(PiCtrl_t *pi, float ref, float fdb, float ts) { float err = ref - fdb; // 积分累加并限幅 pi->integral += err * ts; if (pi->integral > pi->integral_max) { pi->integral = pi->integral_max; } else if (pi->integral < -pi->integral_max) { pi->integral = -pi->integral_max; } float out = pi->kp * err + pi->ki * pi->integral; // 输出限幅 if (out > pi->out_max) { out = pi->out_max; } else if (out < pi->out_min) { out = pi->out_min; } return out; }

这个实现里有几个容易被忽略的地方。

积分限幅必须存在。如果电动机堵转或指令突变,积分项无限累加,会导致“积分饱和”。一旦堵转解除,输出仍处于饱和状态,电机反应迟钝,严重时直接过流跳闸。所以在积分累加后先限幅,再计算输出。

积分限幅和输出限幅不是一回事。输出限幅保护最终电压指令,积分限幅避免积分项过早饱和。实际整定时,可以先设定输出限幅,再把积分限幅设为输出限幅的 0.5 到 0.8 倍,根据响应效果微调。

4.3 电流环参数整定思路

电流环 PI 参数不是随便给的。行业内通常先根据电机电感和采样周期计算一个初值,再在台架上微调。

  • 比例系数 Kp 影响电流环响应速度。Kp 太小,电流跟踪慢;Kp 太大,容易产生振荡和电流噪声。常见初值可以取 Kp = Ls / (3 * ts),其中 Ls 是定子电感,ts 是电流环控制周期。
  • 积分系数 Ki 用于消除稳态误差。常见初值取 Ki = Rs / (3 * ts),其中 Rs 是定子电阻。
  • 电流环带宽一般设计为电流环控制频率的 1/20 到 1/10。控制频率 10kHz 时,带宽 500Hz 到 1kHz 比较常见。

实际空调压缩机产品中,电流环调试通常分三步:

  1. 开环给固定占空比,确认逆变器和电流采样正常;
  2. 只闭合电流环,给定 id_ref=0、iq_ref 为小值,观察电流跟踪波形;
  3. 逐渐增大 iq_ref,直到电流波形稳定无振荡,记录对应 Kp、Ki。

4.4 转速外环与 ADRC 扩展

电流环外面还有一个转速环。转速环的输出就是 q 轴电流指令。传统方案用 PI 调节器,但在空调压缩机这种周期性负载下,转速环会受到负载波动的明显干扰。

为了抑制压缩机负载波动引起的转速脉动,工程上有两种常见的优化措施:

  • 在转速环中加入负载转矩前馈补偿,根据压缩机的转矩特性表进行角度补偿;
  • 把转速环 PI 换成 ADRC(自抗扰控制),利用扩张状态观测器估计总扰动并补偿。

ADRC 在空调压缩机控制中越来越多见,因为它对负载突变有更强的鲁棒性。不过 ADRC 参数比 PI 多,整定更复杂,建议在 PI 方案调通后再引入,不要一开始就上 ADRC。

5. 核心算法四:SVPWM 空间矢量调制

5.1 从 dq 电压到三相占空比

电流环计算出的 dq 轴电压,经过反 Park 变换后变成 αβ 轴电压指令,但 MCU 无法直接输出 αβ 电压。它需要把目标电压矢量转换成三相桥臂的 PWM 占空比,这就是 SVPWM 要做的事。

三相电压源逆变器一共有 6 个开关管,上下桥臂互补导通,所以可以组合出 8 个开关状态:

  • 6 个有效电压矢量,空间间隔 60 度;
  • 2 个零矢量,输出电压为 0。

SVPWM 的基本思路是:在任意一个 PWM 周期内,用目标电压矢量所在扇区的两个相邻有效矢量,加上零矢量,按时间比例合成目标电压。只要开关频率足够高,电机看到的电压就近似等于目标正弦电压。

5.2 SVPWM 的简化实现

一个完整的 SVPWM 实现包含扇区判断、矢量作用时间计算、占空比分配三步。下面给出一段核心实现,代码中采用角度方式判断扇区,便于理解。

// 文件路径:user/foc/svpwm.c #define SQRT3 1.7320508075688772f typedef struct { float ta; float tb; float tc; } Duty_t; Duty_t Svpwm_Calc(float ualpha, float ubeta, float udc, float ts) { Duty_t duty; float angle; float t1, t2, t0; int sector; // 1. 根据电压矢量角度判断扇区 angle = atan2f(ubeta, ualpha) * 180.0f / 3.14159265f; if (angle < 0.0f) { angle += 360.0f; } if (angle < 60.0f) sector = 1; else if (angle < 120.0f) sector = 2; else if (angle < 180.0f) sector = 3; else if (angle < 240.0f) sector = 4; else if (angle < 300.0f) sector = 5; else sector = 6; // 2. 计算基本矢量作用时间 float x = SQRT3 * ubeta * ts / udc; float y = (1.5f * ualpha + 0.5f * SQRT3 * ubeta) * ts / udc; float z = (-1.5f * ualpha + 0.5f * SQRT3 * ubeta) * ts / udc; switch (sector) { case 1: t1 = z; t2 = y; break; case 2: t1 = y; t2 = -x; break; case 3: t1 = -z; t2 = x; break; case 4: t1 = -x; t2 = z; break; case 5: t1 = x; t2 = -y; break; case 6: t1 = -y; t2 = -z; break; default: t1 = 0; t2 = 0; break; } // 3. 过调制限制 if (t1 + t2 > ts) { float scale = ts / (t1 + t2); t1 *= scale; t2 *= scale; } t0 = ts - t1 - t2; // 4. 七段式发波,生成占空比 float ta = t0 * 0.5f; float tb = ta + t1 * 0.5f; float tc = tb + t2 * 0.5f; switch (sector) { case 1: duty.ta = tb; duty.tb = ta; duty.tc = tc; break; case 2: duty.ta = ta; duty.tb = tc; duty.tc = tb; break; case 3: duty.ta = ta; duty.tb = tb; duty.tc = tc; break; case 4: duty.ta = tc; duty.tb = tb; duty.tc = ta; break; case 5: duty.ta = tc; duty.tb = ta; duty.tc = tb; break; case 6: duty.ta = tb; duty.tb = tc; duty.tc = ta; break; default: duty.ta = 0; duty.tb = 0; duty.tc = 0; break; } return duty; }

把这 4 步串起来,SVPWM 的核心工作原理就完整了。

第 1 步到第 3 步的代码里用到了母线电压 udc 和 PWM 周期 ts,目的是把电压矢量作用时间折算成开关周期内的实际时间。如果直流母线电压有波动,比如空调压缩机在高速运行时母线电压跌落,SVPWM 会实时调整占空比,维持输出电压稳定。

5.3 SVPWM 的工程注意事项

SVPWM 实现得好不好,直接影响空调压缩机的电流谐波、噪声和效率。工程上要特别注意以下几点。

第一是死区时间。上下桥臂开关管不能同时导通,必须要加死区,通常 1us 到 3us。死区会造成实际输出电压与指令电压不一致,产生电流畸变。高性能方案会加入死区补偿。

第二是线性调制范围。SVPWM 的线性调制范围比 SPWM 更高,输出电压幅值最大可以达到 Udc/√3。当电流环输出电压超过这个范围时,会进入过调制区,电流谐波明显增加。所以电流环输出必须做电压限幅。

第三是低调制比问题。在电机低速或轻载时,目标电压矢量幅值很小,如果采用三电阻采样,部分扇区会出现采样窗口不足的问题,需要通过电流重构算法补偿。

第四是开关顺序。七段式 SVPWM 在开关次数和电流纹波之间做了折中,是工程中最常用的发波方式。五段式虽然开关次数更少,但电流纹波更大,一般在特殊降耗场景才会使用。

6. 核心算法五:无传感器转子位置估算

6.1 为什么空调压缩机必须做无位置传感器控制

工业伺服电机普遍安装编码器、旋转变压器,但空调压缩机做不到。原因有三点:

  • 压缩机内部是高温高压制冷剂环境,电子元件很难长期可靠工作;
  • 位置传感器成本高,一台空调整机成本压力较大;
  • 传感器线缆穿过密闭壳体容易导致制冷剂泄漏。

因此,家用变频空调压缩机普遍采用无位置传感器 FOC,也就是通过电机电流和电压,实时估算转子位置和转速。中高速段最常用的方案是反电动势法,其中又以 SMO(滑模观测器)应用最广。

6.2 SMO 滑模观测器的基本原理

PMSM 在 αβ 静止坐标系下的电压方程为:

uα = Rs * iα + Ls * diα/dt + eα uβ = Rs * iβ + Ls * diβ/dt + eβ

其中 eα、eβ 是反电动势分量,包含转子位置信息。如果能准确观测出 eα、eβ,就能算出转子角度。

SMO 的思路是:构造一个电机电流估计模型,把实际电流与估计电流的误差作为滑模面,通过滑模控制律强制电流误差收敛到 0。误差为 0 时,滑模控制量中包含了反电动势信息,再经过低通滤波器提取 eα、eβ。

下面是一段核心实现,省去滤波细节,方便理解主体思路。

// 文件路径:user/foc/smo.c typedef struct { float rs; // 定子电阻 float ls; // 定子电感 float k_slide; // 滑模增益 float k_lpf; // 反电动势低通滤波系数 float ialpha_est; // α轴电流估计值 float ibeta_est; // β轴电流估计值 float ealpha; // α轴反电动势估计 float ebeta; // β轴反电动势估计 float theta_est; // 转子角度估计 } Smo_t; static float Sign(float val) { if (val > 0.0f) return 1.0f; if (val < 0.0f) return -1.0f; return 0.0f; } void Smo_Update(Smo_t *smo, float ialpha, float ibeta, float ualpha, float ubeta, float ts) { float ierr_alpha = ialpha - smo->ialpha_est; float ierr_beta = ibeta - smo->ibeta_est; // 滑模控制律 float zalpha = smo->k_slide * Sign(ierr_alpha); float zbeta = smo->k_slide * Sign(ierr_beta); // 电流估计更新 smo->ialpha_est += ts * ((ualpha - smo->rs * smo->ialpha_est - zalpha) / smo->ls); smo->ibeta_est += ts * ((ubeta - smo->rs * smo->ibeta_est - zbeta) / smo->ls); // 低通滤波提取反电动势 smo->ealpha += smo->k_lpf * (zalpha - smo->ealpha); smo->ebeta += smo->k_lpf * (zbeta - smo->ebeta); // 反正切求转子角度,符号约定随电机模型而定 smo->theta_est = atan2f(-smo->ealpha, smo->ebeta); }

这段代码是 SMO 的核心计算片段,真正用到产品中还需要处理电流估计初值、低通滤波相位延迟补偿、速度估算平滑等一系列问题。

SMO 有几个关键参数:

  • k_slide 滑模增益。太小则抗扰不足,太大则电流估计抖动加剧;
  • k_lpf 低通滤波系数。影响反电动势提取的平滑度,也影响角度延迟;
  • rs、ls 电机参数。电机温度升高时电阻变化,会直接影响观测精度。

6.3 从反电动势到角度和转速

反电动势提取出来之后,转子角度有两种常用提取方式。

第一种是反正切法。直接用 atan2f(-eα, eβ) 计算角度,简单直观,但在反电动势过零附近容易受噪声干扰。第二种是锁相环法。利用角度误差通过 PI 调节器跟踪真实角度,抗噪性更好,工程上更推荐。

转速估算通常有两种方式:

  • 对角度做差分,再经过低通滤波得到转速;
  • 直接使用锁相环输出的角速度估计值。

第一种方式简单,但角度噪声会被放大。第二种方式更平滑,适合对转速波动要求高的空调压缩机。

6.4 压缩机启动阶段的位置估算策略

反电动势法的最大缺点是低速时反电动势幅值很小,SMO 难以准确估计位置。但空调压缩机又是重载启动,不能长时间振荡。工程上普遍采用“预定位 + 开环强拉 + 闭环切换”三步启动策略。

  1. 预定位阶段:给一个固定方向的电压矢量,让转子转到已知位置。通常持续 0.2 到 0.5 秒。
  2. 开环强拉阶段:以固定的电流幅值和递增角度,强制转子旋转起来。此阶段电流环仍闭环,但角度来自程序给定。
  3. 闭环切换阶段:当转速达到一定值,且 SMO 估算角度与开环角度误差持续小于阈值时,平滑切换到 SMO 闭环角度。

这个启动策略直接决定空调压缩机能不能可靠起动。如果开环强拉加速度太大,电机容易失步;如果切换太早,电流会过冲。产品调试时,通常会针对不同负载条件做启动参数标定。

7. 变频空调压缩机 FOC 完整控制框架实战

前面把 5 大算法分别拆开,这一节把它们组合起来,形成一个可运行的 FOC 控制主循环框架。空调变频驱动板上的主控 MCU 通常会在定时器中断里执行这个主循环,控制频率常见为 8kHz 到 16kHz。

7.1 FOC 主循环完整流程

下面的代码是 FOC 控制中断的骨架,包含电流采样、坐标变换、电流环、SVPWM 和 SMO 估算。实际项目需要根据 MCU 外设调整函数名。

// 文件路径:user/foc/motor_control.c #define CTRL_FREQ (10000.0f) #define CTRL_TS (1.0f / CTRL_FREQ) typedef enum { START_PRE_POSITION = 0, START_OPEN_LOOP, START_SYNC_CHECK, RUN_CLOSED_LOOP, FAULT_STOP } MotorState_t; static MotorState_t motor_state; static float rotor_theta = 0.0f; static float speed_est = 0.0f; static float open_loop_theta = 0.0f; static float id_ref = 0.0f; static float iq_ref = 0.0f; void Motor_Control_ISR(void) { float ia, ib; AlphaBeta_t ab; DQ_t dq; float ud, u

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

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

立即咨询