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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5294|回復: 0
收起左側

8051單片機PID溫度控制(C語言)

[復制鏈接]
ID:127229 發表于 2016-6-19 16:31 | 顯示全部樓層 |閱讀模式
  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #include<math.h>
  4. #include<string.h>
  5. struct PID {
  6. unsigned int SetPoint; // 設定目標 Desired Value
  7. unsigned int Proportion; // 比例常數 Proportional Const
  8. unsigned int Integral; // 積分常數 Integral Const
  9. unsigned int Derivative; // 微分常數 Derivative Const
  10. unsigned int LastError; // Error[-1]
  11. unsigned int PrevError; // Error[-2]
  12. unsigned int SumError; // Sums of Errors
  13. };
  14. struct PID spid; // PID Control Structure
  15. unsigned int rout; // PID Response (Output)
  16. unsigned int rin; // PID Feedback (Input)
  17. sbit data1=P1^0;
  18. sbit clk=P1^1;
  19. sbit plus=P2^0;
  20. sbit subs=P2^1;
  21. sbit stop=P2^2;
  22. sbit output=P3^4;
  23. sbit DQ=P3^3;
  24. unsigned char flag,flag_1=0;
  25. unsigned char high_time,low_time,count=0;//占空比調節參數
  26. unsigned char set_temper=35;   
  27. unsigned char temper;        
  28. unsigned char i;
  29. unsigned char j=0;
  30. unsigned int s;
  31. /***********************************************************
  32. 延時子程序,延時時間以12M晶振為準,延時時間為30us×time
  33. ***********************************************************/
  34. void delay(unsigned char time)
  35.   {
  36.    unsigned char m,n;
  37.      for(n=0;n<time;n++)
  38.        for(m=0;m<2;m++){}
  39.   }
  40. /***********************************************************
  41. 寫一位數據子程序
  42. ***********************************************************/
  43. void write_bit(unsigned char bitval)
  44.   {
  45.     EA=0;
  46.       DQ=0;  /*拉低DQ以開始一個寫時序*/
  47.     if(bitval==1)
  48.        {
  49.         _nop_();
  50.         DQ=1;   /*如要寫1,則將總線置高*/
  51.         }
  52.       delay(5);   /*延時90us供DA18B20采樣*/
  53.     DQ=1;  /*釋放DQ總線*/
  54.     _nop_();
  55.     _nop_();
  56.    EA=1;
  57.    }
  58. /***********************************************************
  59. 寫一字節數據子程序
  60. ***********************************************************/
  61. void write_byte(unsigned char val)
  62. {
  63.   unsigned char i;
  64.   unsigned char temp;
  65.   EA=0;
  66.   TR0=0;
  67.   for(i=0;i<8;i++)  /*寫一字節數據,一次寫一位*/
  68.       {
  69.        temp=val>>i;  /*移位操作,將本次要寫的位移到最低位*/
  70.        temp=temp&1;
  71.        write_bit(temp);  /*向總線寫該位*/
  72.        }
  73.    delay(7);   /*延時120us后*/
  74. // TR0=1;
  75.   EA=1;
  76.   }
  77. /***********************************************************
  78. 讀一位數據子程序
  79. ***********************************************************/
  80. unsigned char read_bit()
  81. {
  82.   unsigned char i,value_bit;
  83.   EA=0;
  84.   DQ=0;   /*拉低DQ,開始讀時序*/
  85.   _nop_();
  86.   _nop_();
  87.   DQ=1;   /*釋放總線*/
  88.   for(i=0;i<2;i++){}
  89.   value_bit=DQ;
  90.   EA=1;
  91.   return(value_bit);
  92.   }
  93. /***********************************************************
  94. 讀一字節數據子程序
  95. ***********************************************************/
  96. unsigned char read_byte()
  97.   {
  98.    unsigned char i,value=0;
  99.    EA=0;
  100.    for(i=0;i<8;i++)
  101.       {
  102.        if(read_bit())  /*讀一字節數據,一個時序中讀一次,并作移位處理*/
  103.          value|=0x01<<i;
  104.        delay(4);  /*延時80us以完成此次都時序,之后再讀下一數據*/
  105.        }
  106.    EA=1;
  107.    return(value);
  108.   }
  109. /***********************************************************
  110. 復位子程序
  111. ***********************************************************/
  112. unsigned char reset()
  113.   {
  114.    unsigned char presence;
  115.    EA=0;
  116.    DQ=0;   /*拉低DQ總線開始復位*/
  117.    delay(30);   /*保持低電平480us*/
  118.    DQ=1;   /*釋放總線*/
  119.    delay(3);   
  120.    presence=DQ;   /*獲取應答信號*/
  121.    delay(28);   /*延時以完成整個時序*/
  122.    EA=1;
  123.    return(presence);  /*返回應答信號,有芯片應答返回0,無芯片則返回1*/
  124.   }
  125. /***********************************************************
  126. 獲取溫度子程序
  127. ***********************************************************/
  128. void get_temper()
  129. {
  130.   unsigned char i,j;
  131.   do
  132.   {
  133.     i=reset();  /*復位*/
  134.   }while(i!=0);  /*1為無反饋信號*/
  135.   i=0xcc;  /*發送設備定位命令*/
  136.   write_byte(i);
  137.   i=0x44;  /*發送開始轉換命令*/
  138.   write_byte(i);
  139.   delay(180);  /*延時*/
  140.   do
  141.   {
  142.   i=reset();  /*復位*/
  143.   }while(i!=0);  
  144.   i=0xcc;  /*設備定位*/
  145.   write_byte(i);
  146.   i=0xbe;  /*讀出緩沖區內容*/
  147.   write_byte(i);
  148.   j=read_byte();
  149.   i=read_byte();   
  150.   i=(i<<4)&0x7f;
  151.   s=(unsigned int)(j&0x0f);
  152.   s=(s*100)/16;
  153.   j=j>>4;
  154.   temper=i|j;                                      /*獲取的溫度放在temper中*/
  155.   }
  156. /*====================================================================================================
  157. Initialize PID Structure
  158. =====================================================================================================*/
  159. void PIDInit (struct PID *pp)
  160. {
  161. memset ( pp,0,sizeof(struct PID));
  162. }
  163. /*====================================================================================================
  164. PID計算部分
  165. =====================================================================================================*/
  166. unsigned int PIDCalc( struct PID *pp, unsigned int NextPoint )
  167. {
  168. unsigned int dError,Error;
  169. Error = pp->SetPoint - NextPoint; // 偏差
  170. pp->SumError += Error; // 積分
  171. dError = pp->LastError - pp->PrevError; // 當前微分
  172. pp->PrevError = pp->LastError;
  173. pp->LastError = Error;
  174. return (pp->Proportion * Error // 比例項
  175. + pp->Integral * pp->SumEror // 積分項
  176. + pp->Derivative * dError); // 微分項
  177. }
  178. /***********************************************************
  179. 溫度比較處理子程序
  180. ***********************************************************/
  181. compare_temper()
  182. {
  183.   unsigned char i;
  184.      if(set_temper>temper)
  185.          {
  186.           if(set_temper-temper>1)   
  187.              {
  188.               high_time=100;
  189.               low_time=0;
  190.              }
  191.           else
  192.              {
  193.                for(i=0;i<10;i++)
  194.                  {  get_temper();
  195.                     rin = s; // Read Input
  196.                     rout = PIDCalc ( &spid,rin ); // Perform PID Interation
  197.                  }
  198.                if (high_time<=100)
  199.                  high_time=(unsigned char)(rout/800);
  200.                else
  201.                  high_time=100;
  202.                low_time= (100-high_time);
  203.              }
  204.          }
  205.       else if(set_temper<=temper)
  206.              {
  207.                if(temper-set_temper>0)
  208.                  {
  209.                    high_time=0;
  210.                    low_time=100;
  211.                  }
  212.                else
  213.                {
  214.                  for(i=0;i<10;i++)
  215.                  {  get_temper();
  216.                     rin = s; // Read Input
  217.                     rout = PIDCalc ( &spid,rin ); // Perform PID Interation
  218.                  }
  219.                  if (high_time<100)
  220.                    high_time=(unsigned char)(rout/10000);
  221.                  else
  222.                    high_time=0;
  223.                  low_time= (100-high_time);
  224.                }
  225.              }
  226.      //  else
  227.      //      {}
  228.     }
  229. /*****************************************************
  230. T0中斷服務子程序,用于控制電平的翻轉 ,40us*100=4ms周期
  231. ******************************************************/
  232. void serve_T0() interrupt 1 using 1
  233.   {
  234.    if(++count<=(high_time))
  235.      output=1;
  236.    else if(count<=100)
  237.      {
  238.       output=0;
  239.       }
  240.    else
  241.       count=0;
  242.    TH0=0x2f;
  243.    TL0=0xe0;
  244.    }
  245. /*****************************************************
  246. 串行口中斷服務程序,用于上位機通訊
  247. ******************************************************/
  248. void serve_sio() interrupt 4 using 2
  249.   {
  250. /*   EA=0;
  251.    RI=0;  
  252.    i=SBUF;
  253.    if(i==2)
  254.       {
  255.        while(RI==0){}  
  256.        RI=0;
  257.        set_temper=SBUF;  
  258.        SBUF=0x02;  
  259.        while(TI==0){}
  260.        TI=0;
  261.        }
  262.     else if(i==3)  
  263.        {
  264.         TI=0;
  265.        SBUF=temper;
  266.         while(TI==0){}
  267.         TI=0;
  268.         }
  269.      EA=1;   */
  270.    }
  271. void disp_1(unsigned char disp_num1[6])
  272. {
  273.      unsigned char n,a,m;
  274.      for(n=0;n<6;n++)
  275.       {
  276.      //  k=disp_num1[n];
  277.        for(a=0;a<8;a++)
  278.          {
  279.           clk=0;
  280.            m=(disp_num1[n]&1);
  281.             disp_num1[n]=disp_num1[n]>>1;
  282.           if(m==1)
  283.              data1=1;
  284.           else
  285.              data1=0;
  286.           _nop_();
  287.           clk=1;
  288.           _nop_();
  289.           }
  290.        }
  291. }
  292. /*****************************************************
  293. 顯示子程序
  294. 功能:將占空比溫度轉化為單個字符,顯示占空比和測得到的溫度
  295. ******************************************************/
  296. void display()
  297. {
  298. unsigned char code number[]={0xfc,0x60,0xda,0xf2,0x66,0xb6,0xbe,0xe0,0xfe,0xf6};
  299. unsigned char disp_num[6];
  300. unsigned int k,k1;
  301. k=high_time;
  302. k=k%1000;
  303. k1=k/100;
  304. if(k1==0)
  305.     disp_num[0]=0;
  306. else
  307.     disp_num[0]=0x60;
  308. k=k%100;
  309. disp_num[1]=number[k/10];
  310. disp_num[2]=number[k%10];
  311. k=temper;
  312. k=k%100;
  313. disp_num[3]=number[k/10];
  314. disp_num[4]=number[k%10]+1;
  315. disp_num[5]=number[s/10];
  316. disp_1(disp_num);
  317. }
  318. /***********************************************************
  319. 主程序
  320. ***********************************************************/
  321. main()
  322. {
  323.   unsigned char z;
  324.   unsigned char a,b,flag_2=1,count1=0;
  325.   unsigned char phil[]={2,0xce,0x6e,0x60,0x1c,2};;
  326.   TMOD=0x21;   
  327.   TH0=0x2f;   
  328.   TL0=0x40;
  329.   SCON=0x50;   
  330.   PCON=0x00;            
  331.   TH1=0xfd;   
  332.   TL1=0xfd;
  333.   PS=1;           
  334.   EA=1;   
  335.   EX1=0;   
  336.   ET0=1;   
  337.   ES=1;   
  338.   TR0=1;  
  339.   TR1=1;
  340.   high_time=50;                 
  341.   low_time=50;
  342.   PIDInit ( &spid ); // Initialize Structure
  343.   spid.Proportion = 10; // Set PID Coefficients
  344.   spid.Integral = 8;
  345.   spid.Derivative =6;
  346.   spid.SetPoint = 100; // Set PID Setpoint
  347.   while(1)
  348.        {
  349.            if(plus==0)
  350.              {
  351.               EA=0;
  352.               for(a=0;a<5;a++)
  353.                 for(b=0;b<102;b++){}  
  354.                 if(plus==0)
  355.                   {
  356.                   set_temper++;
  357.                   flag=0;
  358.                   }
  359.               }
  360.             else if(subs==0)
  361.               {
  362.                for(a=0;a<5;a++)
  363.                   for(b=0;a<102;b++){}  
  364.                   if(subs==0)
  365.                   {
  366.                     set_temper--;
  367.                     flag=0;
  368.                    }
  369.                }
  370.             else if(stop==0)
  371.                {
  372.                 for(a=0;a<5;a++)
  373.                    for(b=0;b<102;b++){}  
  374.                    if(stop==0)
  375.                    {
  376.                    flag=0;         
  377.                    break;
  378.                    }
  379.              EA=1;
  380.              }
  381.       get_temper();
  382.       b=temper;
  383.       if(flag_2==1)
  384.          a=b;
  385.       if((abs(a-b))>5)
  386.         temper=a;
  387.       else
  388.         temper=b;
  389.       a=temper;
  390.       flag_2=0;
  391.       if(++count1>30)
  392.          {
  393.           display();
  394.           count1=0;
  395.           }
  396.       compare_temper();   
  397.        }
  398.     TR0=0;
  399.     z=1;
  400. while(1)
  401.       {
  402.        EA=0;
  403.        if(stop==0)
  404.         {
  405.          for(a=0;a<5;a++)
  406.            for(b=0;b<102;b++){}
  407.          if(stop==0)
  408.            disp_1(phil);
  409.         //        break;
  410.            }
  411.       EA=1;
  412.          }
  413. }
復制代碼




回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91精品国产自产在线老师啪 | 免费在线观看黄网站 | 久久精品福利视频 | 91精品国产91久久久久久吃药 | 久久色视频 | 亚洲精品在线看 | 日韩毛片 | 国产一级视频 | 欧美一区二区在线播放 | 色婷婷久久久久swag精品 | 日韩一区二区视频 | 久久99精品久久久久久国产越南 | 亚洲欧美少妇 | 99久9| 一区二区三区在线 | 成人不卡 | 99热这里都是精品 | 欧美另类视频 | 中文字幕久久久 | 狠狠ri| 国产高潮好爽受不了了夜色 | 亚洲图片一区二区三区 | 男女又爽又黄视频 | 999国产精品视频 | 91人人爽 | 久草视频2| 成人中文字幕av | 国产一区二区三区在线看 | 国产视频福利在线观看 | 五月婷婷在线播放 | 红桃成人在线 | 日日干夜夜操天天操 | 亚洲国产成人精品女人久久久 | 91视频在线观看免费 | 99小视频| 日韩黄色免费 | 99久久久国产精品免费消防器 | 成年人精品视频在线观看 | 综合五月婷 | 亚洲有码转帖 | 免费观看的av毛片的网站 |