久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

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

QQ登錄

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

搜索
查看: 1375|回復(fù): 2
收起左側(cè)

請(qǐng)教一個(gè)PID程序問(wèn)題分析

[復(fù)制鏈接]
ID:1064364 發(fā)表于 2023-7-24 10:41 | 顯示全部樓層 |閱讀模式
pidout1=90 +   PIDcontrol(setjiaodu,jiaodu);        //pid算式這個(gè)90是哪里來(lái)的?具體指什么?

  1. #include <reg52.h>
  2. #include <intrins.H>
  3. #include <math.H>
  4. #include <stdio.h>   
  5. #define     u8              unsigned char
  6. #define     uchar          unsigned char
  7. #define     uint           unsigned int
  8. #define     u16           unsigned int
  9. #define  uchar unsigned char
  10. #define  uint unsigned int
  11. typedef unsigned char  Uint8;       /* defined for unsigned 8-bits integer variable       無(wú)符號(hào)8位整型變量  */
  12. typedef unsigned int   Uint16;      /* defined for unsigned 16-bits integer variable       無(wú)符號(hào)16位整型變量 */
  13. typedef unsigned long  Uint32;      /* defined for unsigned 32-bits integer variable       無(wú)符號(hào)32位整型變量 */

  14. sbit LCD_RS = P1^0;   //液晶1602  RS端口   
  15. sbit LCD_RW = P1^1;   //液晶1602  RS端口         
  16. sbit LCD_EP = P1^2;   //液晶1602  EN端口
  17. sbit PWM_PIN0 = P2^0 ;
  18. sbit PWM_PIN1 = P2^1 ;
  19. int setjiaodu = 40;//占空比最大100 6 16
  20. u16 pwm;//占空比最大100 6 16

  21. sbit  Key_Set   = P1^3 ;
  22. sbit  Key_Up    = P1^4 ;
  23. sbit  Key_Dowm  = P1^5 ;

  24. uchar code table[] = {":               "};      //設(shè)定速度初始化
  25. uchar code table1[] = {"                "}; //  動(dòng)態(tài)顯示初始化
  26. uchar n , i,x,table2[5],table3[5],ge,shi,bai,flag1,key1n,temp;

  27. ///***********延時(shí)1MS程序***/
  28. void  delay(uint z)
  29. {  uint x,y;
  30.    for(x=z;x>0;x--)
  31.    for(y=80;y>0;y--);

  32. }

  33. float kp = 0.70;
  34. float ki = 0.0005;
  35. float kd = 0.001;
  36. float ee,eeh,p;    //PID誤差和誤差累計(jì)
  37. float pidout1,pidout2,pidout3;                  
  38. float PIDcontrol( int  uset ,  int feedback)        //pid算式
  39. {                                                                                                      
  40.         float duk,D;   
  41.         eeh=ee;  
  42.     ee=uset*1.0-feedback*1.0;
  43.     p += ee;   
  44.     D = ee -eeh;
  45.       duk=kp*ee+ki*p-kd*D;
  46.     return duk;
  47. }



  48. /******液晶寫(xiě)命令************/
  49. void  write_com(uchar com)
  50. {     LCD_RS=0;
  51.   
  52.     P0=com    ;
  53. //    delay(1);
  54.     LCD_EP=1;
  55.     delay(1);
  56.     LCD_EP=0;
  57. }
  58. /*****************/
  59. /********液晶寫(xiě)數(shù)據(jù)***********/
  60. void  write_data(uchar  date)
  61. {      LCD_RS=1;

  62.     P0=date    ;
  63. //delay(1);
  64.     LCD_EP=1;
  65.     delay(1);
  66.     LCD_EP=0;

  67. }
  68. /*****************************/
  69. /********顯示動(dòng)態(tài)速度數(shù)據(jù)*********/
  70. void display_val(unsigned int zhuan)
  71. {

  72.   table2[0]=zhuan/10000+0x30;           //取萬(wàn)位   
  73.   table2[1]=(zhuan%10000)/1000+0x30;   //取千位
  74.   table2[2]=(zhuan%1000)/100+0x30;     //取百位
  75.   table2[3]=(zhuan%100)/10+0x30;       //取十位   
  76.   table2[4]=zhuan%10+0x30;              //取個(gè)位

  77. //  write_com(0x80+0x40+7);
  78. //   write_data(table2[0]);
  79. //   write_com(0x80+0x40+8);
  80. //    write_data(table2[1]);
  81.    write_com(0x80+0x40+4);
  82.    //write_data(table2[2]);
  83.    //write_com(0x80+0x40+10);
  84.    write_data(table2[3]);
  85.    //write_com(0x80+0x40+11);
  86.    write_data(table2[4]);         
  87.      
  88. }
  89. void dis(int z,unsigned int zhua,int x,int y)
  90. {
  91.      
  92.   table2[0]=zhua/10000+0x30;           //取萬(wàn)位   
  93.   table2[1]=(zhua%10000)/1000+0x30;   //取千位
  94.   table2[2]=(zhua%1000)/100+0x30;     //取百位
  95.   table2[3]=(zhua%100)/10+0x30;       //取十位   
  96.   table2[4]=zhua%10+0x30;              //取個(gè)位
  97.     if(z==1)
  98.   write_com(0x80+x);
  99.     if(z==2)
  100.   write_com(0x80+0x40+x);
  101. //  write_data(table2[0]);
  102.   //  write_data(table2[1]);
  103.    write_data(table2[2]);
  104.      if(y==1)
  105.         write_data('.');
  106.    write_data(table2[3]);
  107. //         if(y==2)
  108. //        write_data('.');
  109.    write_data(table2[4]);
  110.    write_com(0x80+16);   
  111.            
  112.      
  113. }
  114. void dis0(int z,int zhua,int x,int y)
  115. {
  116.         if(zhua>0)   
  117.         {
  118.             table2[0]=zhua/10000+0x30;           //取萬(wàn)位   
  119.             table2[1]=' ';   //取千位
  120.             table2[2]=(zhua%1000)/100+0x30;     //取百位
  121.             table2[3]=(zhua%100)/10+0x30;       //取十位   
  122.             table2[4]=zhua%10+0x30;              //取個(gè)位
  123.             if(z==1)
  124.             write_com(0x80+x);
  125.             if(z==2)
  126.             write_com(0x80+0x40+x-1);
  127.             write_data(table2[1]);
  128.             write_data(table2[2]);
  129.             write_data(table2[3]);
  130.             write_data(table2[4]);
  131.             write_com(0x80+16);   
  132.      }
  133.   else   
  134.     {
  135.           zhua=abs(zhua);
  136.           table2[0]=zhua/10000+0x30;           //取萬(wàn)位   
  137.             table2[1]='-';   //取千位
  138.             table2[2]=(zhua%1000)/100+0x30;
  139.             table2[3]=(zhua%100)/10+0x30;       //取十位   
  140.             table2[4]=zhua%10+0x30;              //取個(gè)位
  141.             if(z==1)
  142.             write_com(0x80+x);
  143.             if(z==2)
  144.             write_com(0x80+0x40+x-1);
  145.             write_data(table2[1]);
  146.              write_data(table2[2]);
  147.              write_data(table2[3]);
  148.             write_data(table2[4]);
  149.              write_com(0x80+16);
  150.     }        
  151.      
  152. }

  153. /*--------------------------液晶初始化-----------------------------*/
  154. void  init_lcd()
  155. {     
  156.         LCD_EP=0;
  157.        write_com(0x38);
  158.        write_com(0x08);
  159.        write_com(0x06);  
  160.        write_com(0x0c);
  161.        write_com(0x01);
  162. //初始化顯示
  163.     write_com(0x80+2);                     
  164.     for(i=0;i<13;i++)
  165.     {
  166.         write_data(table[i]);                     
  167.         delay(3);
  168.     }
  169.     write_com(0x80+0x40);                       
  170.     for(i=0;i<14;i++)
  171.     {
  172.         write_data(table1[i]);                     
  173.         delay(3);
  174.     }  

  175. }
  176.     void PWMInit()
  177. {

  178.     TMOD|=0x01;         //模式設(shè)置,00000001,可見(jiàn)采用的是定時(shí)器0,工作與模式1(M1=0,M0=1)。
  179.     TR0=1;             //打開(kāi)定時(shí)器
  180.     TH0=0Xff;         //定時(shí)器設(shè)置,每隔100微秒發(fā)起一次中斷。
  181.     TL0=0Xc1;
  182.     ET0=1;             //開(kāi)定時(shí)器0中斷
  183.     EA=1;             //開(kāi)總中斷   
  184. }


  185. sbit ADCS     = P2^4; //ADC0832 片選
  186. sbit ADCLK  = P2^5; //ADC0832 時(shí)鐘
  187. sbit ADDI     = P2^6; //ADC0832 數(shù)據(jù)輸入        /*因?yàn)閱纹瑱C(jī)的管腳是雙向的,且ADC0832的數(shù)據(jù)輸入輸出不同時(shí)進(jìn)行,
  188. sbit ADDO     = P2^6; //ADC0832 數(shù)據(jù)輸出        /*為節(jié)省單片機(jī)引腳,簡(jiǎn)化電路所以輸入輸出連接在同一個(gè)引腳上

  189. static unsigned char Adc0832(unsigned char channel)
  190. {
  191.     Uint8 i=0;
  192.     Uint8 j;
  193.     Uint16 dat=0;
  194.     Uint8 ndat=0;
  195.     Uint8  Vot=0;

  196.     if(channel==0)channel=2;
  197.     if(channel==1)channel=3;
  198.     ADDI=1;
  199.     _nop_();
  200.     _nop_();
  201.     ADCS=0;//拉低CS端
  202.     _nop_();
  203.     _nop_();
  204.     ADCLK=1;//拉高CLK端
  205.     _nop_();
  206.     _nop_();
  207.     ADCLK=0;//拉低CLK端,形成下降沿1
  208.     _nop_();
  209.     _nop_();
  210.     ADCLK=1;//拉高CLK端
  211.     ADDI=channel&0x1;
  212.     _nop_();
  213.     _nop_();
  214.     ADCLK=0;//拉低CLK端,形成下降沿2
  215.     _nop_();
  216.     _nop_();
  217.     ADCLK=1;//拉高CLK端
  218.     ADDI=(channel>>1)&0x1;
  219.     _nop_();
  220.     _nop_();
  221.     ADCLK=0;//拉低CLK端,形成下降沿3
  222.     ADDI=1;//控制命令結(jié)束
  223.     _nop_();
  224.     _nop_();
  225.     dat=0;
  226.     for(i=0;i<8;i++)
  227.     {
  228.         dat|=ADDO;//收數(shù)據(jù)
  229.         ADCLK=1;
  230.         _nop_();
  231.         _nop_();
  232.         ADCLK=0;//形成一次時(shí)鐘脈沖
  233.         _nop_();
  234.         _nop_();
  235.         dat<<=1;
  236.         if(i==7)dat|=ADDO;
  237.     }
  238.     for(i=0;i<8;i++)
  239.     {
  240.         j=0;
  241.         j=j|ADDO;//收數(shù)據(jù)
  242.         ADCLK=1;
  243.         _nop_();
  244.         _nop_();
  245.         ADCLK=0;//形成一次時(shí)鐘脈沖
  246.         _nop_();
  247.         _nop_();
  248.         j=j<<7;
  249.         ndat=ndat|j;
  250.         if(i<7)ndat>>=1;
  251.     }
  252.     ADCS=1;//拉低CS端
  253.     ADCLK=0;//拉低CLK端
  254.     ADDO=1;//拉高數(shù)據(jù)端,回到初始狀態(tài)
  255.     dat<<=8;
  256.     dat|=ndat;

  257.     return(dat);            //return ad data
  258. }

  259. Uint16 ReadAdc(unsigned char channel,unsigned int Number)//channel為通道 Number為輸出值最大值
  260. {
  261.     Uint8 Read_AD;
  262.     Uint16        AdResult;
  263.     Read_AD = Adc0832(channel);
  264.     AdResult = (Uint32)4*Read_AD*Number/255;//255
  265.     return AdResult;
  266. }   
  267. #define KEYDELAY 20
  268. void KeyScanDeal(Uint8 sMenu,Uint16 *Setnumb1,float *Setnumb2,float *Setnumb3,float *Setnumb4)
  269. {
  270.    
  271.     static Uint8 Menu = 0;

  272.     if(Key_Set == 0)
  273.     {
  274.             Menu ++;
  275.             if(Menu > sMenu)
  276.                 Menu = 0;
  277.             while(Key_Set == 0);
  278.     }
  279.    
  280.     switch (Menu)
  281.     {
  282.             case 1:
  283.             {
  284.                 if(Key_Up == 0)
  285.                 {
  286.                         delay(KEYDELAY);
  287.                         if(Key_Up == 0 && (*Setnumb1) < 100)
  288.                         {        
  289.                                 (*Setnumb1) =*Setnumb1 + 1;
  290.                         }
  291.                 }
  292.                 else if(Key_Dowm == 0 && (*Setnumb1) > 0)
  293.                 {
  294.                         delay(KEYDELAY);
  295.                         if(Key_Dowm == 0)
  296.                         {
  297.                                 (*Setnumb1) =*Setnumb1 - 1;
  298.                         }
  299.                 }
  300.                 break;
  301.             }
  302.             case 2:
  303.             {
  304.                 if(Key_Up == 0 && (*Setnumb2) < 100)
  305.                 {
  306.                         delay(KEYDELAY);
  307.                         if(Key_Up == 0)
  308.                         {
  309.                                 (*Setnumb2) =*Setnumb2 + 0.01;
  310.                         }
  311.                 }
  312.                 else if(Key_Dowm == 0 && (*Setnumb2) > 0)
  313.                 {
  314.                         delay(KEYDELAY);
  315.                         if(Key_Dowm == 0)
  316.                         {
  317.                                 (*Setnumb2) =*Setnumb2 -0.01;
  318.                         }
  319.                 }
  320.                 break;
  321.             }
  322.             case 3:
  323.             {
  324.                 if(Key_Up == 0 && (*Setnumb3) < 50)
  325.                 {
  326.                         delay(KEYDELAY);
  327.                         if(Key_Up == 0)
  328.                         {
  329.                                 (*Setnumb3) =*Setnumb3 + 0.0001;
  330.                         }
  331.                 }
  332.                 else if(Key_Dowm == 0)
  333.                 {
  334.                         delay(KEYDELAY);
  335.                         if(Key_Dowm == 0 && (*Setnumb3) > 0)
  336.                         {
  337.                                 (*Setnumb3) =*Setnumb3 -0.0001;
  338.                         }
  339.                 }
  340.                 break;
  341.             }
  342.             case 4:
  343.             {
  344.                 if(Key_Up == 0 && (*Setnumb4) < 59)
  345.                 {
  346.                         delay(KEYDELAY);
  347.                         if(Key_Up == 0)
  348.                         {
  349.                                 (*Setnumb4) =*Setnumb4 + 0.001;
  350.                         }
  351.                 }
  352.                 else if(Key_Dowm == 0 && (*Setnumb4) > 0)
  353.                 {
  354.                         delay(KEYDELAY);
  355.                         if(Key_Dowm == 0)
  356.                         {
  357.                                 (*Setnumb4) =*Setnumb4 -0.001;
  358.                         }
  359.                 }
  360.                 break;
  361.             }
  362.     }
  363. }
  364.                                     


  365. void main()
  366. {   
  367.     Uint8 i = 0;
  368.     int jiaodu = 0;
  369.     PWMInit();
  370.     LCD_RW=0;
  371.     init_lcd();                        // 初始化液晶顯示  
  372.     PWMInit();
  373.     PWM_PIN1 = 1;
  374.     while(1)   
  375.     {     
  376.         i ++;
  377.         if(i%5 ==0)
  378.         {
  379.             KeyScanDeal(4,&setjiaodu,&kp,&ki,&kd);            
  380.           dis(1,setjiaodu,0,2);
  381.           dis(1,jiaodu,6,2);
  382.           dis(2,kp*100,0,2);
  383.           dis(2,ki*10000,5,2);
  384.             dis(2,kd*1000,9,2);
  385.                     
  386.         }

  387.             jiaodu = ReadAdc(0,80) - 156;

  388.         pidout1=90 +   PIDcontrol(setjiaodu,jiaodu);        //pid算式

  389.             if(pidout1 > 100)
  390.             {
  391.                 pwm = 99;
  392.             }
  393.             else if(pidout1 <1)
  394.             {
  395.                 pwm = 1;
  396.             }
  397.             else
  398.             {
  399.                 pwm = pidout1;
  400.             }
  401.     }
  402. }

  403. void time0() interrupt 1
  404. {
  405.     static  int cnt = 0;

  406.    
  407.     if(cnt <= pwm)
  408.     {
  409.         PWM_PIN0 = 1;
  410.     }
  411.     else
  412.     {
  413.         PWM_PIN0 = 0;
  414.     }
  415.    
  416.         cnt++;
  417.    
  418.   if(cnt > 100)
  419.     {
  420.         cnt = 0;
  421.     }        
  422.     TH0=0Xff;
  423.     TL0=0Xc1;
  424.    
  425. }
復(fù)制代碼
回復(fù)

使用道具 舉報(bào)

ID:883242 發(fā)表于 2023-7-24 15:33 | 顯示全部樓層
明顯是PWM需要加上這個(gè)常數(shù),為什么要加只能去查你的單片機(jī)手冊(cè)PWM寄存器部分。
回復(fù)

使用道具 舉報(bào)

ID:94031 發(fā)表于 2023-7-24 15:33 | 顯示全部樓層
PID系統(tǒng)和實(shí)際現(xiàn)場(chǎng)聯(lián)系非常緊密,離開(kāi)實(shí)際現(xiàn)場(chǎng),有些程序不好理解很正常。這里的90是編程者根據(jù)調(diào)試覺(jué)得,有這個(gè)90系統(tǒng)會(huì)比較快達(dá)到平衡。這里的90是輸出從90開(kāi)始控制調(diào)整,而不是0或其他.
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 午夜欧美一区二区三区在线播放 | 中文日韩在线视频 | 国产精品毛片一区二区三区 | 性高湖久久久久久久久3小时 | 国产一级片在线观看视频 | 久久精品久久久 | 亚洲人精品午夜 | 国产福利在线 | 国产欧美一区二区三区在线看 | 婷婷久久五月天 | 羞羞视频在线观免费观看 | 91夜夜夜| 毛片视频免费观看 | 男女下面一进一出网站 | 国产精品一区二区三区四区五区 | 亚洲一区二区三区四区五区午夜 | 欧美久久久网站 | 久草色播| 亚洲国产欧美一区二区三区久久 | 国产激情免费视频 | 一区二区不卡视频 | 亚洲每日更新 | 国产在线观看一区二区三区 | 国产黄色小视频在线观看 | 五月香婷婷 | 激情五月综合 | 国产女人叫床高潮大片免费 | 亚洲一区播放 | 精品视频在线一区 | 成人一区二区在线 | 国产精品成人一区二区三区夜夜夜 | 久久久久国产精品www | 亚洲午夜电影 | 精品亚洲一区二区三区 | 国产精品美女久久久 | 成人免费网站视频 | 91网站在线观看视频 | 久久一级免费视频 | 黄色av网站在线观看 | 亚洲欧美成人在线 | 久久一二|