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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 10881|回復: 6
打印 上一主題 下一主題
收起左側

51單片機的pid算法溫度控制程序Proteus仿真圖與原理圖PCB文件

  [復制鏈接]
跳轉到指定樓層
樓主
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


Altium Designer畫的原理圖和PCB圖如下:(51hei附件中可下載工程文件)


單片機源程序如下:
  1. #include <REGX51.H>
  2. #define Kp 5        //比例系數
  3. #define Ki 2    //積分系數
  4. #define Kd 1        //微分系數

  5. unsigned char m,n,p;                          //溫度的十位 個位 小數
  6. unsigned char test_temp;                //溫度檢定標志
  7. unsigned char key_set_flag;                //按鍵設定進入標志
  8. unsigned char flag=1;                        //按鍵保持標志
  9. unsigned char Change_step=1,e;        //溫度設置步進
  10. unsigned char T0_H = 0,T0_L = 0,T1_H=0,T1_L=0;
  11. int Real_temp;                //實際溫度值
  12. int Set_temp;                //設置溫度
  13. int Disp_temp;                //顯示溫度
  14. int last_error;                //上次誤差
  15. float I_term;                //前面溫差和
  16. bit        key_hold;
  17. int PID_MAX;
  18. unsigned int out,PWMT,counter,kk,outp,dz;
  19. int time;        //脈沖觸發時刻

  20. sbit DQ=P2^4;        //定義DS18b20的管腳

  21. sbit RS = P2^0;   //定義液晶屏定義端口
  22. sbit RW = P2^1;          //定義液晶屏定義端口
  23. sbit EN = P2^2;          //定義液晶屏定義端口

  24. sbit k1=P1^0;
  25. sbit k2=P1^1;
  26. sbit k3=P1^2;
  27. sbit PWM=P2^7;        //PWM控制腳
  28. sbit led1=P3^5;
  29. sbit led2=P3^6;
  30. sbit led3=P3^7;
  31. sbit beep=P1^3;


  32. #define RS_CLR RS=0
  33. #define RS_SET RS=1

  34. #define RW_CLR RW=0
  35. #define RW_SET RW=1

  36. #define EN_CLR EN=0
  37. #define EN_SET EN=1

  38. unsigned char aa[]={' ',' ','S','e','t','u','p',':',' ',' ','.',' ',' ',' ',' ',' '};           //Distance
  39. unsigned char bb[]={' ',' ',' ',' ',' ',' ',' ','.',' ',' ',' ',' ',' ',' ',' ',' '};       


  40. void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s);
  41. void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data);
  42. void init();                        //初始化
  43. /*------------------------------------------------
  44. uS延時函數,含有輸入參數 unsigned char t,無返回值
  45. unsigned char 是定義無符號字符變量,其值的范圍是
  46. 0~255 這里使用晶振12M,精確延時請使用匯編,大致延時
  47. 長度如下 T=tx2+5 uS
  48. ------------------------------------------------*/
  49. void DelayUs2x(unsigned char t)
  50. {   
  51.         while(--t);
  52. }
  53. /*------------------------------------------------
  54. mS延時函數,含有輸入參數 unsigned char t,無返回值
  55. unsigned char 是定義無符號字符變量,其值的范圍是
  56. 0~255 這里使用晶振12M,精確延時請使用匯編
  57. ------------------------------------------------*/
  58. void DelayMs(unsigned char t)
  59. {
  60.           while(t--)                 //大致延時1mS
  61.         {
  62.              DelayUs2x(245);
  63.                  DelayUs2x(245);
  64.         }
  65. }

  66. /*****延時子程序*****/
  67. void delay(unsigned int t)
  68. {
  69.         for(;t>0;t--);
  70. }
  71. void delay_50us(unsigned int t)
  72. {
  73.         unsigned char j;
  74.         for(;t>0;t--)
  75.                 for(j=19;j>0;j--);
  76. }

  77. /*****初始化DS18B20*****/
  78. unsigned char Init_DS18B20(void)
  79. {
  80.   unsigned char x=0;
  81.   DQ = 1;      //DQ復位
  82.   delay(8);    //稍做延時
  83.   DQ = 0;      //單片機將DQ拉低
  84.   delay(80);   //精確延時,大于480us
  85.   DQ = 1;      //拉高總線
  86.   delay(8);
  87.   x = DQ;      //稍做延時后,如果x=0則初始化成功,x=1則初始化失敗
  88.   delay(4);
  89.   return x;
  90. }

  91. /*****讀一個字節*****/
  92. unsigned char ReadOneChar(void)
  93. {
  94.   unsigned char i=0;
  95.   unsigned char dat = 0;
  96.   for (i=8;i>0;i--)
  97.   {
  98.     DQ = 0;     // 給脈沖信號
  99.     dat>>=1;
  100.     DQ = 1;     // 給脈沖信號
  101.     if(DQ)
  102.             dat|=0x80;
  103.         delay(4);
  104.   }
  105.   return(dat);
  106. }

  107. /*****寫一個字節*****/
  108. void WriteOneChar(unsigned char dat)
  109. {
  110.   unsigned char i=0;
  111.   for (i=8; i>0; i--)
  112.   {
  113.     DQ = 0;
  114.     DQ = dat&0x01;
  115.         delay(4);
  116.     DQ = 1;
  117.     dat>>=1;
  118.   }
  119.   delay(4);
  120. }

  121. /*****讀取溫度*****/
  122. int ReadTemperature(void)
  123. {
  124.           unsigned char a=0;
  125.           unsigned char b=0;
  126.           unsigned int t=0;
  127.           t=Init_DS18B20();
  128.           if(t) return Real_temp;
  129.           WriteOneChar(0xCC);  //跳過讀序號列號的操作
  130.           WriteOneChar(0x44);  //啟動溫度轉換
  131.           t=Init_DS18B20();
  132.           if(t) return Real_temp;
  133.           WriteOneChar(0xCC);  //跳過讀序號列號的操作
  134.           WriteOneChar(0xBE);  //讀取溫度寄存器
  135.           a=ReadOneChar();     //讀低8位
  136.           b=ReadOneChar();     //讀高8位
  137.           t=b;
  138.           t<<=8;
  139.           t=t|a;
  140.           if(t<=0||t>0x900)
  141.         return Real_temp;
  142.         t=t*0.625+0.5;
  143.           return(t);
  144. }



  145. void key_set(void)
  146. {
  147.         if(k1==0)
  148.         {
  149.                 delay(10);
  150.                 while(!k1);
  151.                 key_hold=~key_hold;
  152.         }
  153.         if(key_hold==0)
  154.         {
  155.             if(k2==0)
  156.                 {
  157.                         delay(10);
  158.                     while(!k2);
  159.                         Set_temp=Set_temp+1;
  160.                         if(Set_temp>99)
  161.                         Set_temp=99;
  162.                 }
  163.             if(k3==0)
  164.                 {
  165.                         delay(10);
  166.                         while(!k3);
  167.                         Set_temp=Set_temp-1;
  168.                         if(Set_temp<1)
  169.                         Set_temp=1;
  170.                 }
  171.                 aa[8]=10*Set_temp/100+'0';
  172.                 aa[9]=10*Set_temp/10%10+'0';
  173.                 aa[11]=10*Set_temp%10+'0';
  174.                 LCD_Write_String(0,0,aa);
  175.         }
  176. }

  177. int PID(int Set_value,int Real_value) //標準PID溫度控制算法
  178. {
  179.         float uk ,uk1 ,duk;
  180.         int pid_out,e ,e1 ,e2;
  181.         e=Set_value-Real_value;//誤差量
  182.         duk=Kp*(e-e1)+Ki*e+Kd*(e-2*e1+e2);  //+Kd*(e-2e1+e2)
  183.         uk=uk1+duk;
  184.         pid_out=(int)uk;
  185.         uk1=uk;
  186.         e2=e1;
  187.         e1=e;
  188.         if(pid_out>1000)
  189.         {
  190.                 pid_out=998;
  191.         }
  192.         else if(pid_out<2)
  193.         {
  194.                 pid_out=2;
  195.         }
  196.         outp=pid_out;

  197.         return(pid_out);
  198.                
  199. }


  200. void T0_int(void) interrupt 1
  201. {
  202.         T0_H = (65535-2000)/256;                                //PWM=1高位初值計算
  203.         T0_L = (65535-2000)%256;                                  //PWM=1低位初值計算
  204.         TH0 = T0_H;                                 //通的初值高位
  205.         TL0= T0_L;                                 //通的初值低位
  206.         kk++;
  207.         if(kk>1000)
  208.         kk=0;
  209.         if(kk>outp)
  210.         PWM=1;
  211.         else PWM=0;
  212. //        }

  213. }
  214. void main()
  215. {       
  216.         PWMT=128;                        //128級步進PWM控制               
  217.         PID_MAX=PWMT;
  218.         counter=0;
  219.         out=0;
  220.         PWM=1;
  221.         I_term=0;
  222.         last_error=0;
  223.         Set_temp=30;                //初始設定溫度為30度
  224.         init();
  225.         Real_temp=Set_temp*10;
  226.         key_hold=1;
  227.           Init_DS18B20();
  228.           WriteOneChar(0xCC);        //跳過讀序號列號的操作
  229.           WriteOneChar(0x44); //啟動溫度轉換
  230.         delay_50us(150);        //等待溫度測量                  delay_50us(15000);
  231.         TMOD=0x01;                        //定時器0模式1               
  232.         TR0=1;
  233.         ET0=1;
  234.         IT0=1;
  235.         EX0=1;
  236.         EA=1;

  237.         aa[12]=0xdf;
  238.         aa[13]=0x43;
  239.         bb[9]=0xdf;
  240.         bb[10]=0x43;
  241.         aa[8]=10*Set_temp/100+'0';
  242.         aa[9]=10*Set_temp/10%10+'0';
  243.         aa[11]=10*Set_temp%10+'0';
  244.         LCD_Write_String(0,0,aa);
  245.         while(1)
  246.         {
  247.                 counter++;
  248.                 DelayMs(500);
  249.                 if(counter>4)
  250.                 {
  251.                         test_temp=1;        //進行一次溫度檢定
  252.                         counter=0;                               
  253.                 }
  254.                 if(test_temp)         //溫度檢定標志置位,進入溫度PID調節
  255.                 {
  256.                         Real_temp=ReadTemperature(); //采集當前實際溫度               
  257.                         test_temp=0;                                 //檢定完成,清溫度檢定標志
  258.                         bb[5]=Real_temp/100+'0';
  259.                         bb[6]=Real_temp/10%10+'0';
  260.                         bb[8]=Real_temp%10+'0';
  261.                         LCD_Write_String(0,1,bb);
  262.                         if((Real_temp/10)<(Set_temp))
  263.                         {   
  264.                                 beep=~beep;
  265.                                 led1=~led1;
  266.                                 led2=1;
  267.                     }
  268.                 else if((Real_temp/10)>(Set_temp))
  269.                         {   
  270.                                 beep=~beep;
  271.                                 led3=~led3;
  272.                                 led2=1;
  273.                     }
  274.                         else
  275.                         {
  276.                                 beep=1;
  277.                                 led1=1;
  278.                                 led2=0;
  279.                                 led3=1;
  280.                         }
  281.                 }
  282.                 if((Real_temp/10)<(Set_temp-1))
  283.                 {   
  284.                         outp=998;
  285.             }
  286.         else if((Real_temp/10)>(Set_temp+1))
  287.                 {   
  288.                         outp=2;
  289.             }
  290.                 else
  291.                 {
  292.                         PID(Set_temp*10,Real_temp); //PID程序       
  293.                 }
  294.                        
  295.                 key_set();        //按鍵溫度設置
  296.         }
  297. }

  298. ///////////////////////////////////////////////////
  299. //          液晶屏顯示處理
  300. ///////////////////////////////////////////////////

  301. void write_com(unsigned char com) //寫命令
  302. {
  303.         RS_CLR;
  304.         RW_CLR;
  305.         P0=com;
  306.         DelayMs(1);
  307.         EN_SET;
  308.         DelayMs(1);
  309.         EN_CLR;
  310. ……………………

  311. …………限于本文篇幅 余下代碼請從51黑下載附件…………
復制代碼

所有資料51hei提供下載:
程序仿真.zip (426.9 KB, 下載次數: 305)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

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

使用道具 舉報

沙發
ID:927405 發表于 2021-5-26 09:20 | 只看該作者
pid算法程序是通用的嗎??樓主
回復

使用道具 舉報

板凳
ID:940811 發表于 2021-6-20 18:17 來自手機 | 只看該作者
程序很有用,最好能把各個硬件說清楚
回復

使用道具 舉報

地板
ID:1047200 發表于 2022-10-26 22:40 | 只看該作者
硬件講解還不夠詳細
回復

使用道具 舉報

5#
ID:688008 發表于 2022-10-27 09:20 | 只看該作者
proteus用的啥版本?
回復

使用道具 舉報

6#
ID:156220 發表于 2022-10-27 20:57 | 只看該作者
學習學習PID
回復

使用道具 舉報

7#
ID:71189 發表于 2023-4-23 16:26 | 只看該作者
pid算法程序是通用的嗎??樓
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 国产精品视频在线观看 | 成人免费大片黄在线播放 | 精品乱人伦一区二区三区 | 免费黄色的视频 | 伊人伊人网| 欧美国产在线一区 | 伊人久久精品一区二区三区 | 国产亚洲网站 | 亚洲欧洲精品一区 | 91资源在线| 中文字幕 在线观看 | 黄色大片视频 | 一区二区视频在线 | 久久久久久亚洲精品 | 久久久久久亚洲精品 | 久草视频在线播放 | 麻豆亚洲 | 久久精品日产第一区二区三区 | 手机看片在线播放 | 国产精选一区 | 午夜精品| 欧美精产国品一二三区 | 日韩精品一区二区三区视频播放 | 农夫在线精品视频免费观看 | 午夜小视频免费观看 | 成人在线精品 | 久久乐国产精品 | 精品在线一区二区三区 | 91一区二区三区在线观看 | 久久久久久毛片免费观看 | 欧美成人精品在线观看 | 91久久久精品国产一区二区蜜臀 | 欧美成人hd | 美女一区二区在线观看 | 欧美一区二区三区在线观看视频 | 日韩一区二区三区在线 | 美女一级毛片 | 日本中文字幕一区 | 亚洲视频一区在线观看 | 美女久久久久久久 | 欧美视频一区二区三区 |