1、电机
1、异步电机(感应电机)
1、工作原理
感应电机的定子绕组通入三相交流电,产生旋转磁场。这个旋转磁场在转子上感应出电流(类似变压器的原理),再通过电磁力推动转子旋转。
⚠ 转子转速 nr总是低于定子旋转磁场速度 ns,这就是“异步”的由来。

定子产生旋转磁场 → 转子感应电流 → 形成电磁力推动转子转动,但转速始终稍低于同步速度(有转差)
-
感应电机(异步电机)\的转子是\短路绕组,转子磁场是感应出来的**。
-
由于电磁感应原理,转子转速总是比定子旋转磁场慢一点,即有转差,否则不会产生感应电流。
-
但永磁同步电机没有感应电流,直接由永磁体提供磁场,因此不会有转差,转子和定子磁场严格同步。
交流感应电机(异步电机)

2、永磁同步电机
永磁同步电机分为正弦波永磁同步电机和方波驱动的永磁同步电机,其作用主要为车辆行驶提供驱动力,是电动汽车的动力装置。
1、组成
永磁同步电机主要由定子和转子、端盖、轴承、旋转变压器等部件组成。

-
定子:是电动机或发电机中静止不动的部分,其主要作用是产生旋转磁场。在电动机中,定子通过通电的绕组产生旋转磁场,这个磁场驱动转子旋转,从而将电能转换为机械能。在发电机中,定子则用于产生电能,供应负载使用。
-
转子:指由轴承支撑的旋转体。光盘等自身没有旋转轴的物体,当它采用刚性连接或附加轴时,可视为一个转子。
-
轴承:它的主要功能是支撑机械旋转体,降低其运动过程中的摩擦系数(friction coefficient),并保证其回转精度(accuracy)。
-
旋转变压器:是一种电磁式传感器,又称同步分解器。它是一种测量角度用的小型交流电动机,用来测量旋转物体的转轴角位移和角速度,由定子和转子组成。其中定子绕组作为变压器的原边,接受励磁电压,励磁频率通常用400、3000及5000HZ等。转子绕组作为变压器的副边,通过电磁耦合得到感应电压。
-
电机的温度传感器(热敏电阻):热敏电阻是缠绕在定子绕组里面,监测电机的温度。
2、工作原理
永磁同步电机中的永磁是指电机的转子是永磁铁(永磁体),同步是指转子频率与定子频率是一样的也就是没有转差。,电机是指将电能转化为机械能的装置。
1、定子频率
-
定子绕组通入三相交流电,产生一个旋转磁场。
-
这个旋转磁场的转速称为同步转速 Ns,由电源频率 f 决定(该公式使用所有的三相交流电电机):
2、转子频率
-
永磁同步电机的转子是永磁体,它不会自己产生感应电流,而是被定子磁场带动。
-
由于转子上的磁极被定子磁场吸引,转子和定子磁场同步旋转,所以转子机械转速等于定子的同步转速。
换句话说,定子磁场的旋转频率(电角速度)和转子机械转速是一样的,所以叫“同步”电机!
3、步进电机
- 按固定步长一步步旋转(每次给一个脉冲就转动一个固定角度)
- 多相绕组,控制器逐步切换通电相序
4、伺服电机
原理:
- 可以是 永磁同步电机 或 有刷/无刷直流电机
- 关键是闭环控制:位置、速度、力矩由编码器反馈调节
5、无刷电机
原理:
- 使用电子换向器代替碳刷(霍尔传感器检测位置)
- 实质上是直流控制的三相永磁同步电机
6、有刷直流电机
原理:
- 通过碳刷+换向器机械换向
- 施加直流电压即可转动,简单易用
7、直流电机
是统称,包含:
- 有刷直流电机(Brushed DC)
- 无刷直流电机(BLDC)
原理:
电压直接控制电流 → 产生磁场 → 产生力矩
不需要三相交流系统
8、异步电机和永磁同步电机区别
| 比较项 | 感应电机(异步电机) | 永磁同步电机(PMSM) |
|---|---|---|
| 工作原理 | 通过定子旋转磁场在转子中感应电流,形成电磁力推动转子旋转(有转差) | 通过定子旋转磁场直接驱动转子,转子由永磁体产生磁场(无转差) |
| 转子类型 | 鼠笼式或绕线式转子 | 由永磁体(如钕铁硼)构成的转子 |
| 转速关系 | 转子转速 ( n_r ) 总是小于定子同步转速 ( n_s )(有转差) | 转子转速 ( n_r ) 与同步转速 ( n_s ) 完全相同(无转差) |
| 效率 | 相对较低(因为有转差导致额外损耗) | 相对较高(无转差,损耗较少) |
| 控制难度 | 直接接电网可运行,无需复杂控制 | 需要驱动器控制,才能正常启动和运行 |
| 启动方式 | 直接启动(DOL)、星三角启动、变频启动 | 需要变频器(FOC/矢量控制)进行启动 |
| 结构 | 结构简单、耐用,转子无磁体,制造成本较低 | 需要永磁体,制造成本较高 |
| 维护成本 | 低,因无永磁体,无励磁绕组,维护简单 | 略高,永磁体可能受高温或电磁干扰影响 |
| 适用场景 | 风机、水泵、压缩机、普通电机 | 电动汽车、机器人、伺服电机、高性能工业设备 |
| 调速能力 | 变频调速(V/F 控制)或矢量控制 | 需要矢量控制(FOC),响应更快,控制精确 |
| 扭矩特性 | 低速时扭矩较弱,需要额外启动手段 | 低速时仍可输出较大扭矩 |
| 过载能力 | 允许短时过载 | 受永磁体限制,过载能力一般 |
| 典型应用 | 工业电机、家用电器(洗衣机、风扇、空调) | 电动车、伺服系统、航天航空 |
2、FOC
1、简单介绍和总结
目的:能让 三相交流电机(如 PMSM(永磁同步电机)、BLDC(无刷直流电机))像 直流电机 一样精准控制扭矩和速度。
核心目标:
-
让 定子磁场 始终和 转子磁场 正交(90°),保证最大扭矩输出。
-
采用 坐标变换(Clarke、Park 变换),将 三相交流信号 变成 直流信号,简化控制。
控制环架构:
位置环(外环)→ 速度环(中环)→ 电流环(内环)
- 位置环:计算目标速度(仅在位置控制模式下使用)。
- 速度环:计算目标力矩(在速度控制模式下使用)。
- 电流环:计算目标 q 轴电流并控制 PWM。
2、FOC 详细计算流程
1、AD转换获取电流值Ia和Ib,
2、通过Clark变换得到Iα和Iβ ,
3、获取电机角度,通过Park变换得到Id和Iq,
4、Id、Iq不能突变,同时为减少干扰,做平滑滤波,
5、Id、Iq与设定值比较,通过PID运算得到Vd 和Vq,
Step 1:三相电流采样

float Ia = Read_Current_A();
float Ib = Read_Current_B();
float Ic = - (Ia + Ib); // 计算第三相电流
Step 2:Clarke 变换(三相 → αβ 轴)

float I_alpha = Ia;
float I_beta = (Ia + 2 * Ib) / sqrt(3);

Step 3:Park 变换(αβ 轴 → dq 轴)

我们一通操作将转子磁链进行了解耦,分解为了转子旋转的径向和切向这两个方向的变量:
float I_d = I_alpha * cos(theta) + I_beta * sin(theta); //不需要的,我们希望尽可能把它控制为0
float I_q = -I_alpha * sin(theta) + I_beta * cos(theta); //需要的,代表了期望的力矩输出
其中 θ是 电机转子角度,可以通过 编码器 或 反电动势估算 获取。
Step 4:位置环 、速度环 、电流环控制
应该通过位置环控制计算出目标速度,然后目标速度通过PI计算出目标电流,通过电流环再计算出PWM提供足够的扭矩
场景:
-
位置控制时采用 位置环+电流环 控制(原因:但是在位置控制模式的时候,电机的转速会很慢,这时候用平均测速法会存在非常大的误差(转子不动或者动地很慢,编码器就没有输出或者只输出1、2个脉冲))
-
位置环(外环)PI 控制器:根据目标位置和当前电机位置之间的误差,计算出目标速度。目标位置是最终的期望值,位置环的任务是将其转化为目标速度。
// 位置环 PI 控制 float Position_PI_Controller(float angle_ref, float angle, PI_Controller *pos_pi) { float error = angle_ref - angle; // 计算位置误差 pos_pi->integral += error * pos_pi->Ki; // 计算积分项 return pos_pi->Kp * error + pos_pi->integral; // 计算目标速度 speed_ref } // 运行位置环 void PositionControlLoop() { float angle = ReadEncoderTheta(); // 读取当前编码器位置(角度) speed_ref = Position_PI_Controller(angle_ref, angle, &Position_PI); // 计算目标速度 }- angle_ref:目标位置(角度)
- angle:当前电机位置
- 输出 speed_ref:目标速度(传给速度环)
-
速度环(中环):根据目标速度和电机实际速度之间的误差,计算出目标电流。目标速度决定了电机旋转的快慢,速度环的任务是确保电机以期望速度运行。
// 速度环 PI 控制 float Speed_PI_Controller(float speed_ref, float speed, PI_Controller *speed_pi) { float error = speed_ref - speed; // 计算速度误差 speed_pi->integral += error * speed_pi->Ki; // 计算积分项 return speed_pi->Kp * error + speed_pi->integral; // 输出 Iq_ref } // 运行速度环 void SpeedControlLoop() { float speed = ComputeMotorSpeed(); // 计算当前速度 Iq_ref = Speed_PI_Controller(speed_ref, speed, &Speed_PI); // 计算目标 Iq }- speed_ref:目标速度(从位置环来的)
- speed:当前电机速度
- 输出 Iq_ref:目标转矩电流(传给电流环)
-
电流环(内环):电流环计算出所需的电流来产生足够的扭矩以实现目标速度。电流环是FOC算法中的最后一个环节,它的目标是调整电流,使电机以所需的速度运行。
// 电流环 PI 控制 float Current_PI_Controller(float ref, float feedback, PI_Controller *current_pi) { float error = ref - feedback; // 计算电流误差 current_pi->integral += error * current_pi->Ki; // 计算积分项 return current_pi->Kp * error + current_pi->integral; // 输出 Vq 或 Vd } // 运行电流环 void CurrentControlLoop() { // Clarke 变换(Ia, Ib, Ic → I_alpha, I_beta) ClarkeTransform(Ia, Ib, Ic, &I_alpha, &I_beta); // Park 变换(I_alpha, I_beta → I_d, I_q) ParkTransform(I_alpha, I_beta, theta, &I_d, &I_q); // 计算 Vd, Vq V_d = Current_PI_Controller(Id_ref, I_d, &Id_PI); // 磁场电流控制 V_q = Current_PI_Controller(Iq_ref, I_q, &Iq_PI); // 转矩电流控制 // 逆 Park 变换(V_d, V_q → V_alpha, V_beta) InverseParkTransform(V_d, V_q, theta, &V_alpha, &V_beta); // SVPWM 计算 & 设置 PWM SVPWM(V_alpha, V_beta); }

float PI_Controller(float ref, float feedback, float Kp, float Ki, float *integral)
{
float error = ref - feedback;
*integral += error * Ki;
return Kp * error + *integral;
}
// 计算 Vd 和 Vq
float Vd = PI_Controller(Id_ref, I_d, Kp_d, Ki_d, &integral_d);
float Vq = PI_Controller(Iq_ref, I_q, Kp_q, Ki_q, &integral_q)
ref(目标值):希望达到的电流值(设定值)。feedback(反馈值):当前测量的电流值(电流采样得到的)。Kp(比例系数):PI 控制器的比例参数。Ki(积分系数):PI 控制器的积分参数。integral(积分项):用于累积误差,实现积分控制。
Step 5:逆 Park 变换(dq 轴 → αβ 轴)

float V_alpha = Vd * cos(theta) - Vq * sin(theta);
float V_beta = Vd * sin(theta) + Vq * cos(theta);
Step 6:SVPWM(空间矢量脉宽调制)

void SVPWM(float V_alpha, float V_beta) {
int sector = ComputeSector(V_alpha, V_beta);
ComputeDutyCycles(sector, V_alpha, V_beta);
SetPWM(T1, T2, T0);
}
这可以通过 现成的库(比如 ST 代码库 或 TI FOC 库),也可以直接写
总体示例代码
// ============================== 利用实时的电机三相电流精准控制电机性能 ========================================
I_a, I_b, I_c 是实时的三相电流
// ============================== 保持电机在目标位置 ==================================================
#include "stm32f4xx_hal.h"
#include <math.h>
// 电机参数
#define MOTOR_POLE_PAIR 7
#define PI 3.14159265359
// 控制器参数
#define Kp_Position 10.0fc
#define Ki_Position 1.0f
#define Kp_Iq 1.0f
#define Ki_Iq 0.1f
// 假设获取电机位置的函数
extern float GetMotorPosition(); // 获取电机位置(通过编码器等)
// Clark 变换:三相电流 -> αβ 坐标系
void ClarkTransform(float I_a, float I_b, float I_c, float* I_alpha, float* I_beta) {
*I_alpha = I_a;
*I_beta = (I_a + 2 * I_b) / sqrt(3.0f);
}
// Park 变换:αβ -> dq 坐标系
void ParkTransform(float I_alpha, float I_beta, float theta, float* I_d, float* I_q) {
*I_d = I_alpha * cos(theta) + I_beta * sin(theta);
*I_q = -I_alpha * sin(theta) + I_beta * cos(theta);
}
// 位置环 PI 控制
float PositionPIController(float target_position, float current_position, float* integral) {
float error = target_position - current_position;
*integral += error;
return Kp_Position * error + Ki_Position * (*integral);
}
// 控制电机的函数
void MotorControl() {
// 获取电机当前位置
float current_position = GetMotorPosition(); // 电机当前位置(通过编码器)
// 设置目标位置
float target_position = 1.0f; // 目标位置(假设目标位置为 1.0 位置单位)
// 使用位置环控制计算电压
static float integral_position = 0.0f;
float voltage = PositionPIController(target_position, current_position, &integral_position);
// 控制电流(使用位置环计算的电压,进行电流调节等)
float I_d = 0.0f; // 假设磁场控制电流保持为 0
float I_q = voltage; // 转矩控制电流根据电压变化
// Clark 变换和 Park 变换的电流控制
float I_alpha, I_beta;
ClarkTransform(I_a, I_b, I_c, &I_alpha, &I_beta);
float motor_angle = current_position; // 当前位置的电机角度
float V_d, V_q;
ParkTransform(I_alpha, I_beta, motor_angle, &V_d, &V_q);
// 逆 Park 变换:计算最终电压(V_d, V_q)
float V_alpha, V_beta;
InverseParkTransform(V_d, V_q, motor_angle, &V_alpha, &V_beta);
// PWM 输出
GeneratePWM(V_alpha, V_beta);
}
// 主程序
int main(void) {
HAL_Init(); // 初始化 HAL 库
// 进行其他初始化,设置时钟,GPIO,PWM 输出等
while (1) {
// 进行电机控制
MotorControl();
// 延时
HAL_Delay(10); // 模拟实时控制
}
}
// ========================== 保持电机在目标转速 ===================================================
// 速度环 PI 控制
float SpeedPIController(float target_speed, float current_speed, float* integral) {
float error = target_speed - current_speed;
*integral += error;
return Kp_Speed * error + Ki_Speed * (*integral);
}
// 控制电机的函数
void MotorControl() {
// 获取电机的速度(假设通过编码器获取速度)
float current_speed = GetMotorSpeed(); // 电机当前速度
// 设置目标速度
float target_speed = 1000.0f; // 假设目标速度为 1000 rpm
// 使用速度环控制计算电压
static float integral_speed = 0.0f;
float voltage = SpeedPIController(target_speed, current_speed, &integral_speed);
// 控制电流(通过速度控制调整电流)
float I_d = 0.0f; // 磁场电流
float I_q = voltage; // 转矩电流
// Clark 变换和 Park 变换的电流控制
float I_alpha, I_beta;
ClarkTransform(I_a, I_b, I_c, &I_alpha, &I_beta);
float motor_angle = GetMotorPosition(); // 获取电机角度
float V_d, V_q;
ParkTransform(I_alpha, I_beta, motor_angle, &V_d, &V_q);
// 逆 Park 变换:计算最终电压(V_d, V_q)
float V_alpha, V_beta;
InverseParkTransform(V_d, V_q, motor_angle, &V_alpha, &V_beta);
// PWM 输出
GeneratePWM(V_alpha, V_beta);
}
// 主程序
int main(void) {
HAL_Init(); // 初始化 HAL 库
// 进行其他初始化,设置时钟,GPIO,PWM 输出等
while (1) {
// 进行电机控制
MotorControl();
// 延时
HAL_Delay(10); // 模拟实时控制
}
}
// ========================== 给定目标速度,和目标位置 稳定到固定位置的示例 ===========================================
#include "stm32f4xx_hal.h"
#include <math.h>
// 定义常量
#define PI 3.14159265358979
#define MAX_VOLTAGE 24.0
// 电流目标(由上层控制给定)
float target_current_q = 0.0; // 转矩控制
float target_current_d = 0.0; // 磁场控制
// 当前电流(三相电流)
float I_a = 0.0, I_b = 0.0, I_c = 0.0;
// 当前电流在αβ坐标系下的分量
float I_alpha = 0.0, I_beta = 0.0;
// 当前电流在dq坐标系下的分量
float I_d = 0.0, I_q = 0.0;
// 转子角度(假设实时角度是通过编码器读取)
float theta = 0.0;
// PI 控制器的积分变量
float integral_d = 0.0, integral_q = 0.0;
// 电流环控制的 PI 参数
float Kp_d = 1.0, Ki_d = 0.1, Kp_q = 1.0, Ki_q = 0.1;
// 位置环控制的参数(用来根据目标位置控制目标速度)
float position_error = 0.0, target_position = 0.0, current_position = 0.0;
float target_velocity = 0.0;
// Clark 变换:三相电流 → αβ 坐标系
void clark_transform() {
I_alpha = I_a;
I_beta = (1.0 / sqrt(3)) * (I_a + 2.0 * I_b); // Clark 变换公式
}
// Park 变换:αβ 坐标系 → dq 坐标系
void park_transform() {
I_d = I_alpha * cos(theta) + I_beta * sin(theta);
I_q = -I_alpha * sin(theta) + I_beta * cos(theta);
}
// PI 控制:调节 d 轴和 q 轴电流
void current_control() {
// d 轴电流控制 (保持磁场)
float error_d = target_current_d - I_d;
integral_d += error_d;
float V_d = Kp_d * error_d + Ki_d * integral_d;
// q 轴电流控制 (控制转矩)
float error_q = target_current_q - I_q;
integral_q += error_q;
float V_q = Kp_q * error_q + Ki_q * integral_q;
// 逆 Park 变换:dq → αβ
float V_alpha = V_d * cos(theta) - V_q * sin(theta);
float V_beta = V_d * sin(theta) + V_q * cos(theta);
// 计算SVPWM (根据V_alpha, V_beta计算PWM占空比)
sv_pwm_calculation(V_alpha, V_beta);
}
// SVPWM 计算 (生成PWM信号)
void sv_pwm_calculation(float V_alpha, float V_beta) {
// 使用空间矢量脉宽调制计算三相电压 (V_a, V_b, V_c)
// 这里只是简单的伪代码,实际实现需要根据V_alpha, V_beta计算PWM占空比
float V_max = sqrt(V_alpha * V_alpha + V_beta * V_beta);
float V_a = V_max; // 简化的计算
float V_b = V_max; // 简化的计算
float V_c = V_max; // 简化的计算
// 通过 PWM 驱动电机
drive_motor(V_a, V_b, V_c);
}
// 驱动电机 (PWM 输出)
void drive_motor(float V_a, float V_b, float V_c) {
// 将电压信号转换为PWM信号输出到逆变器
// 这里只是伪代码,实际中需要用PWM生成模块来驱动电机
HAL_PWM_SetDutyCycle(TIM_CHANNEL_1, V_a); // 假设TIM1作为PWM输出通道
HAL_PWM_SetDutyCycle(TIM_CHANNEL_2, V_b); // 假设TIM2作为PWM输出通道
HAL_PWM_SetDutyCycle(TIM_CHANNEL_3, V_c); // 假设TIM3作为PWM输出通道
}
// 位置环控制
void position_control() {
// 目标位置与当前电机位置进行比较,计算出目标速度
position_error = target_position - current_position;
target_velocity = position_error * 0.1; // 比例控制
// 目标速度控制,调节目标电流
velocity_control();
}
// 速度环控制
void velocity_control() {
// 目标速度与当前电机速度进行比较
float speed_error = target_velocity - current_velocity;
target_current_q = speed_error * 0.1; // 比例控制
// 调用电流控制
current_control();
}
int main(void) {
// 初始化STM32硬件和外设...
// 主循环
while (1) {
// 位置环控制
position_control();
// 获取当前电流值(I_a, I_b, I_c)并转换为 αβ 坐标系
clark_transform();
// 将 αβ 坐标系电流转换为 dq 坐标系
park_transform();
// 使用PI控制器调节电流并转换回 αβ 坐标系电压
current_control();
HAL_Delay(10); // 10ms 控制周期
}
}




