这个基于DSP28335平台的正交编码器三闭环控制方案,是我在工业伺服系统开发中积累的一套成熟解决方案。它实现了电流环、速度环和位置环的完整闭环控制,最核心的创新点在于"不改代码自由切换"的设计理念。在实际产线设备改造项目中,这套方案帮助客户将调试效率提升了60%以上。
传统伺服控制系统在切换控制模式时,往往需要重新编译下载程序,甚至修改硬件接线。而本方案通过精心设计的软件架构和参数配置机制,实现了运行时的动态模式切换。操作人员只需通过上位机发送简单指令,就能在电流控制、速度控制和位置控制三种模式间无缝切换,这对需要频繁调整控制策略的柔性生产线尤为重要。
选择TI的TMS320F28335作为主控芯片主要基于三点考量:
实际测试中,即使在最严苛的三环同时运行场景下,CPU负载率仍能控制在75%以下,这为实时性提供了充分保障。
eQEP模块的配置要点包括:
c复制EQep1Regs.QUPRD = 150000; // 单位定时器周期(对应100Hz)
EQep1Regs.QDECCTL.bit.QSRC = 0; // 正交计数模式
EQep1Regs.QEPCTL.bit.FREE_SOFT = 2; // 仿真挂起时继续运行
特别要注意的是,在工业现场环境中,编码器信号容易受到干扰。我们在硬件上增加了SN75176差分收发器,软件上采用数字滤波:
c复制EQep1Regs.QFLTCTL.bit.FLTEN = 1; // 使能滤波
EQep1Regs.QFLTCTL.bit.FLTPRD = 8; // 滤波周期
电流环作为最内环,采用PI控制算法,采样周期设置为50μs。关键参数计算过程:
code复制比例系数Kp = (R×Ts)/(2×L) = (0.5×50e-6)/(2×5e-3) = 0.0025
积分时间Ti = L/R = 5e-3/0.5 = 0.01s
实际代码实现采用抗积分饱和的改进PI算法:
c复制void Current_PI_Update(PI_Obj *pi) {
float err = pi->Ref - pi->Fdb;
pi->Up = pi->Kp * err;
pi->Ui += pi->Ki * err * pi->Ts;
// 抗饱和处理
if(pi->Ui > pi->OutMax) pi->Ui = pi->OutMax;
else if(pi->Ui < pi->OutMin) pi->Ui = pi->OutMin;
pi->Out = pi->Up + pi->Ui;
}
速度环采用带前馈的PID控制,关键创新点在于自适应滤波器设计:
c复制float Speed_Filter(float new_speed) {
static float buf[FILTER_LEN];
static int index = 0;
buf[index] = new_speed;
index = (index + 1) % FILTER_LEN;
// 动态调整滤波系数
float var = calculate_variance(buf, FILTER_LEN);
float alpha = 1 - exp(-var/VAR_THRESHOLD);
return alpha * new_speed + (1-alpha) * last_speed;
}
这种动态滤波方法在低速时保持较高截止频率以保证响应速度,在高速时增强滤波效果抑制噪声。
位置环的特殊之处在于需要处理编码器溢出问题。我们采用32位扩展计数方法:
c复制long32 Position_GetTotalCount() {
static uint16_t last_cnt = 0;
static long32 total_cnt = 0;
uint16_t curr_cnt = EQep1Regs.QPOSCNT;
int16_t delta = (int16_t)(curr_cnt - last_cnt);
total_cnt += delta;
last_cnt = curr_cnt;
return total_cnt;
}
模式切换的核心是精心设计的状态机:
c复制typedef enum {
MODE_IDLE,
MODE_CURRENT,
MODE_VELOCITY,
MODE_POSITION,
MODE_TRANSITION
} ControlMode;
void Control_StateMachine() {
static ControlMode current_mode = MODE_IDLE;
switch(current_mode) {
case MODE_CURRENT:
Current_Loop_Update();
if(new_mode == MODE_VELOCITY) {
Init_Velocity_Transition();
current_mode = MODE_TRANSITION;
}
break;
case MODE_TRANSITION:
if(Transition_Complete()) {
current_mode = new_mode;
}
break;
// 其他状态处理...
}
}
实现平滑切换的关键技术:
c复制void Transition_S_Curve(float *out, float start, float end, float t) {
float T = TRANSITION_TIME;
if(t <= 0) *out = start;
else if(t >= T) *out = end;
else {
float x = t/T;
*out = start + (end-start)*(x*x*(3-2*x));
}
}
重要提示:电流环调试必须先断开速度环和位置环!
调试步骤:
实测某750W伺服电机的最佳参数:
code复制Kp = 0.0032
Ki = 0.12
速度环调试的黄金法则:
典型参数整定过程:
位置环特有的调试技巧:
现象:位置反馈值出现跳变
排查步骤:
现象:切换瞬间电机抖动
解决方案:
可能原因:
在实际部署中,我们还实现了以下增强功能:
这套系统在包装机械上连续运行12个月的统计数据显示:
对于需要更高性能的场景,可以考虑升级到C2000系列的新款DSP,如F28379D,其双核架构可以将控制周期缩短到10μs级别。不过就大多数工业应用而言,F28335的性能已经足够出色。