速度环和电流环调了好几天了,老是有问题,要么稳态偏差大,要么就振荡,片子是33FJ64MC508A,目前外部晶振为7.3728M,经PLL后得到16588800Hz的系统时钟,弄这个频率,主要是为了方便和VB6.0做串口通信,观察PID数据曲线的波特率为115200,我是1.25MS算一次速度环,算5次后算一次电流环,速度环的PID结果不作任何处理,直接作为电流环的设定值,占空比更新是在电流环里进行,刚开始请教别人说是算若干次电流环然后算一次速度环,我照这个思路来发现电机速度启振荡没法控制,然后我就改为算5次速度环才算一次电流环,这样情况有所好转,但老是有较大的稳态偏差,能从几十转/分跳到100多转/分,有时又能将速度锁定在几转/分之内,压缩包里是我的程序,做过的大侠帮我看看有哪里没对,也希望对新手有所帮助,当然我自己也是新手,共同进步哈
//速度闭环PID计算程序
//----------------------------------------------------------------------
void Speed_Pid(void)
{
//DesiredSpeed = Motor_Speed/14;
if(Speed >= DesiredSpeed) //计算偏差
{
SpeedError = Speed - DesiredSpeed; //测量值大于给定值
Flags.Speed_error_dir = 1; //偏差为负数
}
else
{
SpeedError = DesiredSpeed - Speed; //给定值大于测量值
Flags.Speed_error_dir= 0; //偏差为正负数
}
Txbuff[4] = SpeedError >>8; //将速度偏差值存入发送缓存
Txbuff[5] = SpeedError & 0x00FF;
//Speed = 0x0000; //得到偏差后,将测量到得数据清空
if(Flags.Speed_error_dir ==0) //偏差为正数,则积分数据和偏差相加
{
SpeedIntegral = SpeedIntegral + SpeedError; //对偏差进行积分
}
else //偏差为负数,则积分数据和偏差相减
{
if(SpeedIntegral>=SpeedError) //积分大于偏差
{
SpeedIntegral = SpeedIntegral - SpeedError;
}
else //偏差大于积分
{
SpeedIntegral = SpeedError - SpeedIntegral;
}
}
if(SpeedIntegral >2000) //积分限幅
{
SpeedIntegral = 2000;
}
Speed_PID = (SpeedError + SpeedIntegral*0 )/100;
Txbuff[8] = Speed_PID >>8; //将电机速度PID数据存入发送缓存
Txbuff[9] = Speed_PID & 0x00FF;
这是速度环的代码
//----------------------------------------------------------------
//电流闭环PID计算程序
//----------------------------------------------------------------
void Current_Pid(void)
{
DesiredCurrent = Speed_PID; //将速度环输出转换为电流环输入
if(Current >= DesiredCurrent) //计算电流偏差
{
CurrentError = Current - DesiredCurrent; //测量值大于给定值
Flags.Current_error_dir = 1; //偏差为负
}
else
{
CurrentError = DesiredCurrent - Current; //给定值大于测量值
Flags.Current_error_dir= 0; //偏差为正
}
//Current = 0x0000; //得到偏差后,将测量到的数据清空
if(Flags.Speed_error_dir ==0) //根据偏差方向,决定积分数据和偏差是相加还是相减
{
CurrentIntegral = CurrentIntegral + CurrentError; //对偏差进行积分
}
else
{
if(CurrentIntegral>=CurrentError)
{
CurrentIntegral = CurrentIntegral - CurrentError;
}
else
{
CurrentIntegral = CurrentError - CurrentIntegral;
}
}
if(CurrentIntegral >2000) //积分限幅
{
CurrentIntegral = 2000;
}
Current_PID = (CurrentError + CurrentIntegral/20 )/20;
if(Flags.Speed_error_dir==0)
{
if(DutyCycle >= 65000)
{
DutyCycle = 65535;
}
else
{
DutyCycle = Current_PID + DutyCycle; //电机加速
if(DutyCycle >=65000)
{
DutyCycle = 65535;
}
}
}
else ////电机减速
{
if(DutyCycle >= Current_PID)
{
DutyCycle = DutyCycle - Current_PID;
}
else
{
DutyCycle = Current_PID - DutyCycle;
}
}
PDC1 = DutyCycle;
PDC2 = PDC1;
PDC3 = PDC1;
Txbuff[6] = DutyCycle >>8; //将电机占空比数据存入发送缓存
Txbuff[7] = DutyCycle & 0x00FF;
这是电流环的代码
一周热门 更多>