电机驱动开发学习15. Clark、Park、反Park坐标变换
-
- [一、 FOC 核心坐标系概览](#一、 FOC 核心坐标系概览)
- [二、 Clark 变换:三相静止 → \rightarrow → 两相静止( a b c → α β abc \rightarrow \alpha\beta abc→αβ)](#二、 Clark 变换:三相静止 → \rightarrow → 两相静止( a b c → α β abc \rightarrow \alpha\beta abc→αβ))
-
- [1. 几何推导与等幅值约束](#1. 几何推导与等幅值约束)
- [三、 Park 变换:两相静止 → \rightarrow → 两相旋转( α β → d q \alpha\beta \rightarrow dq αβ→dq)](#三、 Park 变换:两相静止 → \rightarrow → 两相旋转( α β → d q \alpha\beta \rightarrow dq αβ→dq))
-
- [1. 数学推导](#1. 数学推导)
- [四、 反 Park 变换:两相旋转 → \rightarrow → 两相静止( d q → α β dq \rightarrow \alpha\beta dq→αβ)](#四、 反 Park 变换:两相旋转 → \rightarrow → 两相静止( d q → α β dq \rightarrow \alpha\beta dq→αβ))
- [五、Python 代码仿真](#五、Python 代码仿真)
-
-
- [(1) 时域解耦(波形对比):](#(1) 时域解耦(波形对比):)
- [(2) 空间等效(矢量圆轨迹):](#(2) 空间等效(矢量圆轨迹):)
- [(3) 滑块交互交互调试体验:](#(3) 滑块交互交互调试体验:)
-
- [六、基于 STM32F407 的工程代码实现](#六、基于 STM32F407 的工程代码实现)
-
- [1. Clark 变换代码落地](#1. Clark 变换代码落地)
- [2. Park 与反 Park 变换代码落地](#2. Park 与反 Park 变换代码落地)
- [七、 本章总结](#七、 本章总结)

📌 前言 :
在上一章中,我们理解了 FOC 的核心本质------将交流无刷电机等效为直流电机控制。要实现这一步,核心秘诀就在于坐标变换 。
本章将用最通俗的物理直觉 + 严谨的工程推导,一起攻克 Clark 与 Park 变换,并直接给出基于野火骄阳 F407(带有硬件浮点运算单元 FPU)的高效 C 语言实现代码。
一、 FOC 核心坐标系概览
在编写代码前,我们需要建立三个坐标系的清晰图像。它们如同三层不同的"观察视角":
- A − B − C A-B-C A−B−C 三相静止坐标系:
- 观察者:站在电机外面不动的你。
- 特点 :三个轴互差 120°,轴上的电流 I A , I B , I C I_A, I_B, I_C IA,IB,IC 都是随时间变化的交变正弦波。

- α − β \alpha - \beta α−β 两相静止坐标系:
- 观察者:依然是站在电机外面不动的你。
- 特点 :两个轴互相垂直(90°),电流 I α , I β I_\alpha, I_\beta Iα,Iβ 虽然解耦,但依然是正弦交流电。

- d − q d - q d−q 两相旋转坐标系:
- 观察者:坐在转子永磁体上、跟着电机一起高速旋转的"缩小的你"。
- 特点 : d d d 轴(直轴)始终对准转子磁场方向, q q q 轴(交轴)始终垂直于磁场方向。在你的视角里, I d I_d Id 和 I q I_q Iq 变成了静止不动的直流电!

二、 Clark 变换:三相静止 → \rightarrow → 两相静止( a b c → α β abc \rightarrow \alpha\beta abc→αβ)
1. 几何推导与等幅值约束
我们希望用互相垂直的 α \alpha α 轴和 β \beta β 轴来等效代替互差 120° 的 A 、 B 、 C A、B、C A、B、C 三轴。通常,我们让 α \alpha α 轴与 A A A 轴完全重合, β \beta β 轴超前 α \alpha α 轴 90°。
根据向量投影,我们可以得到 α \alpha α 和 β \beta β 轴上的分量:
I α = I A − I B ⋅ cos ( 60 ∘ ) − I C ⋅ cos ( 60 ∘ ) = I A − 1 2 I B − 1 2 I C I_\alpha = I_A - I_B \cdot \cos(60^\circ) - I_C \cdot \cos(60^\circ) = I_A - \frac{1}{2}I_B - \frac{1}{2}I_C Iα=IA−IB⋅cos(60∘)−IC⋅cos(60∘)=IA−21IB−21IC
I β = 0 + I B ⋅ sin ( 60 ∘ ) − I C ⋅ sin ( 60 ∘ ) = 3 2 I B − 3 2 I C I_\beta = 0 + I_B \cdot \sin(60^\circ) - I_C \cdot \sin(60^\circ) = \frac{\sqrt{3}}{2}I_B - \frac{\sqrt{3}}{2}I_C Iβ=0+IB⋅sin(60∘)−IC⋅sin(60∘)=23 IB−23 IC
在实际工程中,为了保证变换前后的电流幅值大小不变 (即等幅值变换),根据基尔霍夫电流定律,在三相平衡系统中满足 I A + I B + I C = 0 I_A + I_B + I_C = 0 IA+IB+IC=0(即 I B + I C = − I A I_B + I_C = -I_A IB+IC=−IA)。
代入上式进行化简,乘以等幅值系数 2 3 \frac{2}{3} 32 后,最终的 Clark 变换公式 极为精简:
I α = I A I_\alpha = I_A Iα=IA
I β = 3 3 ( I A + 2 I B ) 或 I β = 1 3 ( I B − I C ) I_\beta = \frac{\sqrt{3}}{3}(I_A + 2I_B) \quad \text{或} \quad I_\beta = \frac{1}{\sqrt{3}}(I_B - I_C) Iβ=33 (IA+2IB)或Iβ=3 1(IB−IC)
🛠️ 工程提示 :在写 C 代码时,由于三相下桥臂电阻采样更习惯拿到 I A , I B I_A, I_B IA,IB,我们通常使用包含 I A , I B I_A, I_B IA,IB 的变形公式,避免引入 I C I_C IC,从而减少运算量。
三、 Park 变换:两相静止 → \rightarrow → 两相旋转( α β → d q \alpha\beta \rightarrow dq αβ→dq)
1. 数学推导
现在我们要把视角切换到旋转的转子上。已知转子当前的电角度为 θ \theta θ(即 d d d 轴与 α \alpha α 轴的夹角)。
将静止的 I α I_\alpha Iα 和 I β I_\beta Iβ 投影到旋转的 d d d 轴和 q q q 轴上:
I d = I α ⋅ cos θ + I β ⋅ sin θ I_d = I_\alpha \cdot \cos\theta + I_\beta \cdot \sin\theta Id=Iα⋅cosθ+Iβ⋅sinθ
I q = − I α ⋅ sin θ + I β ⋅ cos θ I_q = -I_\alpha \cdot \sin\theta + I_\beta \cdot \cos\theta Iq=−Iα⋅sinθ+Iβ⋅cosθ
- 物理直觉 :通过引入 θ \theta θ,我们将旋转运动的物理量投射到了相对静止的参考系。此时算出来的 I d I_d Id 和 I q I_q Iq 在稳态下就是两个平稳的直流值。
四、 反 Park 变换:两相旋转 → \rightarrow → 两相静止( d q → α β dq \rightarrow \alpha\beta dq→αβ)
经过电流环 PI 调节器后,我们得到了 V d V_d Vd 和 V q V_q Vq(直流电压指令)。但是,SVPWM 模块需要的是静止坐标系下的电压来产生物理 PWM。所以,我们需要执行 Park 的逆运算:
V α = V d ⋅ cos θ − V q ⋅ sin θ V_\alpha = V_d \cdot \cos\theta - V_q \cdot \sin\theta Vα=Vd⋅cosθ−Vq⋅sinθ
V β = V d ⋅ sin θ + V q ⋅ cos θ V_\beta = V_d \cdot \sin\theta + V_q \cdot \cos\theta Vβ=Vd⋅sinθ+Vq⋅cosθ
⚠️ 避坑指南 :注意看清正负号!反 Park 变换中 V α V_\alpha Vα 的公式中间是减号( − - −) ,而 V β V_\beta Vβ 中间是加号( + + +)。
三个变化总结示意图:

五、Python 代码仿真
为了让复杂的矩阵投影更形象展示出来,下面使用Python的matplotlib库编写一个FOC交互式FOCus坐标变换仿真器。该仿真器支持通过滑块实时调节电机转速与电流幅值,用来同步观测空间矢量和时域波形。
python
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib.widgets import Slider
# --- 初始常数 ---
init_Amp = 1.0 # 初始幅值
init_Freq = 0.5 # 初始频率 (降低到0.5Hz,方便肉眼观察)
FPS = 50 # 帧率
sqrt3_3 = 0.577350269 # 1/sqrt(3)
# --- 创建画布 ---
# 增加画布尺寸以容纳下方的波形图和滑块
fig = plt.figure(figsize=(14, 9))
fig.canvas.manager.set_window_title('FOC Clark Transformation Interactive Simulator')
# 划分网格布局 (3行2列)
# Top row: 矢量圆图
ax_abc_vector = plt.subplot2grid((3, 2), (0, 0), rowspan=2)
ax_ab_vector = plt.subplot2grid((3, 2), (0, 1), rowspan=2)
# Bottom row: 时间波形图
ax_abc_wave = plt.subplot2grid((3, 2), (2, 0))
ax_ab_wave = plt.subplot2grid((3, 2), (2, 1))
# 调整整体布局给滑块留出底部空间
plt.subplots_adjust(bottom=0.18, hspace=0.4, wspace=0.25)
# --- 1. 左上:ABC 空间矢量图 ---
ax_abc_vector.set_title("1. ABC Stationary Frame (Vector)", fontsize=11, fontweight='bold')
ax_abc_vector.set_xlim(-1.5, 1.5)
ax_abc_vector.set_ylim(-1.5, 1.5)
ax_abc_vector.set_aspect('equal')
ax_abc_vector.grid(True, linestyle='--', alpha=0.5)
# 绘制ABC三相物理轴线 (互差120度)
ax_abc_vector.quiver(0, 0, 1.3, 0, angles='xy', scale_units='xy', scale=1, color='gray', alpha=0.5)
ax_abc_vector.text(1.35, 0, 'A-axis', color='gray')
ax_abc_vector.quiver(0, 0, 1.3 * np.cos(2 * np.pi / 3), 1.3 * np.sin(2 * np.pi / 3), angles='xy', scale_units='xy',
scale=1, color='gray', alpha=0.5)
ax_abc_vector.text(1.35 * np.cos(2 * np.pi / 3), 1.3 * np.sin(2 * np.pi / 3), 'B-axis', color='gray')
ax_abc_vector.quiver(0, 0, 1.3 * np.cos(4 * np.pi / 3), 1.3 * np.sin(4 * np.pi / 3), angles='xy', scale_units='xy',
scale=1, color='gray', alpha=0.5)
ax_abc_vector.text(1.35 * np.cos(4 * np.pi / 3), 1.3 * np.sin(4 * np.pi / 3), 'C-axis', color='gray')
vector_abc = ax_abc_vector.quiver(0, 0, 0, 0, angles='xy', scale_units='xy', scale=1, color='purple', width=0.015,
label=r'$\vec{I}_{abc}$')
trace_abc, = ax_abc_vector.plot([], [], 'purple', linestyle=':', alpha=0.6, linewidth=1.5)
ax_abc_vector.legend(loc='upper right')
# --- 2. 右上:alpha-beta 空间矢量图 ---
ax_ab_vector.set_title(r"2. $\alpha\beta$ Stationary Frame (Vector)", fontsize=11, fontweight='bold')
ax_ab_vector.set_xlim(-1.5, 1.5)
ax_ab_vector.set_ylim(-1.5, 1.5)
ax_ab_vector.set_aspect('equal')
ax_ab_vector.grid(True, linestyle='--', alpha=0.5)
ax_ab_vector.axhline(0, color='gray', alpha=0.5)
ax_ab_vector.axvline(0, color='gray', alpha=0.5)
ax_ab_vector.text(1.3, 0.05, r'$\alpha$-axis', color='gray')
ax_ab_vector.text(0.05, 1.3, r'$\beta$-axis', color='gray')
vector_ab = ax_ab_vector.quiver(0, 0, 0, 0, angles='xy', scale_units='xy', scale=1, color='darkorange', width=0.015,
label=r'$\vec{I}_{\alpha\beta}$')
trace_ab, = ax_ab_vector.plot([], [], 'darkorange', linestyle=':', alpha=0.6, linewidth=1.5)
ax_ab_vector.legend(loc='upper right')
# --- 3. 左下:ABC 三相电流时间波形 ---
ax_abc_wave.set_title("3. ABC Phase Currents (Time Domain)", fontsize=10)
ax_abc_wave.set_xlim(0, 4.0) # 显示4秒的历史波形
ax_abc_wave.set_ylim(-1.5, 1.5)
ax_abc_wave.grid(True, linestyle='--', alpha=0.5)
ax_abc_wave.set_ylabel("Current (A)")
wave_Ia, = ax_abc_wave.plot([], [], 'r-', label=r'$I_A$')
wave_Ib, = ax_abc_wave.plot([], [], 'g-', label=r'$I_B$')
wave_Ic, = ax_abc_wave.plot([], [], 'b-', label=r'$I_C$')
ax_abc_wave.legend(loc='upper right', fontsize='small')
# --- 4. 右下:alpha-beta 电流时间波形 ---
ax_ab_wave.set_title(r"4. $\alpha\beta$ Currents (Time Domain)", fontsize=10)
ax_ab_wave.set_xlim(0, 4.0)
ax_ab_wave.set_ylim(-1.5, 1.5)
ax_ab_wave.grid(True, linestyle='--', alpha=0.5)
wave_Ialpha, = ax_ab_wave.plot([], [], 'r-', label=r'$I_\alpha$')
wave_Ibeta, = ax_ab_wave.plot([], [], 'b-', label=r'$I/\beta$')
ax_ab_wave.legend(loc='upper right', fontsize='small')
# --- 添加交互滑块 (Sliders) ---
ax_slider_freq = plt.axes([0.15, 0.08, 0.7, 0.03])
ax_slider_amp = plt.axes([0.15, 0.03, 0.7, 0.03])
slider_freq = Slider(ax_slider_freq, 'Speed (Freq Hz)', 0.0, 3.0, valinit=init_Freq, valfmt='%1.2f Hz')
slider_amp = Slider(ax_slider_amp, 'Current Amp (A)', 0.1, 1.5, valinit=init_Amp, valfmt='%1.2f A')
# --- 动态数据追踪变量 ---
time_history = []
Ia_history, Ib_history, Ic_history = [], [], []
# 修复:左边两个变量,右边对应两个空列表
Ialpha_history, Ibeta_history = [], []
trace_x_abc, trace_y_abc = [], []
trace_x_ab, trace_y_ab = [], []
current_theta = 0.0 # 积分累计电角度,防止改频率时波形跳变
t_global = 0.0 # 全局时间计数
# --- 动画更新核心函数 ---
def update(frame):
global current_theta, t_global
# 获取滑块当前实时值
freq = slider_freq.val
amp = slider_amp.val
# 计算步进时间
dt = 1.0 / FPS
t_global += dt
# 根据当前频率累加角度: d_theta = 2 * pi * f * dt
current_theta += 2 * np.pi * freq * dt
# 1. 计算三相平衡交流电指令
Ia = amp * np.cos(current_theta)
Ib = amp * np.cos(current_theta - 2 * np.pi / 3)
Ic = amp * np.cos(current_theta + 2 * np.pi / 3)
# 2. 执行等幅值 Clark 变换
Ialpha = Ia
Ibeta = (Ia + 2.0 * Ib) * sqrt3_3
# 3. 物理空间合成矢量(ABC)
res_abc_x = Ia + Ib * np.cos(2 * np.pi / 3) + Ic * np.cos(4 * np.pi / 3)
res_abc_y = 0 + Ib * np.sin(2 * np.pi / 3) + Ic * np.sin(4 * np.pi / 3)
# 4. 缓存历史数据用于波形绘制 (限制最多保存200点,防止内存溢出)
time_history.append(t_global)
Ia_history.append(Ia)
Ib_history.append(Ib)
Ic_history.append(Ic)
Ialpha_history.append(Ialpha)
Ibeta_history.append(Ibeta)
if len(time_history) > 200:
time_history.pop(0)
Ia_history.pop(0)
Ib_history.pop(0)
Ic_history.pop(0)
Ialpha_history.pop(0)
Ibeta_history.pop(0)
# 5. 缓存矢量旋转轨迹
trace_x_abc.append(res_abc_x)
trace_y_abc.append(res_abc_y)
trace_x_ab.append(Ialpha)
trace_y_ab.append(Ibeta)
if len(trace_x_abc) > 40: # 轨迹只保留最近40帧
trace_x_abc.pop(0);
trace_y_abc.pop(0)
trace_x_ab.pop(0);
trace_y_ab.pop(0)
# --- 刷新图形元素 ---
# 更新上方矢量箭头
vector_abc.set_UVC(res_abc_x, res_abc_y)
vector_ab.set_UVC(Ialpha, Ibeta)
# 更新上方矢量圆圈轨迹
trace_abc.set_data(trace_x_abc, trace_y_abc)
trace_ab.set_data(trace_x_ab, trace_y_ab)
# 更新下方波形图数据
wave_Ia.set_data(time_history, Ia_history)
wave_Ib.set_data(time_history, Ib_history)
wave_Ic.set_data(time_history, Ic_history)
wave_Ialpha.set_data(time_history, Ialpha_history)
wave_Ibeta.set_data(time_history, Ibeta_history)
# 动态调整下方波形图的时间轴 X 轴视窗
if t_global > 4.0:
ax_abc_wave.set_xlim(t_global - 4.0, t_global)
ax_ab_wave.set_xlim(t_global - 4.0, t_global)
else:
ax_abc_wave.set_xlim(0, 4.0)
ax_ab_wave.set_xlim(0, 4.0)
return (vector_abc, vector_ab, trace_abc, trace_ab,
wave_Ia, wave_Ib, wave_Ic, wave_Ialpha, wave_Ibeta)
# --- 启动动画 ---
ani = FuncAnimation(fig, update, frames=None, blit=False, interval=1000 / FPS, cache_frame_data=False)
plt.show()

运行该 Python 脚本后,我们可以通过交互界面直观地印证 Clark 变换的几个核心硬核结论:
(1) 时域解耦(波形对比):
- 观察左下角【图3】:三相平衡电流 I A , I B , I C I_A, I_B, I_C IA,IB,IC 彼此在时间轴上互差 120 ∘ 120^\circ 120∘ 电角度,幅值均为滑块设定的 A m p Amp Amp。
- 观察右下角【图4】:经 Clark 变换后,输出的 I α I_\alpha Iα 与基准 I A I_A IA 曲线完全重合(这完美契合了数学推导中 I α = I A I_\alpha = I_A Iα=IA 的简便公式)。而 I β I_\beta Iβ 则蜕变成了一个在相位上精准超前 I α I_\alpha Iα 恰好 90 ∘ 90^\circ 90∘ 的标准正弦波。
- 结论:Clark 变换成功将三路非正交的 120 ∘ 120^\circ 120∘ 交流量,解耦为了两路空间正交(互差 90 ∘ 90^\circ 90∘)的直角坐标系交流量。
(2) 空间等效(矢量圆轨迹):
- 观察左上【图1】(紫色箭头 I ⃗ a b c \vec{I}{abc} I abc)与右上【图2】(橘色箭头 I ⃗ α β \vec{I}{\alpha\beta} I αβ):随着时间推移,两边的空间合成矢量都在各自的坐标系中顺时针做匀速圆周旋转。
- 细心对比可以发现,无论是旋转的角度(相位),还是旋转轨迹圆的半径(幅值),两边都完全一模一样!
- 物理本质:这通过图形化铁证证明了等幅值约束 Clark 变换的真谛------变换不仅没有改变合成磁场的旋转特性,而且保持了"在数值上变换前后的电流幅值完全相等",这对后续我们在 MCU 内部设定电流采样限制(如保护阈值)和调试 PI 控制器提供了极大便利!
(3) 滑块交互交互调试体验:
尝试将底部的 Speed 滑块拖动至 0.00 Hz:电机瞬间静止,此时下方的时域正弦波停止向右滚动。你可以清晰看到:当物理 A 轴电流( I A I_A IA)达到正向最大值时,B、C 两相电流正好处于负的 1 2 \frac{1}{2} 21 倍幅值处,它们在空间上共同合成了方向直指 α \alpha α 轴正方向的旋转矢量。
有了这两路完美的、互差 90 ∘ 90^\circ 90∘ 的静止直角交流电 I α , I β I_\alpha, I_\beta Iα,Iβ 后,我们已经成功解决了线圈在空间上的不便利性。现在,最关键的挑战来了:虽然空间解耦了,但这两个物理量依旧是随时间高频变化的正弦交流电,PI 控制器对交流电的跟踪效果很差。为了解决这个问题,我们需要进入下一级视角------坐上高速旋转的转子,用 Park 变换 将其"驯服"为直流电!
六、基于 STM32F407 的工程代码实现
野火骄阳 F407 搭载了 Cortex-M4 核心,支持硬件浮点数运算(FPU)。为了追求极致的执行效率,我们在编写 FOC 算法时,应尽量使用 float 类型,并调用标准的 arm_math.h 库或高效的硬件三角函数。
这里我们定义一个 FOC 的核心结构体,用于统一管理变量:
c
typedef struct {
// 输入的三相电流
float Ia;
float Ib;
float Ic;
// Clark 变换输出
float Ialpha;
float Ibeta;
// Park 变换输出
float Id;
float Iq;
// 电流环 PI 输入的参考目标值
float Id_ref;
float Iq_ref;
// 电流环 PI 输出的电压指令
float Vd;
float Vq;
// 反 Park 变换输出
float Valpha;
float Vbeta;
// 当前转子电角度(弧度制: 0 ~ 2*PI)
float theta;
float sin_theta;
float cos_theta;
} FOC_Ctrl_t;
FOC_Ctrl_t g_foc_ctrl; // 全局 FOC 控制结构体
1. Clark 变换代码落地
c
#define SQRT3_3 0.577350269f // 1/sqrt(3) 的预计算常数,避免在中断中做除法
/**
* @brief 克拉克变换 (Clark Transformation)
* @param foc: FOC控制结构体指针
* @note 输入: foc->Ia, foc->Ib 输出: foc->Ialpha, foc->Ibeta
*/
void FOC_Clark(FOC_Ctrl_t *foc)
{
// 等幅值 Clark 变换简化公式
foc->Ialpha = foc->Ia;
foc->Ibeta = (foc->Ia + 2.0f * foc->Ib) * SQRT3_3;
}
2. Park 与反 Park 变换代码落地
c
#include "arm_math.h" // 调用库函数计算正余弦
/**
* @brief 帕克变换 (Park Transformation)
*/
void FOC_Park(FOC_Ctrl_t *foc)
{
// 提前计算好当前角度的正余弦值(也可使用查表法优化)
foc->sin_theta = arm_sin_f32(foc->theta);
foc->cos_theta = arm_cos_f32(foc->theta);
// 核心公式映射
foc->Id = foc->Ialpha * foc->cos_theta + foc->Ibeta * foc->sin_theta;
foc->Iq = -foc->Ialpha * foc->sin_theta + foc->Ibeta * foc->cos_theta;
}
/**
* @brief 反帕克变换 (Inverse Park Transformation)
*/
void FOC_InvPark(FOC_Ctrl_t *foc)
{
// 注意中间的正负号,别和 Park 变换搞混了
foc->Valpha = foc->Vd * foc->cos_theta - foc->Vq * foc->sin_theta;
foc->Vbeta = foc->Vd * foc->sin_theta + foc->Vq * foc->cos_theta;
}
七、 本章总结
- Clark 变换 完成了线圈空间的精简( 3 3 3 轴变 2 2 2 轴),它不需要角度参与,只负责空间解耦。
- Park 变换 完成了物理视角的跨越(静止变旋转),必须传入精准的转子电角度 θ \theta θ,负责把交流电提炼为直流电。
- 反 Park 变换 是控制输出的桥梁,负责将 PI 调节器算出的 V d , V q V_d, V_q Vd,Vq 直流指令还原回控制定子的 V α , V β V_\alpha, V_\beta Vα,Vβ 交流电压。
三大变换在每个 PWM 周期(通常为 50 μ s 50\mu s 50μs 或 100 μ s 100\mu s 100μs)的定时器中断里会被高频调用,因此在代码中严禁使用动态除法 ,所有根号运算必须提前定义为常数(如 SQRT3_3),以腾出 CPU 耗时给后面的观测器算法。
下一章,我们将正式接入 PID 控制器,把本章解耦出来的 I d I_d Id 和 I q I_q Iq 锁死在闭环中,实现 第16章:DQ双轴电流环闭环控制。
本系列教程学习资源来自野火官方电机教程,部分代码及博客内容摘自官方教程。
本系列教程使用野火骄阳 F407 开发板及野火有刷/无刷驱动板。
适配场景:家电工业级FOC双闭环方案变频开发