|
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)
51hei.png (18.52 KB, 下載次數(shù): 28)
下載附件
2019-11-30 15:05 上傳
單片機(jī)源程序如下:
- #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'}; //目標(biāo)轉(zhuǎn)速。Target r/min
- unsigned char cc[]={'A','c','t','u','a','l',' ',' ',' ',' ',' ','r','/','m','i','n'}; //實(shí)測轉(zhuǎn)速: Actual r/min
-
- uchar i=0;
- sbit k1=P1^3;
- sbit k2=P1^4;
- sbit k3=P1^5;
- sbit k4=P1^6;
- sbit k5=P1^7;
- sbit PWM_FC=P3^5;
- sbit IN1=P3^4;
- sbit IN2=P3^3;
- int e ,e1 ,e2 ;//pid 偏差
- float uk ,uk1 ,duk ;//pid輸出值
- float Kp=0.25,Ki=0.05,Kd=0.015;//pid控制系數(shù) 0.1 0.05 0.016
- /*
- PID的參數(shù)設(shè)置可以參照以下來進(jìn)行:
- 參數(shù)整定找最佳,從小到大順序查;
- 先是比例后積分,最后再把微分加;
- 曲線振蕩很頻繁,比例度盤要放大;
- 曲線漂浮繞大灣,比例度盤往小扳;
- 曲線偏離回復(fù)慢,積分時間往下降;
- 曲線波動周期長,積分時間再加長;
- 曲線振蕩頻率快,先把微分降下來;
- 動差大來波動慢。微分時間應(yīng)加長;
- 理想曲線兩個波,前高后低4比1 ;
- 一看二調(diào)多分析,調(diào)節(jié)質(zhì)量不會低;
- */
- int out=0;
- uint SpeedSet=3000;
- uint cnt=0;
- uint Inpluse=0,num=0,zs;//脈沖計(jì)數(shù)
- uint PWMTime=100;//脈沖寬度
- void PIDControl();
- void SystemInit();
- void delay(uchar x);
- void PWMOUT();
- void SetSpeed();
- /**************主函數(shù)************/
- void main()
- {
- SystemInit();
- init();
- LCD_Write_String(0,0,aa);
- zs=1;
- while(1)
- {
- SetSpeed();
- 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偏差計(jì)算
- {
- 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用來測量轉(zhuǎn)速
- IT0=1;
- EA=1;
- e =0;
- e1=0;
- e2=0;
- IN1=1;
- IN2=1;
- }
- void SetSpeed()
- {
- if(k1==0)
- {
- delay(100);
- if(k1==0)
- {
- IN1=0;
- IN2=1;
- }
- }
- if(k2==0)
- {
- delay(100);
- if(k2==0)
- {
- IN1=1;
- IN2=1;
- }
- }
- if(k3==0)
- {
- delay(100);
- if(k3==0)
- {
- IN1=~IN1;
- IN2=~IN2;
- }
- while(k3==0);
- }
- if(k4==0)
- {
- delay(100);
- if(k4==0)
- {
- SpeedSet+=10;
- if(SpeedSet>3500)
- {
- SpeedSet=3500;
- }
- }
- }
- if(k5==0)
- {
- delay(100);
- if(k5==0)
- {
- SpeedSet-=10;
- if(SpeedSet<0) SpeedSet=0;
- }
- }
- aa[7]=SpeedSet/1000+'0';
- aa[8]=SpeedSet/100%10+'0';
- aa[9]=SpeedSet/10%10+'0';
- aa[10]=SpeedSet%10+'0';
- LCD_Write_String(0,0,aa);
- }
- void int0() interrupt 0
- {
- Inpluse++;
- }
- void t0() interrupt 1
- {
- static unsigned int time=0;
- TH0=THC0;
- TL0=TLC0;
- time++; //轉(zhuǎn)速測量周期
- if(time>500)
- {
- zs=1;
- time=0;
- num=Inpluse; //計(jì)算式中是仿真時,碼盤數(shù)60時的情況,如果碼盤數(shù)n=10時,num=Inpluse*60/n=Inpluse*6;
- Inpluse=0;
- PIDControl();
- }
- PWMOUT();
- }
- void timer_1() interrupt 3
- {
- cnt++; //cnt越大占空比越高2.5Khz
- }
復(fù)制代碼
51hei.png (6.37 KB, 下載次數(shù): 25)
下載附件
2019-11-30 15:06 上傳
全部資料51hei下載地址:
2-PID轉(zhuǎn)速測量控制_LCD.zip
(296.09 KB, 下載次數(shù): 122)
2019-11-30 15:00 上傳
點(diǎn)擊文件名下載附件
下載積分: 黑幣 -5
|
評分
-
查看全部評分
|