基于TI C2000 DSP的永磁同步电机(PMSM)无传感器控制程序,采用滑模观测器(SMO)+ 模型参考自适应(MRAS) 方案
一、系统架构
三相电流 → 3/2变换 → 滑模观测器 → 位置/速度估算
↓ ↓ ↓
ADC Clarke变换 锁相环(PLL)
↓ ↓ ↓
电流采样 αβ电流 位置反馈
↓ ↓ ↓
速度环PID → 电流环PID → 反Park变换
↓ ↓ ↓
电流给定 dq电流控制 SVPWM生成
↓ ↓ ↓
PWM输出 → 逆变器 → PMSM
二、核心算法选择
| 算法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 滑模观测器 | 鲁棒性强,计算量小 | 高频抖振 | 中高速运行(>5%额定) |
| 模型参考自适应 | 平滑,无抖振 | 依赖电机参数 | 全速范围 |
| 高频注入 | 零低速有效 | 噪声大,计算复杂 | 零低速启动 |
| 磁链观测器 | 精度高 | 对参数敏感 | 有编码器对比 |
推荐方案:SMO + 高频注入启动 + MRAS平滑过渡
三、DSP程序架构
1. 文件结构
PMSM_Sensorless/
├── Source/
│ ├── main.c # 主程序
│ ├── ADC.c # ADC采样处理
│ ├── SMO.c # 滑模观测器
│ ├── MRAS.c # 模型参考自适应
│ ├── HFI.c # 高频注入
│ ├── PLL.c # 锁相环
│ ├── FOC.c # 磁场定向控制
│ ├── SVPWM.c # SVPWM生成
│ ├── PID.c # PID控制器
│ └── Protection.c # 保护功能
├── Include/ # 头文件
└── DSP2833x_Device.h # DSP寄存器定义
四、核心数据结构
// PMSM_Sensorless.h
#ifndef PMSM_SENSORLESS_H
#define PMSM_SENSORLESS_H
#include "DSP2833x_Device.h"
// 电机参数结构体
typedef struct {
float Rs; // 定子电阻 (Ω)
float Ld; // d轴电感 (H)
float Lq; // q轴电感 (H)
float lambda_f; // 永磁体磁链 (Wb)
float J; // 转动惯量 (kg·m²)
float B; // 阻尼系数
float pole_pairs; // 极对数
float rated_speed; // 额定转速 (rpm)
float rated_current; // 额定电流 (A)
} Motor_Params_t;
// 观测器结构体
typedef struct {
float theta_est; // 估算角度 (rad)
float omega_est; // 估算速度 (rad/s)
float alpha; // 滑模增益
float k_slide; // 滑模系数
float z_alpha; // α轴滑模变量
float z_beta; // β轴滑模变量
float e_alpha; // α轴反电动势
float e_beta; // β轴反电动势
float lpf_alpha; // α轴低通滤波
float lpf_beta; // β轴低通滤波
} SMO_Observer_t;
// 控制系统结构体
typedef struct {
float id_ref; // d轴电流参考
float iq_ref; // q轴电流参考
float id_fb; // d轴电流反馈
float iq_fb; // q轴电流反馈
float vd_ref; // d轴电压参考
float vq_ref; // q轴电压参考
float speed_ref; // 速度参考 (rpm)
float speed_fb; // 速度反馈 (rpm)
float theta; // 电角度 (rad)
float omega_e; // 电角速度 (rad/s)
} FOC_Control_t;
// 全局变量声明
extern Motor_Params_t motor;
extern SMO_Observer_t smo;
extern FOC_Control_t foc;
#endif
五、滑模观测器核心代码
// SMO.c
#include "PMSM_Sensorless.h"
#include "math.h"
// 电机参数(示例值)
Motor_Params_t motor = {
.Rs = 0.5f, // 0.5Ω
.Ld = 0.001f, // 1mH
.Lq = 0.001f, // 1mH
.lambda_f = 0.1f, // 0.1Wb
.pole_pairs = 4, // 4对极
.rated_speed = 3000 // 3000rpm
};
SMO_Observer_t smo = {0};
FOC_Control_t foc = {0};
// 滑模观测器初始化
void SMO_Init(void) {
smo.alpha = 100.0f; // 滑模增益
smo.k_slide = 20.0f; // 滑模系数
smo.theta_est = 0.0f;
smo.omega_est = 0.0f;
}
// 滑模观测器核心算法
void SMO_Update(float i_alpha, float i_beta,
float v_alpha, float v_beta, float Ts) {
static float i_alpha_est = 0, i_beta_est = 0;
float di_alpha, di_beta;
// 1. 电流观测器
di_alpha = (v_alpha - motor.Rs * i_alpha_est
- smo.z_alpha) / motor.Ld;
di_beta = (v_beta - motor.Rs * i_beta_est
- smo.z_beta) / motor.Lq;
i_alpha_est += di_alpha * Ts;
i_beta_est += di_beta * Ts;
// 2. 滑模面计算
float e_alpha = i_alpha_est - i_alpha;
float e_beta = i_beta_est - i_beta;
// 3. 滑模控制律
smo.z_alpha = smo.alpha * sign(e_alpha);
smo.z_beta = smo.alpha * sign(e_beta);
// 4. 反电动势估算
smo.e_alpha = smo.z_alpha + smo.k_slide * e_alpha;
smo.e_beta = smo.z_beta + smo.k_slide * e_beta;
// 5. 低通滤波(减小高频抖振)
float lpf_coef = 0.05f; // 低通滤波系数
smo.lpf_alpha = smo.lpf_alpha * (1 - lpf_coef)
+ smo.e_alpha * lpf_coef;
smo.lpf_beta = smo.lpf_beta * (1 - lpf_coef)
+ smo.e_beta * lpf_coef;
// 6. 位置和速度估算
// 角度 = atan2(-e_alpha, e_beta)
float theta_raw = atan2f(-smo.lpf_alpha, smo.lpf_beta);
// 角度归一化到[0, 2π]
smo.theta_est = fmodf(theta_raw, 2.0f * 3.1415926f);
if (smo.theta_est < 0) {
smo.theta_est += 2.0f * 3.1415926f;
}
// 7. 速度估算(角度微分)
static float theta_last = 0;
float delta_theta = smo.theta_est - theta_last;
// 角度补偿(过2π跳变)
if (delta_theta > 3.1415926f) delta_theta -= 2.0f * 3.1415926f;
if (delta_theta < -3.1415926f) delta_theta += 2.0f * 3.1415926f;
smo.omega_est = delta_theta / Ts; // 电角速度 (rad/s)
theta_last = smo.theta_est;
}
// 符号函数(改进的饱和函数,减少抖振)
float sign(float x) {
float delta = 0.1f; // 边界层厚度
if (x > delta) return 1.0f;
else if (x < -delta) return -1.0f;
else return x / delta; // 边界层内线性过渡
}
六、高频注入启动(零低速)
// HFI.c
#include "PMSM_Sensorless.h"
// 高频注入参数
typedef struct {
float vh_alpha; // α轴高频电压
float vh_beta; // β轴高频电压
float fh; // 高频频率 (Hz)
float vh_amp; // 高频幅值 (V)
float ih_alpha; // α轴高频电流
float ih_beta; // β轴高频电流
float theta_est; // 估算角度
uint8_t enabled; // 使能标志
} HFI_Params_t;
HFI_Params_t hfi = {0};
// 高频注入初始化
void HFI_Init(void) {
hfi.fh = 1000.0f; // 1kHz高频
hfi.vh_amp = 10.0f; // 10V幅值
hfi.enabled = 1;
}
// 生成高频电压信号
void HFI_Generate(float angle, float *vh_alpha, float *vh_beta) {
static float phase = 0;
float vh_mag = hfi.vh_amp;
// 旋转高频电压
*vh_alpha = vh_mag * cosf(phase);
*vh_beta = vh_mag * sinf(phase);
// 更新相位
phase += 2.0f * 3.1415926f * hfi.fh * 0.00005f; // 50us控制周期
if (phase > 2.0f * 3.1415926f) {
phase -= 2.0f * 3.1415926f;
}
}
// 高频响应处理(提取位置信息)
void HFI_Process(float i_alpha, float i_beta, float angle) {
static float i_alpha_last = 0, i_beta_last = 0;
float di_alpha, di_beta;
float ih_alpha_filt, ih_beta_filt;
// 1. 电流微分(提取高频分量)
di_alpha = i_alpha - i_alpha_last;
di_beta = i_beta - i_beta_last;
i_alpha_last = i_alpha;
i_beta_last = i_beta;
// 2. 带通滤波(提取高频信号)
static float bp_coef = 0.1f;
hfi.ih_alpha = hfi.ih_alpha * (1 - bp_coef) + di_alpha * bp_coef;
hfi.ih_beta = hfi.ih_beta * (1 - bp_coef) + di_beta * bp_coef;
// 3. 解调得到位置误差
// 将高频电流变换到估计的d-q坐标系
float sin_theta = sinf(angle);
float cos_theta = cosf(angle);
float ih_d = hfi.ih_alpha * cos_theta + hfi.ih_beta * sin_theta;
float ih_q = -hfi.ih_alpha * sin_theta + hfi.ih_beta * cos_theta;
// 4. 位置误差信号
float pos_error = ih_q * cosf(2.0f * 3.1415926f * hfi.fh * 0.00005f);
// 5. 锁相环跟踪位置
static float pll_kp = 10.0f, pll_ki = 100.0f;
static float pll_integral = 0;
pll_integral += pos_error;
float delta_theta = pll_kp * pos_error + pll_ki * pll_integral;
hfi.theta_est += delta_theta * 0.00005f; // 50us周期
// 角度归一化
if (hfi.theta_est > 2.0f * 3.1415926f) {
hfi.theta_est -= 2.0f * 3.1415926f;
}
if (hfi.theta_est < 0) {
hfi.theta_est += 2.0f * 3.1415926f;
}
}
七、FOC控制核心
// FOC.c
#include "PMSM_Sensorless.h"
#include "math.h"
// PID控制器结构体
typedef struct {
float kp;
float ki;
float kd;
float integral;
float error_last;
float output;
float out_max;
float out_min;
} PID_Controller_t;
PID_Controller_t pid_id = {0}; // d轴电流环
PID_Controller_t pid_iq = {0}; // q轴电流环
PID_Controller_t pid_speed = {0}; // 速度环
// FOC初始化
void FOC_Init(void) {
// d轴电流环PID
pid_id.kp = 0.5f;
pid_id.ki = 0.1f;
pid_id.kd = 0.0f;
pid_id.out_max = 100.0f; // 最大输出电压
pid_id.out_min = -100.0f;
// q轴电流环PID
pid_iq.kp = 0.5f;
pid_iq.ki = 0.1f;
pid_iq.kd = 0.0f;
pid_iq.out_max = 100.0f;
pid_iq.out_min = -100.0f;
// 速度环PID
pid_speed.kp = 0.1f;
pid_speed.ki = 0.01f;
pid_speed.kd = 0.001f;
pid_speed.out_max = 5.0f; // 最大电流
pid_speed.out_min = -5.0f;
}
// 通用PID计算
float PID_Calculate(PID_Controller_t *pid, float setpoint, float feedback, float dt) {
float error = setpoint - feedback;
// 比例项
float p_out = pid->kp * error;
// 积分项(抗饱和)
pid->integral += pid->ki * error * dt;
if (pid->integral > pid->out_max) pid->integral = pid->out_max;
if (pid->integral < pid->out_min) pid->integral = pid->out_min;
// 微分项
float d_out = 0;
if (pid->kd > 0) {
d_out = pid->kd * (error - pid->error_last) / dt;
}
pid->error_last = error;
// 输出总和
pid->output = p_out + pid->integral + d_out;
// 输出限幅
if (pid->output > pid->out_max) pid->output = pid->out_max;
if (pid->output < pid->out_min) pid->output = pid->out_min;
return pid->output;
}
// Clarke变换 (3相 → αβ)
void Clarke_Transform(float ia, float ib, float ic, float *i_alpha, float *i_beta) {
*i_alpha = ia;
*i_beta = (ia + 2.0f * ib) / 1.7320508f; // 1/√3
}
// Park变换 (αβ → dq)
void Park_Transform(float i_alpha, float i_beta, float theta,
float *id, float *iq) {
float sin_theta = sinf(theta);
float cos_theta = cosf(theta);
*id = i_alpha * cos_theta + i_beta * sin_theta;
*iq = -i_alpha * sin_theta + i_beta * cos_theta;
}
// 反Park变换 (dq → αβ)
void Inv_Park_Transform(float vd, float vq, float theta,
float *v_alpha, float *v_beta) {
float sin_theta = sinf(theta);
float cos_theta = cosf(theta);
*v_alpha = vd * cos_theta - vq * sin_theta;
*v_beta = vd * sin_theta + vq * cos_theta;
}
// FOC主控制函数
void FOC_Control(float theta, float omega_e,
float ia, float ib, float ic,
float *v_alpha, float *v_beta) {
float i_alpha, i_beta;
float id, iq;
float vd, vq;
// 1. Clarke变换
Clarke_Transform(ia, ib, ic, &i_alpha, &i_beta);
// 2. Park变换
Park_Transform(i_alpha, i_beta, theta, &id, &iq);
// 更新反馈
foc.id_fb = id;
foc.iq_fb = iq;
// 3. 速度环PID(外环)
foc.iq_ref = PID_Calculate(&pid_speed, foc.speed_ref, foc.speed_fb, 0.0001f);
// 4. 电流环PID(内环)
// d轴电流控制(通常设为0,最大转矩控制)
foc.id_ref = 0; // MTPA时可以计算非零值
vd = PID_Calculate(&pid_id, foc.id_ref, id, 0.00005f);
vq = PID_Calculate(&pid_iq, foc.iq_ref, iq, 0.00005f);
// 5. 前馈解耦补偿
vd = vd - omega_e * motor.Lq * iq;
vq = vq + omega_e * (motor.Ld * id + motor.lambda_f);
foc.vd_ref = vd;
foc.vq_ref = vq;
// 6. 反Park变换
Inv_Park_Transform(vd, vq, theta, v_alpha, v_beta);
}
八、SVPWM生成
// SVPWM.c
#include "PMSM_Sensorless.h"
#include "math.h"
// SVPWM生成
void SVPWM_Generate(float v_alpha, float v_beta,
float vdc, float *ta, float *tb, float *tc) {
float t1, t2, t0;
float sector;
float va, vb, vc;
float vmax, vmin, vmid;
// 1. Clarke逆变换 (αβ → abc)
va = v_alpha;
vb = -0.5f * v_alpha + 0.8660254f * v_beta; // √3/2
vc = -0.5f * v_alpha - 0.8660254f * v_beta;
// 2. 计算三相占空比
vmax = fmaxf(va, fmaxf(vb, vc));
vmin = fminf(va, fminf(vb, vc));
// 3. 扇区判断
float vref1 = vb - vc;
float vref2 = vc - va;
float vref3 = va - vb;
if (vref1 > 0) {
if (vref2 > 0) {
if (vref3 > 0) sector = 1; // 扇区1
else sector = 5; // 扇区5
} else {
sector = 0; // 扇区0
}
} else {
if (vref2 > 0) {
sector = 3; // 扇区3
} else {
if (vref3 > 0) sector = 2; // 扇区2
else sector = 4; // 扇区4
}
}
// 4. 计算开关时间
switch ((int)sector) {
case 0: // 扇区1
t1 = vb;
t2 = va;
break;
case 1: // 扇区2
t1 = va;
t2 = vc;
break;
case 2: // 扇区3
t1 = vc;
t2 = vb;
break;
case 3: // 扇区4
t1 = -vc;
t2 = -va;
break;
case 4: // 扇区5
t1 = -va;
t2 = -vb;
break;
case 5: // 扇区6
t1 = -vb;
t2 = -vc;
break;
default:
t1 = t2 = 0;
break;
}
// 5. 时间归一化
float t_sum = fabsf(t1) + fabsf(t2);
if (t_sum > 1.0f) {
t1 = t1 / t_sum;
t2 = t2 / t_sum;
}
// 6. 死区时间补偿
float dead_time = 2.0e-6f; // 2us死区
float t_dead = dead_time * 20000.0f; // 20kHz PWM
// 7. 计算PWM占空比
float t0_half = (1.0f - t1 - t2) / 2.0f;
switch ((int)sector) {
case 0: // 扇区1
*ta = t0_half + t1 + t2;
*tb = t0_half + t2;
*tc = t0_half;
break;
case 1: // 扇区2
*ta = t0_half + t1;
*tb = t0_half + t1 + t2;
*tc = t0_half;
break;
case 2: // 扇区3
*ta = t0_half;
*tb = t0_half + t1 + t2;
*tc = t0_half + t2;
break;
case 3: // 扇区4
*ta = t0_half;
*tb = t0_half + t1;
*tc = t0_half + t1 + t2;
break;
case 4: // 扇区5
*ta = t0_half + t2;
*tb = t0_half;
*tc = t0_half + t1 + t2;
break;
case 5: // 扇区6
*ta = t0_half + t1 + t2;
*tb = t0_half;
*tc = t0_half + t1;
break;
}
// 8. 死区补偿
*ta = fmaxf(0, fminf(1, *ta - t_dead));
*tb = fmaxf(0, fminf(1, *tb - t_dead));
*tc = fmaxf(0, fminf(1, *tc - t_dead));
}
九、DSP主程序
// main.c
#include "DSP2833x_Device.h"
#include "PMSM_Sensorless.h"
// 全局变量
float adc_result[6]; // ADC采样结果
float ia, ib, ic; // 三相电流
float vdc; // 直流母线电压
float v_alpha, v_beta; // αβ电压
float ta, tb, tc; // PWM占空比
// 控制周期计数
Uint32 control_counter = 0;
// 系统初始化
void System_Init(void) {
// 1. 初始化系统控制
InitSysCtrl();
// 2. 关闭看门狗
DisableDog();
// 3. 初始化PIE控制
DINT; // 禁用全局中断
InitPieCtrl();
IER = 0x0000;
IFR = 0x0000;
InitPieVectTable();
// 4. 初始化外设
InitAdc(); // ADC
InitEPwm(); // PWM
InitECap(); // 捕获
InitSci(); // 串口
// 5. 算法初始化
SMO_Init();
HFI_Init();
FOC_Init();
// 6. 使能全局中断
EINT;
ERTM;
}
// ADC中断服务程序
__interrupt void ADC_ISR(void) {
// 1. 读取ADC结果
adc_result[0] = AdcRegs.ADCRESULT0 * 3.0f / 4095.0f; // Ia
adc_result[1] = AdcRegs.ADCRESULT1 * 3.0f / 4095.0f; // Ib
adc_result[2] = AdcRegs.ADCRESULT2 * 3.0f / 4095.0f; // Ic
adc_result[3] = AdcRegs.ADCRESULT3 * 3.0f / 4095.0f; // Vdc
// 2. 计算实际值
ia = (adc_result[0] - 1.65f) * 20.0f; // 20A/V霍尔
ib = (adc_result[1] - 1.65f) * 20.0f;
ic = (adc_result[2] - 1.65f) * 20.0f;
vdc = adc_result[3] * 10.0f; // 10:1分压
// 3. 电流重构(3相→2相)
float i_alpha, i_beta;
Clarke_Transform(ia, ib, ic, &i_alpha, &i_beta);
// 4. 状态检测
static uint8_t state = 0; // 0:启动, 1:运行, 2:故障
if (state == 0) { // 启动阶段
// 高频注入启动
float vh_alpha, vh_beta;
HFI_Generate(smo.theta_est, &vh_alpha, &vh_beta);
v_alpha = vh_alpha;
v_beta = vh_beta;
// 处理高频响应
HFI_Process(i_alpha, i_beta, hfi.theta_est);
// 检查是否达到切换条件
if (smo.omega_est > 10.0f) { // 10rad/s切换
state = 1;
hfi.enabled = 0;
}
foc.theta = hfi.theta_est;
} else if (state == 1) { // 正常运行
// 滑模观测器更新
SMO_Update(i_alpha, i_beta, v_alpha, v_beta, 0.00005f);
// 更新反馈
foc.theta = smo.theta_est;
foc.omega_e = smo.omega_est;
foc.speed_fb = smo.omega_est * 30.0f / (3.1415926f * motor.pole_pairs);
// FOC控制
FOC_Control(foc.theta, foc.omega_e, ia, ib, ic, &v_alpha, &v_beta);
} else { // 故障状态
v_alpha = v_beta = 0;
}
// 5. 生成SVPWM
SVPWM_Generate(v_alpha, v_beta, vdc, &ta, &tb, &tc);
// 6. 更新PWM占空比
EPwm1Regs.CMPA.half.CMPA = (Uint16)(ta * EPwm1Regs.TBPRD);
EPwm2Regs.CMPA.half.CMPA = (Uint16)(tb * EPwm2Regs.TBPRD);
EPwm3Regs.CMPA.half.CMPA = (Uint16)(tc * EPwm3Regs.TBPRD);
// 7. 清除中断标志
AdcRegs.ADC_ST_FLAG.bit.INT_SEQ1_CLR = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
control_counter++;
}
// 主函数
void main(void) {
// 1. 系统初始化
System_Init();
// 2. 配置ADC
// 配置ADC为SEQ1,触发源为EPWM1
AdcRegs.ADCTRL1.bit.SEQ_CASC = 1; // 级联模式
AdcRegs.ADCTRL2.bit.EPWM_SOCA_SEQ1 = 1; // EPWM触发
AdcRegs.ADCTRL2.bit.INT_ENA_SEQ1 = 1; // 使能中断
// 3. 配置PWM
// 20kHz PWM频率
EPwm1Regs.TBPRD = 1500; // 150MHz/1500 = 100kHz, 再二分频=20kHz
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // 上下计数
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
// 4. 启动PWM
EPwm1Regs.ETSEL.bit.SOCAEN = 1; // 使能ADC触发
EPwm1Regs.ETSEL.bit.SOCASEL = 1; // 周期匹配时触发
EPwm1Regs.ETPS.bit.SOCAPRD = 1; // 每次触发
// 5. 主循环
while(1) {
// 主循环可以处理低速任务
// 如通讯、状态显示、参数调整等
// 串口通讯示例
if (control_counter > 20000) { // 每1秒发送一次
control_counter = 0;
// 发送状态数据
SCI_Send_Data(foc.speed_fb, foc.theta, ia, ib, ic);
}
// 低功耗模式
asm(" IDLE");
}
}
十、中断向量表配置
// DSP2833x_DefaultIsr.c
// 添加ADC中断
interrupt void ADCINT1_ISR(void) {
ADC_ISR();
}
// 中断向量表
PieVectTable.ADCINT1 = &ADCINT1_ISR;
// 使能PIE中断
PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // ADCINT1
IER |= M_INT1; // 使能CPU INT1
十一、保护功能
// Protection.c
#include "PMSM_Sensorless.h"
// 保护参数
typedef struct {
float oc_threshold; // 过流阈值
float ov_threshold; // 过压阈值
float uv_threshold; // 欠压阈值
float ot_threshold; // 过温阈值
uint8_t fault_flag; // 故障标志
} Protection_t;
Protection_t protect = {0};
// 保护初始化
void Protection_Init(void) {
protect.oc_threshold = 20.0f; // 20A
protect.ov_threshold = 400.0f; // 400V
protect.uv_threshold = 200.0f; // 200V
protect.ot_threshold = 85.0f; // 85°C
}
// 保护检测
uint8_t Protection_Check(float ia, float ib, float ic, float vdc, float temp) {
protect.fault_flag = 0;
// 过流保护
if (fabsf(ia) > protect.oc_threshold ||
fabsf(ib) > protect.oc_threshold ||
fabsf(ic) > protect.oc_threshold) {
protect.fault_flag |= 0x01; // OC故障
}
// 过压保护
if (vdc > protect.ov_threshold) {
protect.fault_flag |= 0x02; // OV故障
}
// 欠压保护
if (vdc < protect.uv_threshold) {
protect.fault_flag |= 0x04; // UV故障
}
// 过温保护
if (temp > protect.ot_threshold) {
protect.fault_flag |= 0x08; // OT故障
}
// 缺相保护
float avg_current = (ia + ib + ic) / 3.0f;
float unbalance = fabsf(ia - avg_current) +
fabsf(ib - avg_current) +
fabsf(ic - avg_current);
if (unbalance > protect.oc_threshold) {
protect.fault_flag |= 0x10; // 不平衡故障
}
return protect.fault_flag;
}
// 保护动作
void Protection_Action(uint8_t fault_code) {
if (fault_code != 0) {
// 立即关闭PWM
EPwm1Regs.TBCTL.bit.CTRMODE = TB_FREEZE; // 停止PWM
EPwm2Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
EPwm3Regs.TBCTL.bit.CTRMODE = TB_FREEZE;
// 触发故障引脚
GpioDataRegs.GPBCLEAR.bit.GPIO34 = 1; // 故障指示灯
// 记录故障代码
Save_Fault_Code(fault_code);
}
}
参考代码 永磁同步电机无传感器控制DSP程序 www.youwenfan.com/contentcnu/70034.html
十二、参数整定与调试
1. 电流环PID整定
KP_id = 0.5 * Rs * f_sw (Rs:定子电阻, f_sw:开关频率)
KI_id = 0.5 * Rs * 2π * f_bandwidth
2. 速度环PID整定
KP_speed = 0.1 * J * 2π * f_bandwidth
KI_speed = 0.01 * J * (2π * f_bandwidth)²
3. 滑模观测器参数
smo.alpha = 2.0f * motor.Rs; // 滑模增益
smo.k_slide = 0.5f * motor.Ld; // 滑模系数
十三、调试工具与接口
1. 串口数据监控
// SCI发送状态数据
void SCI_Send_Data(float speed, float angle, float ia, float ib, float ic) {
uint8_t buffer[20];
float* p_float = (float*)buffer;
p_float[0] = speed;
p_float[1] = angle;
p_float[2] = ia;
p_float[3] = ib;
p_float[4] = ic;
SciRegs.SCITXBUF = 0xAA; // 帧头
for (int i = 0; i < 20; i++) {
while (SciRegs.SCICTL2.bit.TXRDY == 0);
SciRegs.SCITXBUF = buffer[i];
}
}
2. CCS实时调参
#pragma DATA_SECTION(foc, "ramgs0");
FOC_Control_t foc; // 放在可实时修改的RAM区