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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

基于51單片機的水溫PID控制恒溫系統Proteus仿真源程序

  [復制鏈接]
跳轉到指定樓層
樓主
基于51單片機的PID控制恒溫系統protues仿真,樓主之前找了很久,沒找到好用的,這個是樓主花了一點小代價找到的,現在免費分享給那些需要的伙伴吧,希望能幫助到你們一點

仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)


單片機源程序如下:
  1. #include"reg51.h"
  2. #define uchar unsigned char
  3. #define uint unsigned int
  4. #define ulong unsigned long
  5. /*****************引腳定義*********************************/
  6. //l298n
  7. sbit output=P2^5;
  8. sbit in1=P2^3;
  9. sbit in2=P2^4;
  10. /********************************/
  11. //AD芯片
  12. sbit CLOCK=P3^1;
  13. sbit D_IN=P2^7;
  14. sbit D_OUT=P2^6;
  15. sbit _CS=P3^0;
  16. /********************************/
  17. //lcd液晶
  18. sbit lcdrs=P2^0;
  19. sbit lcdrw=P2^1;
  20. sbit lcden=P2^2;
  21. /********************************/
  22. //燈
  23. sbit led=P3^2;
  24. //蜂鳴器
  25. sbit speaker=P3^3;
  26. /*****************引腳定義*********************************/
  27. /*****************變量定義(申明)*********************************/
  28. int freq=500,pwm=0;
  29. uchar setflag=0,pageflag=0,ok=0;
  30. float pwm_temp=0;
  31. float  KP=100,KI=10,KD=0;  
  32. uint  pul_count=0;
  33. float ek=0,ek1=0,ek2=0;
  34. float keytemp=0;

  35. uchar code str[16]="    welcome!    ";
  36. uchar code str1[16]=" temperature PID";
  37. uchar code str2[16]="set-T     now-T " ;
  38. uchar code str3[16]="P:     I:     D:" ;
  39. uchar code str4[16]="set-P:       " ;
  40. uchar code str5[16]="set-I:       " ;
  41. uchar code str6[16]="set-D:       " ;
  42. void Init(void);
  43. uint adcread(uchar port);
  44. void delay(uint n);
  45. void writecom(uchar com);
  46. void writedata(uchar date);
  47. void initlcd();
  48. float keyscan(void);
  49. uchar keyscans(void);
  50. void lcdnumdisplay(uchar pos,double  f);
  51. void lcdnumdisplays(uchar pos,double  f);
  52. uint read_pul();
  53. void mypid(float Kp,float Ki,float Kd,uint count,uint point);
  54. /*****************變量定義(申明)*********************************/

  55. void main()
  56. {
  57.     uchar i;float scantemp;
  58.         float adnum0=0;
  59.         float adnum1=0;
  60.         bit init0,init1,init2,init3,init4;
  61.         Init();
  62.         initlcd();
  63.     writecom(0x80);
  64.         for(i=0;i<16;i++)writedata(str[i]);                 //huanyin
  65.         writecom(0x80+0x40);
  66.         for(i=0;i<16;i++)writedata(str1[i]);          //shuming
  67.         delay(2000);
  68. //        output=0;
  69. //        in1=1;in2=0;
  70. //        while(1);
  71.         while(1)
  72.         {
  73.                  pwm_temp=500*(float)(adnum0)/4095;
  74.                  //pwm=pwm_temp;
  75.                  mypid(KP,KI,KD,adnum1,pwm_temp);
  76.                  scantemp=keyscan();
  77.                  if(adnum1>=pwm_temp-1.5&&adnum1<=pwm_temp+1.5)
  78.                    {
  79.                         led=0;
  80.                         speaker=1;
  81.                    }
  82.                 else{
  83.                     led=1;
  84.                         speaker=0;
  85.                         }
  86.             if(setflag==0)
  87.                 {
  88.                  adnum0=adcread(0);
  89.                  adnum1=adcread(1)/45;
  90.                  if(init0==0)
  91.                  {
  92.                  initlcd();
  93.                  writecom(0x80);
  94.              for(i=0;i<16;i++)
  95.                                         writedata(str2[i]);          //shuming
  96.                         init0=1;init1=0;init2=0;init3=0;init4=0;
  97.                  }
  98.                  lcdnumdisplays(0x80+0x40,(float)pwm_temp);         //pwm_temp
  99.                  lcdnumdisplays(0x80+0x4a,(float)adnum1);         
  100.                  }

  101.                  if(setflag!=0&&pageflag==0)
  102.                  {
  103.                     if(init1==0)
  104.                         {
  105.                         initlcd();
  106.                         writecom(0x80);
  107.                         for(i=0;i<16;i++)writedata(str3[i]);          
  108.                         init0=0;init1=1;init2=0;init3=0;init4=0;
  109.                         }
  110.                         lcdnumdisplays(0x80+0x40,KP);
  111.                         lcdnumdisplays(0x80+0x46,KI);
  112.                         lcdnumdisplays(0x80+0x4D,KD);       
  113.                  }
  114.                  if(setflag!=0&&pageflag==1)
  115.                  {
  116.                     if(init2==0)
  117.                         {
  118.                         initlcd();
  119.                         writecom(0x80);
  120.                         for(i=0;i<16;i++)writedata(str4[i]);          
  121.                         init0=0;init1=0;init2=1;init3=0;init4=0;
  122.                         }
  123.                         lcdnumdisplays(0x80+0x40,scantemp);
  124.                         if(ok==1){KP=scantemp;ok=0;}       
  125.                  }
  126.                  if(setflag!=0&&pageflag==2)
  127.                  {
  128.                     if(init3==0)
  129.                         {
  130.                         initlcd();
  131.                         writecom(0x80);
  132.                         for(i=0;i<16;i++)writedata(str5[i]);          
  133.                         init0=0;init1=0;init2=0;init3=1;init4=0;
  134.                         }
  135.                         lcdnumdisplays(0x80+0x40,scantemp);
  136.                         if(ok==1){KI=scantemp;ok=0;}       
  137.                  }
  138.                  if(setflag!=0&&pageflag==3)
  139.                  {
  140.                     if(init4==0)
  141.                         {
  142.                         initlcd();
  143.                         writecom(0x80);
  144.                         for(i=0;i<16;i++)writedata(str6[i]);        
  145.                         init0=0;init1=0;init2=0;init3=0;init4=1;
  146.                         }
  147.                         lcdnumdisplays(0x80+0x40,scantemp);
  148.                         if(ok==1){KD=scantemp;ok=0;}               
  149.                  }             
  150.     }
  151. }

  152. void mypid(float Kp,float Ki,float Kd,uint count,uint point)
  153. {
  154.    static float Uk;
  155.    ek=point-count;
  156. //   if(ek>=5&&ek<=-5)   //積分分離                                       
  157.    {Uk=Kp*(ek-ek1)+Ki*ek+Kd*(ek-2*ek1+ek2);}      
  158. //   else
  159. //   Uk=Kp*ek;
  160.    pwm=Uk;
  161.          //lcdnumdisplays(0x80+0x4a,(float)pwm);       
  162.    if(pwm>freq)pwm=freq;
  163.    if(pwm<=0){pwm=0;in1=0;in2=1;}
  164.    if(pwm>0) {in1=1;in2=0;}
  165.    ek2=ek1;
  166.    ek1=ek;
  167. }
  168. uint read_pul()
  169. {
  170.   uint t1,th1,th2;                                 
  171.   uint val;
  172.   while(1)
  173.   {
  174.      th1=TH1;
  175.          t1=TL1;
  176.          th2=TH1;
  177.          if(th1==th2)
  178.            break;
  179.   }      
  180.      val=th1*256+t1;
  181.          return val;
  182. }


  183. void delay(uint n)
  184. {
  185. uint i,j;
  186. for(i=n;i>0;i--)
  187. for(j=1;j>0;j--);
  188. }

  189. void Init(void)//初始化函數
  190. {
  191.     TMOD=0x51;
  192.         TH0=(65536-10)/256;
  193.         TL0=(65536-10)%256;
  194.         EA=1;
  195.         ET0=1;               
  196.         TR0=1;
  197.         TH1=0;
  198.         TL1=0;
  199.         TR1=1;
  200. }

  201. void  Timer_0(void) interrupt 1
  202. {
  203.        static ulong t_count=0;
  204.            static uint num_count=0;
  205.        TR0=0;
  206.            TH0=(65536-10)/256;
  207.            TL0=(65536-10)%256;
  208.            TR0=1;
  209.            num_count++;
  210. //           t_count++;
  211. //           if(t_count==2320)
  212. //                 {
  213. //                             t_count=0;
  214. //                                 TR1=0;
  215. //                                 pul_count=read_pul();               
  216. //                         TH1=0;
  217. //                         TL1=0;
  218. //                                 TR1=1;
  219. //                 }
  220.            if(num_count>freq)num_count=0;    //1khz;
  221.            if(num_count<pwm)output=1;
  222.            else output=0;
  223.           
  224. }
  225. //lcd寫命令
  226. void writecom(uchar com)
  227. {
  228.    lcdrs=0;
  229.    P0=com;
  230.    delay(1);
  231.    lcden=1;
  232.    delay(1);
  233.    lcden=0;         
  234. }
  235. //lcd寫數據
  236. void writedata(uchar date)
  237. //初始化lcd
  238. {  
  239.    lcdrs=1;          
  240.    P0=date;
  241.    delay(1);
  242.    lcden=1;
  243.    delay(1);
  244.    lcden=0;          
  245. }
  246. void initlcd()
  247. {
  248.    lcdrw=0;
  249.    writecom(0x38);delay(1);       
  250.    writecom(0x0c);delay(1);          
  251.    writecom(0x06);delay(1);
  252.    writecom(0x01);delay(5);
  253. }

  254. //adc讀
  255. uint adcread(uchar port)
  256. {                 
  257.    uint ad=0,i;
  258.        
  259.    CLOCK=0;
  260.    _CS=0;
  261.    port<<=4;
  262.    for(i=0;i<12;i++)
  263.   {
  264.                 if(D_OUT)
  265.                         ad|=0x01;
  266.                 D_IN=(bit)(port&0x80);
  267.                 CLOCK=1;
  268.                 delay(1);
  269.                 CLOCK=0;
  270.                 delay(1);
  271.                 port<<=1;
  272.                 ad<<=1;
  273.   }
  274.   _CS=1;
  275.        
  276.   ad>>=1;
  277.   return(ad);
  278. }
  279. //lcd顯示數據1
  280. void lcdnumdisplays(uchar pos,float f)                //(0.001-99999) 精度低 但方便數據更新
  281. {  
  282.    uchar i;
  283.    writecom(pos);
  284.    if(f>65535&&f<0.001) for(i=0;i<5;i++)writedata(0x23);//超出范圍 顯示#
  285.    else if(f==0){writedata(0x30);for(i=0;i<4;i++)writedata(0x20);}
  286.    else
  287.      {
  288.            if((uint)f/10000!=0)
  289.            {
  290.             writedata((uint)f/10000+0x30);
  291.             writedata((uint)f%10000/1000+0x30);
  292.                 writedata((uint)f%1000/100+0x30);
  293.                 writedata((uint)f%100/10+0x30);
  294.                 writedata((uint)f%10+0x30);
  295.            }
  296.            else
  297.            {
  298.             if((uint)f/1000!=0)
  299.                 {
  300.                 writedata(0+0x30);
  301.             writedata((uint)f/1000+0x30);
  302.                 writedata((uint)f%1000/100+0x30);
  303.                 writedata((uint)f%100/10+0x30);
  304.                 writedata((uint)f%10+0x30);
  305.                 }
  306.                 else
  307.                 {
  308.                   if((uint)f/100!=0)
  309.                   {
  310.                     writedata((uint)f/100+0x30);
  311.                            writedata((uint)f%100/10+0x30);
  312.                     writedata((uint)f%10+0x30);
  313.                         writedata(0x2e);
  314.                         writedata((uint)(f*10)%10+0x30);
  315.                   }
  316.                   else
  317.                   {
  318.                     if((uint)f/10!=0)
  319.                         {
  320.                         writedata((uint)f/10+0x30);
  321.                         writedata((uint)f%10+0x30);
  322.                         writedata(0x2e);
  323.                         writedata((uint)(f*10)%10+0x30);
  324.                         writedata((uint)(f*100)%10+0x30);
  325.                         }
  326.                         else
  327.                         {
  328.                         writedata((uint)f%10+0x30);
  329.                         writedata(0x2e);
  330.                         writedata((uint)(f*10)%10+0x30);
  331.                         writedata((uint)(f*100)%10+0x30);
  332.                         writedata((uint)(f*1000)%10+0x30);
  333.                         }
  334.                   }
  335.                  }
  336.            }
  337.          }
  338. }


  339. //lcd顯示數據2
  340. void lcdnumdisplay(uchar pos,float f0)                //(0.00001-99999.99999) 精度高 但數據需刷屏更新
  341. {
  342.    uchar temp;
  343.    ulong    f;
  344.    writecom(pos);
  345.    f=(ulong)f0;
  346.    temp=f/10000;         //整數部分
  347.    if(temp!=0)
  348.      {
  349.             writedata(temp+0x30);
  350.                 writedata(f%10000/1000+0x30);
  351.                 writedata(f%1000/100+0x30);
  352.                 writedata(f%100/10+0x30);
  353.                 writedata(f%10+0x30);
  354.          }
  355.    else
  356.      {
  357.             temp=f%10000/1000;
  358.                 if(temp!=0)
  359.                 {
  360.                    writedata(temp+0x30);
  361.                    writedata(f%1000/100+0x30);
  362.                    writedata(f%100/10+0x30);
  363.                    writedata(f%10+0x30);
  364.                 }
  365.                 else
  366.                 {
  367.                    temp=f%1000/100;
  368.                    if(temp!=0)
  369.                    {
  370.                       writedata(temp+0x30);
  371.                           writedata(f%100/10+0x30);
  372.                       writedata(f%10+0x30);
  373.                    }
  374.                    else
  375.                    {
  376.                       temp=f%100/10;
  377.                           if(temp!=0)
  378.                                 {
  379.                                    writedata(temp+0x30);
  380.                                    writedata(f%10+0x30);     
  381.                                 }
  382.                                 else
  383.                                 {
  384.                                    temp=f%10;
  385.                                    if(temp!=0)
  386.                                    {
  387.                                      writedata(temp+0x30);
  388.                                    }
  389.                                    else writedata(0+0x30);
  390.                                  }
  391.                           }  
  392.                    }
  393.                 }


  394.     if((ulong)(f0*10)%10!=0||(ulong)(f0*100)%10!=0||(ulong)(f0*1000)%10!=0||(ulong)(f0*10000)%10!=0)                  
  395.         {
  396.                       writedata(0x2e);
  397.                    temp=(ulong)(f0*10000)%10;
  398.                    if(temp!=0)
  399.                    {
  400.                      writedata((ulong)(f0*10)%10+0x30);
  401.                          writedata((ulong)(f0*100)%10+0x30);
  402.                          writedata((ulong)(f0*1000)%10+0x30);
  403.                          writedata(temp+0x30);
  404.                    }
  405.                    else
  406.                    {
  407.                        temp=(ulong)(f0*1000)%10;
  408.                        if(temp!=0)
  409.                            {
  410.                              writedata((ulong)(f0*10)%10+0x30);
  411.                              writedata((ulong)(f0*100)%10+0x30);
  412.                                  writedata(temp+0x30);
  413.                            }
  414.                            else
  415.                            {
  416.                               temp=(ulong)(f0*100)%10;
  417.                                   if(temp!=0)
  418.                                   {
  419.                                     writedata((ulong)(f0*10)%10+0x30);
  420.                                         writedata(temp+0x30);
  421.                                   }
  422.                                   else
  423.                                   {
  424.                                     temp=(ulong)(f0*10)%10;
  425.                                         if(temp!=0)
  426.                                           writedata(temp+0x30);
  427.                                   }
  428.                             }            
  429.                       }
  430.                     }
  431. }



  432. uchar keyscans(void)//矩陣鍵盤掃描
  433. {
  434.     uchar i, j, temp, Buffer[4] = {0xef, 0xdf, 0xbf, 0x7f};
  435.     for(j = 0; j < 4; j++)    //循環四次
  436.    {
  437.       P1 = Buffer[j];         //在P1高四位分別輸出一個低電平
  438.       temp = 0x01;            //計劃先判斷P1.0位
  439.       for(i = 0; i < 4; i++)
  440.    {
  441.         if(!(P1 & temp))      //從P1低四位,截取1位
  442.           return (i + j * 4); //返回取得的按鍵值
  443.         temp <<= 1;           //判斷的位,左移一位
  444.    }
  445. ……………………

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

所有資料51hei提供下載:
水溫控制系統PID可調51單片機仿真.zip (100.06 KB, 下載次數: 171)

評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:897014 發表于 2021-5-25 12:07 | 只看該作者
這里面沒有溫度傳感器呀,滑動電阻控制的是設定溫度
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 久久大陆| h网站在线观看 | 欧美中文在线 | 国产欧美日韩一区 | 午夜精品久久久久久久久久久久久 | 日日干天天操 | 三级视频在线观看 | 日本不卡一区二区三区 | 国产精品久久久乱弄 | 日本一二三区高清 | 黄色免费在线网址 | 久久99精品久久久久 | 日日想夜夜操 | 成人在线播放网址 | 久久婷婷国产麻豆91 | 日韩欧美视频在线 | 久久精品一区二区三区四区 | 午夜视频免费在线 | 精品少妇v888av| 亚洲精品中文字幕中文字幕 | 亚洲国产精品一区二区三区 | 日本中文字幕一区 | a级片播放 | 亚洲性免费| 国产精品久久av | 一区二区三区国产 | 欧美一区二区 | 久久99久久99精品免视看婷婷 | 免费在线日韩 | 国产成人综合亚洲欧美94在线 | 涩涩99| 日韩一区二区视频 | 人人看人人爽 | 国产精品视频专区 | www.夜夜骑.com | 国产欧美久久精品 | 91精品国产91久久久久久 | 久久精品日产第一区二区三区 | 国产成人精品999在线观看 | 国产精品亚洲综合 | 欧美日韩精品中文字幕 |