找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開(kāi)始

搜索
查看: 2922|回復(fù): 4
打印 上一主題 下一主題
收起左側(cè)

單片機(jī)+電機(jī)PID控制之參數(shù)確定問(wèn)題

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:587051 發(fā)表于 2019-7-24 16:00 | 只看該作者 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
這個(gè)是在論壇里找到的一個(gè)比較簡(jiǎn)單且經(jīng)典的pid控制算法,但是我很想知道三個(gè)參數(shù)是什么確定的,我認(rèn)為這才是問(wèn)題的關(guān)鍵所在啊。
求大神教一下選定參數(shù)的方法,就如果給你們做,代碼已經(jīng)寫好,現(xiàn)在就是要確定pid的三個(gè)參數(shù),你們通過(guò)什么方法找到一個(gè)比較好的參數(shù)?

單片機(jī)源程序如下:
  1. #include<reg51.h>
  2. #include "intrins.h"
  3. #include <lcd.H>
  4. #define uchar unsigned char
  5. #define uint unsigned int
  6. #define GPIO_KEY P2
  7. sbit PWM=P1^4;                  
  8. sbit P10=P1^0;
  9. sbit P12=P1^2;
  10. uchar speed1[4]={"0000"};//設(shè)定轉(zhuǎn)速
  11. uchar speed2[3]={"000"};//占空比       
  12. uchar speed[]={"0000"};//當(dāng)前轉(zhuǎn)速
  13. uchar KeyValue=0;
  14. uint AA,count=0,flag;

  15. float pid_p=0.003,pid_i=0.003,pid_d=0.002;        //PID三個(gè)參數(shù) 初值
  16. uint SpeedSet=3000,CurrentSpeed;//設(shè)定轉(zhuǎn)速 當(dāng)前轉(zhuǎn)速
  17. unsigned char pid_val_mid;//pid_val_mid脈沖寬度
  18. unsigned int lastError=0;
  19. long int sumError=0;//sum偏差和
  20.        
  21.        
  22. void delay1(unsigned int i)
  23. {
  24.    unsigned int j;
  25.          for(;i>0;i--)
  26.          for(j=0;j<333;j++)
  27.          {;}
  28. }       


  29. /********************* 鍵盤掃描*************/
  30. void KeyDown(void)               
  31. {
  32.         GPIO_KEY=0x0f;
  33.                 delay1(10);
  34.         if(GPIO_KEY!=0x0f)
  35.         {
  36.                 delay1(10);
  37.                 if(GPIO_KEY!=0x0f)
  38.                 {
  39.                                 //測(cè)試列
  40.                         GPIO_KEY=0X0F;
  41.                         delay1(10);
  42.                         switch(GPIO_KEY)
  43.                         {
  44.                                 case(0X07):        KeyValue=0;break;
  45.                                 case(0X0b):        KeyValue=1;break;
  46.                                 case(0X0d): KeyValue=2;break;
  47.                                 case(0X0e):        KeyValue=3;break;
  48.                         }
  49.                         //測(cè)試行
  50.                         GPIO_KEY=0XF0;
  51.                         delay1(10);
  52.                         switch(GPIO_KEY)
  53.                         {
  54.                                 case(0X70):        KeyValue=KeyValue;break;
  55.                                 case(0Xb0):        KeyValue=KeyValue+4;break;
  56.                                 case(0Xd0): KeyValue=KeyValue+8;break;
  57.                                 case(0Xe0):        KeyValue=KeyValue+12;break;
  58.                         }
  59.                        
  60.                 }

  61.         }
  62. }

  63. void timer()
  64. {
  65.   
  66.          TMOD=0x11;//定時(shí)器0工作方式1.16位,定時(shí)器1工作方式1,16位定時(shí);
  67.          TH0=0x4b;//50ms初值
  68.          TL0=0xfe;
  69.          
  70.          TH1=0xfc;//1msPWM控制
  71.          TL1=0x66;
  72.          
  73.          TR1=1;          //啟動(dòng)定時(shí)器1
  74.          ET1=1;           //定時(shí)器1中斷使能
  75.          IT0=1;//外部中斷下降沿觸發(fā)
  76.          TR0=1;        //定時(shí)器啟動(dòng)標(biāo)志
  77.          ET0=1;        //定時(shí)器中斷使能
  78.          EX0=1;        //外部中斷使能
  79.          EA=1;        //全局中斷
  80. }


  81. /***********************lcd顯示*************/
  82. void  display()
  83. {   
  84.    
  85.           speed[0]=CurrentSpeed/1000+0x30; //當(dāng)前轉(zhuǎn)速
  86.                 speed[1]=CurrentSpeed/100%10+0x30;
  87.                 speed[2]=CurrentSpeed/10%10+0x30;
  88.                 speed[3]=CurrentSpeed%10+0x30;  
  89.                
  90.                
  91.                 speed1[0]=SpeedSet/1000+0x30;//設(shè)定轉(zhuǎn)速
  92.                 speed1[1]=SpeedSet/100%10+0x30;
  93.                 speed1[2]=SpeedSet/10%10+0x30;
  94.                 speed1[3]=SpeedSet%10+0x30;  
  95.                
  96.                 speed2[0]=pid_val_mid/100+0x30;
  97.           speed2[1]=pid_val_mid/10%10+0x30;//占空比
  98.                 speed2[2]=pid_val_mid%10+0x30;
  99.                
  100.        
  101.           DispHanzi(0,0,5,"當(dāng)前轉(zhuǎn)速:");
  102.                 DispZimu(0,5,4,speed);       
  103.                 DispHanzi(1,0,5,"設(shè)定轉(zhuǎn)速:");
  104.                 DispZimu(1,5,4,speed1);

  105.                 DispHanzi(3,0,4,"占空比:");//占空比       
  106.                 DispZimu(3,4,3,speed2);
  107.                 DispHanzi(3,6,1,"%");//占空比       
  108.                
  109. }



  110. /************************電機(jī)控制*************/
  111. void keyKZ()
  112. {
  113.                          if(KeyValue==4)//正轉(zhuǎn)
  114.                          {
  115.                           P10=1;
  116.                     P12=0;
  117.                                 }
  118.                          if(KeyValue==5)//反轉(zhuǎn)
  119.                          {
  120.                           P10=0;
  121.                     P12=1;
  122.                                 }
  123.                                 if(KeyValue==6)//停車
  124.                          {
  125.                           P10=0;
  126.                     P12=0;
  127.                                 }
  128.                        
  129.                         if(KeyValue==12)//設(shè)定速度加50
  130.                           SpeedSet+=50;
  131.                         if(KeyValue==13)//設(shè)定速度減50
  132.                                 SpeedSet-=50;
  133.                         if(KeyValue==14)//設(shè)定速度加1
  134.                           SpeedSet+=1;
  135.                         if(KeyValue==15)//設(shè)定速度減1
  136.                                 SpeedSet-=1;
  137.         KeyValue=0;
  138.                                
  139. }


  140. /************************PID控制算法*************/
  141. unsigned int PID()
  142. {  

  143.   int dError=0,Error=0,B;
  144.        
  145.         Error=SpeedSet-CurrentSpeed;//當(dāng)前誤差
  146.    sumError=Error+sumError;//誤差和
  147.    dError=Error-lastError;//誤差偏差
  148.    lastError=Error;
  149.   B=pid_p*Error+pid_i*sumError+pid_d*dError;
  150.        
  151.         if(B>100) pid_val_mid=100;
  152.    if(B<0) pid_val_mid=0;
  153.         if(B>=0&&B<=100)
  154.    pid_val_mid=B;
  155.          return(0);
  156. }


  157. void Timer0_isr() interrupt 1  //定時(shí)器0中斷
  158. {
  159.          AA++;
  160.          TH0=0x4b;
  161.          TL0=0xfe;
  162.          if(AA==20)
  163.          {               
  164.            CurrentSpeed=count*3;//一分鐘的轉(zhuǎn)速
  165.                                 count=0;
  166.                                 AA=0;
  167.                                 PID();
  168.          }

  169. }


  170. void key_int() interrupt 0         //外部中斷P32口
  171. {
  172.         count++;
  173. }

  174. void Timer1() interrupt 3
  175. {
  176.    static int c=0;
  177.                  TH1=0xfc;
  178.                   TL1=0x66;
  179.                  c++;    //每次定時(shí)器溢出加1                  
  180.          
  181.           if(c<=pid_val_mid) PWM=1;
  182.              
  183.           if(c>pid_val_mid)  PWM=0;
  184.             
  185.                 if(c>=100)         c=0;
  186. }
  187.        
  188. void main()
  189. {
  190.                 timer();//定時(shí)器初始化
  191.                 InitLCD();//LCD初始化
  192.                 while(1)
  193.                 {
  194.                    KeyDown();        //鍵盤掃描
  195.                          keyKZ();//鍵盤控制
  196.                          display();//顯示LCD
  197.                 }
  198. }       
復(fù)制代碼

所有資料51hei提供下載:
PID控制電機(jī).zip (41.03 KB, 下載次數(shù): 25)





分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:405033 發(fā)表于 2019-7-24 18:23 | 只看該作者
matlab仿真一下吧,上位機(jī)看波形也ok,或者先把ID定為0,然后調(diào)整P,等調(diào)到差不多的時(shí)候,在去調(diào)整I(D為0),最后調(diào)D,PID有很多方法調(diào)整,看你喜歡哪種咯
回復(fù)

使用道具 舉報(bào)

板凳
ID:147266 發(fā)表于 2019-7-24 22:00 | 只看該作者
如果沒(méi)學(xué)過(guò)自控原理,可以搜一下“PID口訣”……
回復(fù)

使用道具 舉報(bào)

地板
ID:388197 發(fā)表于 2019-7-24 22:41 | 只看該作者
PID的公式你別看它又有積分又有微分,真正的難點(diǎn)還是三個(gè)項(xiàng)前面的系數(shù),這3個(gè)系數(shù)取值需要根據(jù)你實(shí)際的系統(tǒng),電機(jī)我不太懂,我就拿簡(jiǎn)單的可控硅延時(shí)導(dǎo)通來(lái)控制加熱來(lái)舉例子,這三個(gè)系數(shù)跟你的加熱棒功率,加熱棒與被加熱物體直接的接觸,被加熱物體質(zhì)量,材料等溫度傳感器安裝的位置都有關(guān),需要反復(fù)調(diào)試,觀察其響應(yīng)曲線,才能找出三個(gè)系數(shù)最佳的取值.
回復(fù)

使用道具 舉報(bào)

5#
ID:123289 發(fā)表于 2019-7-25 12:02 | 只看該作者
你問(wèn)的問(wèn)題,與單片機(jī)及程序無(wú)關(guān),與控制理論相關(guān),你需要補(bǔ)自動(dòng)化控制理論方面的課。
否則你只能用實(shí)驗(yàn)方式去試出一組或N組不太保險(xiǎn)的經(jīng)驗(yàn)值。
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表