找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 2805|回复: 1
收起左侧

这个直流电机PID怎么调节转速误差,让进度达到1位?

[复制链接]
ID:190577 发表于 2020-4-26 10:08 | 显示全部楼层 |阅读模式
28KD8JA)_F%`)3QTK$)}2Y2.png #include <REGX51.H>#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
#define THC0 0xf8
#define TLC0 0x50   //2ms,0x30,含中断处理时间时,0x50
#include "LCD.H"
#include "delay.h"

unsigned char aa[]={'T','a','r','g','e','t',' ',' ',' ',' ',' ','r','/','m','i','n'};  //目标转速。Target            r/min
unsigned char cc[]={'A','c','t','u','a','l',' ',' ',' ',' ',' ','r','/','m','i','n'};           //实测转速: Actual      r/min
uchar flag;                                                                                                                                                                                                                                 
uchar i=0;

sbit PWM_FC=P3^3;
sbit IN1=P3^0;
sbit IN2=P3^1;

int e ,e1 ,e2 ;//pid 偏差
float uk ,uk1 ,duk ;//pid输出值
float Kp=0.36,Ki=0.05,Kd=0.016;//pid控制系数        0.1 0.05 0.016

/*
PID的参数设置可以参照以下来进行:  
     参数整定找最佳,从小到大顺序查;  
         先是比例后积分,最后再把微分加;  
         曲线振荡很频繁,比例度盘要放大;  
         曲线漂浮绕大湾,比例度盘往小扳;  
         曲线偏离回复慢,积分时间往下降;  
         曲线波动周期长,积分时间再加长;  
         曲线振荡频率快,先把微分降下来;  
         动差大来波动慢。微分时间应加长;  
         理想曲线两个波,前高后低4比1 ; 
         一看二调多分析,调节质量不会低;
*/

int out=0;
uint SpeedSet=2000;
uint cnt=0;
uint Inpluse=0,num=0,zs;//脉冲计数
uint PWMTime=100;//脉冲宽度
void PIDControl();
void SystemInit();
void delay(uchar x);
void PWMOUT();
void SetSpeed();

/**************主函数************/
void main()
{
        SystemInit();
        init();
        LCD_Write_String(0,0,aa);
        zs=1;
        while(1)
        {
            if(flag==1)
                {
                 flag=0;
                  LCD_Write_String(0,0,aa);
                }
                if(zs==1)
                {
                    zs=0;
                        cc[7]=num/1000+'0';
                        cc[8]=num/100%10+'0';
                        cc[9]=num/10%10+'0';
                        cc[10]=num%10+'0';
                        LCD_Write_String(0,1,cc);
                }
        }
}

void PIDControl()        //pid偏差计算
{
        e=SpeedSet-num;
        duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2));  
        uk=uk1+duk;
        out=(int)uk;
        if(out>1000)
        {
                out=1000;
        }
        else if(out<0)
        {
                out=0;
        }
        uk1=uk;
        e2=e1;
        e1=e;
        PWMTime=out;
}

void delay(uchar x)
{
        uint i,j;
        for(i=x;i>0;i--)
                for(j=50;j>0;j--);
}

void PWMOUT()
{
        if(cnt<PWMTime)
        {
                PWM_FC=1;
        }
        else
        {
                PWM_FC=0;
        }
        if(cnt>1000) cnt=0;
}
void SystemInit()
{
        TMOD=0X21;    //t1用来串口t2定时
        TH0=THC0;
        TL0=TLC0;
        TH1=0xC0;
        TL1=0XC0;
        ET1=1;
        ET0=1;
        TR0=1;
        TR1=1;
        EX0=1;     //中断0用来测量转速
        IT0=1;
        EA=1;
        e =0;
        e1=0;
        e2=0;
        IN1=1;
        IN2=1;
}


uchar Key_Scan(void)

{

        static uchar State_Cnt=0;//静态变量,用于改变状态过程

       uchar Key_State = 0;//用于存储键值码

       switch(State_Cnt)

        {

                case 0x00:P1 = 0x1f;//先往P3(1到4独立按键)口送0001 1111

               if(P1 != 0x1f)//有无按键被按下

                {

                       State_Cnt = 0x01;//改变状态

                        break;                           

                }

               case 0x01:

                if(P1 != 0x1f)//经过定时器延时后,再次判断按键是否按下

                {

                        State_Cnt = 0x02;//改变状态

                       Key_State = P1;//把键值保存下来

                        P1 = 0x1f;//恢复P3,以便下次按下重新保存键值

                        break;

                }

                else

                {

                        State_Cnt = 0x00;//改变状态

                       break;

                }

                case 0x02:

               if(P1 == 0x1f)//判断按键释放

               {

                       State_Cnt = 0x00;//改变状态

                       break;

                }

                default:break;

       }

       return Key_State;//返回键值

}

void Display_Key(uchar key_value)

{

       switch(key_value)

        {

               case 0x1e:
                           IN1=0;
                   IN2=1;break;//键值改变时,做出相应的动作(用户自定义动作)

               case 0x1d:
                           IN1=1;
                   IN2=1;break;

               case 0x1b:
                           IN1=~IN1;
                   IN2=~IN2;
                   break;

               case 0x17:
                                   SpeedSet+=10;
                        if(SpeedSet>3500)
                        {
                                SpeedSet=3500;
                        }
                          
                           break;
                           case 0x0f:
                          SpeedSet-=10;
                        if(SpeedSet<0) SpeedSet=0;
                          
                           break;
        }

}



void int0() interrupt 0
{
        Inpluse++;
}
void t0() interrupt 1
{
        static unsigned int time=0,time1=0;

        TH0=THC0;
        TL0=TLC0;
        time++;  //转速测量周期
        time1++;
        if(time1>=5)
        {
                time1=0;
                flag=1;
                Display_Key(Key_Scan());//按键按下,键值码送入函数,以便做相应动作
                   aa[7]=SpeedSet/1000+'0';
        aa[8]=SpeedSet/100%10+'0';
        aa[9]=SpeedSet/10%10+'0';
        aa[10]=SpeedSet%10+'0';
       
        }
        if(time>500)
        {
                zs=1;
                time=0;
                num=Inpluse;         //计算式中是仿真时,码盘数60时的情况,如果码盘数n=10时,num=Inpluse*60/n=Inpluse*6;
                Inpluse=0;
                PIDControl();
        }
        PWMOUT();
}
void timer_1()  interrupt 3
{
           cnt++;        //cnt越大占空比越高2.5Khz
}


回复

使用道具 举报

ID:342451 发表于 2020-4-27 00:02 | 显示全部楼层
增大转速上限,还有就是设置编码器电机的一圈脉冲个数,以及转速计算周期,使得正好可以计算达到奇偶转速数都可以出现,然后就是PID参数了,这个慢慢挑
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表