利用PID算法实现倒立摆控制
#include #include #define uchar unsigned char #define uint unsigned int #define THC0 0xf8 #define TLC0 0xcD //2ms unsigned char code Duan[]={0x3F, 0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F};//共阴极数码管,0-9段码表 unsigned char Data_Buffer[8]={0,0,0,0,0,0,0,0}; uchar i=0; sbit AddSpeed=P1^1; sbit SubSpeed=P1^2; sbit PWM_FC=P1^0; int e ,e1 ,e2 ; //pid 偏差 float uk ,uk1 ,duk ;//pid输出值 float Kp=5,Ki=10,Kd=1.9;//pid控制系数 int out=0; uint SpeedSet=1000; uint cnt=0; uint Inpluse=0,num=0;//脉冲计数 uint PWMTime=100;// 脉冲宽度 unsigned char arry[]; void SendString(uint ch); void PIDControl(); //PID控制 void SystemInit(); //系统初始化 void delay(uchar x); void PWMOUT(); //PWM输出 void SetSpeed(); //速度设置 void SegRefre(); /**************主函数************/ void main() { SystemInit(); while(1) { SetSpeed(); SegRefre(); PWMOUT(); } } void PIDControl() //pid偏差计算 { e=SpeedSet-num; duk=(Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2))/50; uk=uk1+duk; out=(int)uk; if(out>1000) { out=1000; } else if(out<0) { //+Kd*(e-2e1+e2) 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 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; } void SetSpeed() { if(AddSpeed==0) { delay(200); if(AddSpeed==0) { SpeedSet+=100; if(SpeedSet>9999) { SpeedSet=9999; } } } if(SubSpeed==0) { delay(200); if(SubSpeed==0) { SpeedSet-=100; if(SpeedSet<0) SpeedSet=0; } } } void SegRefre() //显示刷新 { Data_Buffer[0]=SpeedSet/1000; Data_Buffer[1]=SpeedSet%1000/100; Data_Buffer[2]=SpeedSet%100/10; Data_Buffer[3]=SpeedSet%10; Data_Buffer[4]=num/1000; Data_Buffer[5]=num%1000/100; Data_Buffer[6]=num%100/10; Data_Buffer[7]=num%10; } void int0() interrupt 0 { Inpluse++; } void t0() interrupt 1 { static unsigned char Bit=0;//静态变量,退出程序值保留 static unsigned int time=0; static unsigned int aa=0; TH0=THC0; TL0=TLC0; aa++; if(aa==50) { aa=0; flag0=1; } Bit++; time++; //转速测量周期 if(Bit>8) Bit=0; P0=0xff; P2=Duan[Data_Buffer[Bit]]; switch(Bit) { case 0:P0=0X7F;break; case 1:P0=0XBF;break; case 2:P0=0XDF;break; case 3:P0=0XEF;break; case 4:P0=0XF7;break; case 5:P0=0XFB;break; case 6:P0=0XFD;break; case 7:P0=0XFE;break; } if(time>100) { time=0; num=Inpluse*15*5; Inpluse=0; PIDControl(); } } void timer_1() interrupt 3 { cnt++; } //cnt越大占空比越高2.5Khz 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- sarr.cn 版权所有 赣ICP备2024042794号-1
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务