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

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

QQ登錄

只需一步,快速開始

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

單片機(jī)PID溫控源程序

[復(fù)制鏈接]
ID:404701 發(fā)表于 2018-10-1 18:53 | 顯示全部樓層 |閱讀模式
第一章 前言
溫度控制系統(tǒng)無論是工業(yè)生產(chǎn)過程,還是日常生活都起著非常重要的作用,過低或過高的溫度環(huán)境不僅是一種資源的浪費(fèi),同時(shí)也會(huì)對(duì)機(jī)器和工作人員的壽命產(chǎn)生嚴(yán)重影響,極有可能造成嚴(yán)重的經(jīng)濟(jì)財(cái)產(chǎn)損失,給生活生產(chǎn)帶來許多不利的因素。基于AT89C51的單片機(jī)溫度控制系統(tǒng)與傳統(tǒng)的溫度控制系統(tǒng)相比具有操作方便、價(jià)格便宜、精確度高和開展容易等優(yōu)點(diǎn),因此市場前景好。

第二章 系統(tǒng)設(shè)計(jì)
2.1方案論證
    方案一:整個(gè)系統(tǒng)采用LCD1602,該顯示器原理簡單,編程簡單,對(duì)于我們這個(gè)系統(tǒng)顯示效果也可以了。
方案二:整個(gè)系統(tǒng)采用LCD12864,該顯示器是點(diǎn)陣的,編程相對(duì)有點(diǎn)難度,可以顯示漢字。
綜上,對(duì)于我們初學(xué)者來說,對(duì)編程還不是很熟練,我們采用方案一。
2.2系統(tǒng)的總設(shè)計(jì)
本設(shè)計(jì)使用單片機(jī)作為控制核心,采用整個(gè)溫度傳感器(DS18B20)對(duì)溫度進(jìn)行檢測,以液晶顯示屏(LCD1602)顯示檢測溫度,通過繼電器對(duì)加熱降溫系統(tǒng)進(jìn)行控制;溫度過高或過低,蜂鳴器報(bào)警提示;溫度偏低進(jìn)行熱風(fēng)機(jī)加熱處理;溫度偏高進(jìn)行冷風(fēng)機(jī)降溫處理。系統(tǒng)總體控制框圖如圖2.1所示:
  
2.3 功能模塊
    根據(jù)總系統(tǒng)的結(jié)構(gòu)可以將其分為五個(gè)功能模塊:單片機(jī)主控制模塊、溫度信號(hào)采集模塊、溫度處理模塊、液晶屏溫度顯示模塊、蜂鳴器報(bào)警模塊。單片機(jī)主控制模塊即整個(gè)系統(tǒng)的核心模塊,是一個(gè)AT89C51芯片,主要通過執(zhí)行其程序存儲(chǔ)器Rom中得到程序來對(duì)其4個(gè)并行I/O口進(jìn)行讀寫操作完成對(duì)其他模塊的控制。溫度信號(hào)采集模塊是由一個(gè)溫度信號(hào)采集器組成,主要是溫度信號(hào)采集并將數(shù)據(jù)傳回給單片機(jī)主控制模塊。傳感器采集的溫度值通過傳回給主控制模塊AT89C51單片機(jī)進(jìn)行處理,然后送入液晶顯示器進(jìn)行溫度顯示。溫度處理模塊是由繼電器控制,熱電機(jī)和冷電機(jī)分別來對(duì)溫度進(jìn)行升溫、降溫處理。液晶屏溫度顯示模塊當(dāng)然就是對(duì)溫度的當(dāng)前值進(jìn)行顯示。蜂鳴器報(bào)警模塊就是對(duì)當(dāng)采集的溫度值大于或小于用戶自定義的臨界溫度值進(jìn)行報(bào)警提示。

整個(gè)設(shè)計(jì)總體分為以下幾個(gè)部分:控制部分、顯示部分、溫度采集部分、按鍵控制部分。

控制部分由單片機(jī)AT89C51芯片在程序控制和外圍簡單組合電路作用下運(yùn)行,和控制溫度的上、下限,和LED的溫度顯示。控制發(fā)光的二極管的亮滅,起到提醒報(bào)警功能。

顯示部分

顯示電路采用1602LCD顯示屏從P2口送數(shù),P0口掃描。有兩部分顯示電路,第一是顯示DS18B20溫度傳感器所檢測的當(dāng)前溫度,第二是設(shè)定恒定的溫度值。

溫度采集部分由DS18B20智能溫度傳感器直接采集被測溫度。

按鍵控制部分由三個(gè)按鍵控制調(diào)節(jié),用來調(diào)節(jié)溫度的恒定限值,起到預(yù)設(shè)調(diào)節(jié)作用。

  1. #include<reg51.h>
  2. #include<intrins.h>
  3. #include<math.h>
  4. #include<string.h>

  5. //PID結(jié)構(gòu)體存儲(chǔ)PID參數(shù)
  6. struct PID {
  7. unsigned int SetPoint; // 設(shè)定目標(biāo) Desired Value
  8. unsigned int Proportion; // 比例常數(shù) Proportional Const
  9. unsigned int Integral; // 積分常數(shù) Integral Const
  10. unsigned int Derivative; // 微分常數(shù) Derivative Const
  11. unsigned int LastError; // Error[-1]
  12. unsigned int PrevError; // Error[-2]
  13. unsigned int SumError; // Sums of Errors
  14. };
  15. struct PID spid; // PID Control Structure

  16. unsigned int rout; // PID Response (Output)
  17. unsigned int rin; // PID Feedback (Input)

  18. sbit data1=P1^0;
  19. sbit clk=P1^1;
  20. sbit plus=P2^0;
  21. sbit subs=P2^1;
  22. sbit stop=P2^2;
  23. sbit output=P3^4;
  24. sbit DQ=P3^3;

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


回復(fù)

使用道具 舉報(bào)

ID:1 發(fā)表于 2018-10-1 22:46 | 顯示全部樓層
能補(bǔ)一下word嗎?
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

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

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

快速回復(fù) 返回頂部 返回列表
主站蜘蛛池模板: 一区二区在线 | 精品久久久久久久久久久久久久 | 亚洲一区二区三区免费视频 | 91在线精品视频 | 国产精品日韩欧美一区二区三区 | 国产欧美精品一区二区三区 | 丝袜美腿av | 一区二区视频在线 | 中文字幕在线播放第一页 | 久草在线高清 | 福利精品 | 久久久久久免费毛片精品 | 97精品国产97久久久久久免费 | 91原创视频在线观看 | 九九久久精品视频 | 欧美精品久久久久 | 日韩三级电影在线看 | 日本高清aⅴ毛片免费 | 久久国产欧美日韩精品 | 精品国产免费人成在线观看 | 国产精品不卡视频 | 久热久热 | 视频在线亚洲 | 91精品国产乱码久久久久久久久 | 午夜精品一区二区三区免费视频 | 亚洲狠狠 | 九九爱这里只有精品 | www.99精品 | 亚洲欧美精品久久 | 狠狠做深爱婷婷综合一区 | 国产成人精品久久二区二区91 | 国产精品一区二区三区四区五区 | 一区二区三区在线免费观看视频 | 黄视频免费在线 | 91精品国产99 | 欧美老妇交乱视频 | 亚洲综合色网 | 91综合在线视频 | 国产999精品久久久 日本视频一区二区三区 | 国产精品视频500部 a久久 | 欧美4p |