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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

單片機溫控風扇程序 DS18B20 Protuse仿真

[復制鏈接]
跳轉到指定樓層
樓主
ID:1097839 發(fā)表于 2023-11-4 23:05 | 只看該作者 |只看大圖 回帖獎勵 |倒序瀏覽 |閱讀模式
仿真原理圖如下(proteus仿真工程文件可到本帖附件中下載)



仿真圖的單片機代碼和仿真圖在附件里
  1. #include<reg51.h>
  2. #include<intrins.h>                         //包含頭文件

  3. #define uchar unsigned char
  4. #define uint unsigned int                 //宏定義
  5. #include "eeprom52.h"

  6. //////////////////////////////按鍵定義/////////////////////////////////
  7. sbit dj=P1^0;//電機控制端接口
  8. sbit DQ=P1^6;//溫度傳感器接口
  9. sbit key1=P3^5;//設置溫度
  10. sbit key2=P3^6;//溫度加
  11. sbit key3=P3^7;//溫度減
  12. sbit BEEP=P1^3;                            //定義蜂鳴器
  13. bit beep_st;                                     //蜂鳴器間隔標志
  14. sbit w1=P2^4;
  15. sbit w2=P2^5;
  16. sbit w3=P2^6;
  17. sbit w4=P2^7;                          //數(shù)碼管的四個位

  18. uchar table[22]=
  19. {0x3F,0x06,0x5B,0x4F,0x66,
  20. 0x6D,0x7D,0x07,0x7F,0x6F,
  21. 0x77,0x7C,0x39,0x5E,0x79,0x71,
  22. 0x40,0x38,0x76,0x00,0xff,0x37};//'-',L,H,滅,全亮,n         16-21/////共陰數(shù)碼管段選//////////
  23. unsigned int wen_du;                                                //溫度變量  
  24. int shang,xia; //對比溫度暫存變量
  25. uchar dang; //檔位顯示
  26. uchar flag;
  27. uchar d1,d2,d3;//顯示數(shù)據(jù)暫存變量
  28. uchar m;
  29. uchar js;
  30. uchar cs=0;
  31. unsigned char s_t[];
  32. uchar stc[50]={"The current temperature is:"};
  33. //將數(shù)字轉成字符串
  34. void convert_uint_to_uchar_array(unsigned int wen_du, unsigned char s_t[4]) {  
  35.     int i;
  36.                 for (i = 0; i < 4; i++) {  
  37.         s_t[i] = (wen_du >> i * 8) & 0xFF;  
  38.     }  
  39. }  

  40. void delay(unsigned int xms)//延時
  41. {
  42.         unsigned char i, j;
  43.         while(xms--)
  44.         {
  45.                 i = 2;
  46.                 j = 239;
  47.                 do
  48.                 {
  49.                         while (--j);
  50.                 } while (--i);
  51.         }
  52. }
  53. //發(fā)送
  54. void PutString(unsigned char *TXStr)  
  55. {   
  56.                 SCON=0x40;  //串行口方式1
  57.                 PCON=0x80;//增倍波特率
  58.                 TH1=0xf3; //4800波特率
  59.                 TL1=0xf3;
  60.                 TMOD=0x20;  //將T1定時器方式2
  61.                 TR1=1;  //啟動T1
  62.     ES=0;     
  63.       while(*TXStr!=0)
  64.      {                     
  65.         SBUF=*TXStr;
  66.          while(TI==0);
  67.          TI=0;   
  68.         TXStr++;
  69.     }
  70.     ES=1;
  71. }

  72. /*寫eeprom中*/
  73. void write_eeprom()
  74. {
  75.         SectorErase(0x2000);                //清除扇區(qū)
  76.         byte_write(0x2000, shang);        //寫上限數(shù)值到扇區(qū)
  77.         byte_write(0x2001, xia);        //寫下限數(shù)值到扇區(qū)
  78.         byte_write(0x2060, a_a);        //寫初始變量到扇區(qū)指定位置
  79. }

  80. /*把數(shù)據(jù)從單片機內部eeprom中讀出來*/
  81. void read_eeprom()
  82. {
  83.         shang   = byte_read(0x2000);                 //從扇區(qū)讀取上限數(shù)據(jù)
  84.         xia = byte_read(0x2001);                         //從扇區(qū)讀取下限數(shù)據(jù)
  85.         a_a      = byte_read(0x2060);                 //從扇區(qū)讀取初始變量
  86. }

  87. /*開機自檢傳感器eeprom初始化*/
  88. void init_eeprom()
  89. {
  90.         read_eeprom();                //先讀扇區(qū)的數(shù)據(jù)
  91.         if(a_a != 1)                //判斷是否是新單片機(原理:新的單片機扇區(qū)里的數(shù)據(jù)都是0,這里判斷是否不等于1。如果是不等于1,就是等于0,那就是新單片機了,就會執(zhí)行下面的上下限值初始化數(shù)值的語句,并讓a_a變成1,下次開機就會知道是用過的單片機了就會讀取EEPROM里的上下限數(shù)據(jù)了)
  92.         {
  93.                 shang   = 30;        //上限數(shù)值初始為30
  94.                 xia = 20;                //下限數(shù)值初始為20
  95.                 a_a = 1;                //初始值變量賦值1,下次開機就會直接讀取EEPROM內的上下限數(shù)據(jù)
  96.                 write_eeprom();           //將初始的數(shù)據(jù)保存進單片機的EEPROM
  97.         }        
  98. }


  99. /*ds18b20延遲子函數(shù)(晶振12MHz )*/
  100. void delay_18B20(uint i)
  101. {
  102.         while(i--);
  103. }
  104. /*ds18b20初始化函數(shù)*/
  105. void Init_DS18B20()
  106. {
  107.          uchar x=0;
  108.          DQ=1;          //DQ復位
  109.          delay_18B20(8);  //稍做延時
  110.          DQ=0;          //單片機將DQ拉低
  111.          delay_18B20(80); //精確延時 大于 480us
  112.          DQ=1;          //拉高總線
  113.          delay_18B20(14);
  114.          x=DQ;            //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
  115.          delay_18B20(20);
  116. }
  117. /*ds18b20讀一個字節(jié)*/  
  118. uchar ReadOneChar()
  119. {
  120.         uchar i=0;
  121.         uchar dat=0;
  122.         for (i=8;i>0;i--)
  123.          {
  124.                   DQ=0; // 給脈沖信號
  125.                   dat>>=1;
  126.                   DQ=1; // 給脈沖信號
  127.                   if(DQ)
  128.                   dat|=0x80;
  129.                   delay_18B20(4);
  130.          }
  131.          return(dat);
  132. }
  133. /*ds18b20寫一個字節(jié)*/  
  134. void WriteOneChar(uchar dat)
  135. {
  136.          uchar i=0;
  137.          for (i=8;i>0;i--)
  138.          {
  139.                   DQ=0;
  140.                  DQ=dat&0x01;
  141.             delay_18B20(5);
  142.                  DQ=1;
  143.             dat>>=1;
  144.         }
  145. }
  146. /*讀取ds18b20當前溫度*/
  147. void ReadTemperature()
  148. {
  149.         uchar a=0;
  150.         uchar b=0;
  151.         uchar t=0;
  152.         Init_DS18B20();
  153.         WriteOneChar(0xCC);            // 跳過讀序號列號的操作
  154.         WriteOneChar(0x44);         // 啟動溫度轉換
  155.         delay_18B20(100);       // this message is very important
  156.         Init_DS18B20();
  157.         WriteOneChar(0xCC);         //跳過讀序號列號的操作
  158.         WriteOneChar(0xBE);         //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度
  159.         delay_18B20(100);
  160.         a=ReadOneChar();            //讀取溫度值低位
  161.         b=ReadOneChar();                   //讀取溫度值高位
  162.         wen_du=((b*256+a)>>4);    //當前采集溫度值除16得實際溫度值
  163.         
  164.         
  165. }

  166. /*按鍵*/
  167. void zi_keyscan()//自動模式按鍵掃描函數(shù)
  168. {
  169.         if(key1==0)                                                          //設置鍵按下
  170.         {
  171.                 delay(300);                                                  //延時去抖
  172.                 if(key1==0)flag=1;                                  //再次判斷按鍵,按下的話進入設置狀態(tài)
  173.                 while(key1==0);//松手檢測                  //按鍵釋放
  174.         }
  175.         while(flag==1)                                                  //進入設置上限狀態(tài)
  176.         {
  177.                 d1=18;d2=shang/10;d3=shang%10;          //顯示字母H 和上限溫度值
  178.                 if(key1==0)                                                  //判斷設置鍵是否按下
  179.                 {
  180.                         delay(300);                                          //延時去抖
  181.                         if(key1==0)flag=2;                          //按鍵按下,進入設置下限模式
  182.                         while(key1==0);//松手檢測
  183.                 }
  184.                 if(key2==0)                                                  //加鍵按下
  185.                 {
  186.                         delay(300);                                          //延時去抖
  187.                         if(key2==0)                                          //加鍵按下
  188.                         {
  189.                                 shang+=5;                                  //上限加5
  190.                                 if(shang>=100)shang=100;  //上限最大加到100
  191.                         }while(key2==0);//松手檢測
  192.                         write_eeprom();                           //保存數(shù)據(jù)
  193.                 }
  194.                 if(key3==0)                                                  //減鍵按下
  195.                 {
  196.                         delay(300);                                          //延時去抖
  197.                         if(key3==0)                                          //減鍵按下
  198.                         {
  199.                                 shang-=1;                                  //上限減1
  200.                                 if(shang<=10)shang=10;          //上限最小減到10
  201.                         }while(key3==0);//松手檢測
  202.                         write_eeprom();                           //保存數(shù)據(jù)
  203.                 }               
  204.         }
  205.         while(flag==2)                                                  //設置下限
  206.         {
  207.                 d1=17;d2=xia/10;d3=xia%10;                  //顯示字母L 顯示下限溫度值
  208.                 if(key1==0)
  209.                 {
  210.                         delay(300);
  211.                         if(key1==0)flag=0;
  212.                         while(key1==0);//松手檢測
  213.                 }
  214.                 if(key2==0)
  215.                 {
  216.                         delay(300);
  217.                         if(key2==0)
  218.                         {
  219.                                 xia+=5;
  220.                                 if(xia>=95)xia=95;        
  221.                         }while(key2==0);//松手檢測
  222.                         write_eeprom();                           //保存數(shù)據(jù)
  223.                 }
  224.                 if(key3==0)
  225.                 {
  226.                         delay(300);
  227.                         if(key3==0)
  228.                         {
  229.                                 xia-=1;
  230.                                 if(xia<=0)xia=0;        
  231.                         }while(key3==0);//松手檢測
  232.                         write_eeprom();                           //保存數(shù)據(jù)
  233.                 }               
  234.         }
  235. }
  236. void zi_dong()//自動溫控模式
  237. {
  238.         d1=dang;d2=wen_du/10;d3=wen_du%10;                //顯示檔位,顯示當前溫度值
  239.         zi_keyscan();//按鍵掃描函數(shù)
  240.         if(wen_du<xia){dang=0;
  241.                 if(cs==0){
  242.                         BEEP=0;
  243.                         delay(500);
  244.                         BEEP=1;
  245.                         delay(500);
  246.                         
  247.                 }else{        BEEP=1;}
  248.                 cs=1;
  249.         }//低于下限  檔位為0 電機停止
  250.         if((wen_du>=xia)&&(wen_du<=shang))//溫度大于下限,小于上限  1擋
  251.         {dang=1;cs=0;}
  252.         if(wen_du>shang){dang=2;}//溫度大于上限,2檔
  253.         
  254. }

  255. void init()                   //定時器初始化函數(shù)
  256. {
  257.         TMOD=0x01;           //定時器0工作方式1
  258.         TH0=0xf8;
  259.         TL0=0x30;           //定時器初值5ms
  260.         ET0=1;                   //打開定時器0中斷允許
  261.         TR0=1;                   //打開定時器0定時器開關
  262.         EA=1;                   //打開中斷系統(tǒng)總開關
  263. }
  264. void main()                  //主函數(shù)
  265. {
  266.         uchar j;
  267.         dj=0;                  //電機開
  268.         init_eeprom();  //開始初始化保存的數(shù)據(jù)
  269.         for(j=0;j<80;j++)          //先讀取溫度值,防止開機顯示85
  270.         ReadTemperature();
  271.         init();
  272.         while(1)                          //進入while循環(huán)
  273.         {
  274.                 if(js>=50)                        //當js在定時器里加到50次時(js加一次是20ms,加到50次就是1000ms,也就是1秒讀取一次溫度)
  275.                 {
  276.                         ReadTemperature();        //讀取溫度值
  277.                         js=0;                                //定時讀取溫度的變量js清零,重新計時下次讀取溫度
  278.                         
  279.                 }        
  280.                
  281.                 zi_dong();//判斷當前需要哪一個檔位
  282.                
  283.                
  284.         }
  285. }

  286. /*
  287. 控制占空比原理:
  288. 定時器每5ms控制變量m加一,當m加到4時,將m清零。
  289. 也就是占空比的一個周期是5ms*4=20ms,頻率就是50Hz。
  290. 因為m是加四次是一個周期,也就是加一次占空比是加25%。
  291. 下面程序里if(m<=3)dj=1;else dj=0;就是讓dj高電平的時間是m加3次的時間,而dj為低電平的時間就是加第四次的時間,所以占空比就是3/4就是75%
  292. */

  293. void T0_TIME() interrupt 1                  //定時器工作函數(shù),用于PWM工作
  294. {
  295.         TH0=0xf8;
  296.         TL0=0x30;                                          //定時器賦初值5ms
  297.         m++;                                                  //5ms,m加一
  298.         switch(dang)                                  //判斷檔位
  299.         {
  300.                 case 0:dj=0;break;                  //0檔,控制電機停止
  301.                 case 1:if(m<=3)dj=1;else dj=0;break;//控制電機以75%占空比轉動
  302.                 case 2:dj=1;break;                  //2檔,控制電機100%占空比轉動
  303.                 default:;                                  //其他情況,直接跳出
  304.         }
  305.         switch(m)                                          //判斷m的數(shù)值
  306.         {
  307.                 case 1:                                                                        //m為1時
  308.                                 w4=1;P0=table[d1];w1=0; break;        //關閉低四位數(shù)碼管位選;P0口輸出對應數(shù)字的段碼;打開第一位數(shù)碼管位選
  309.                 case 2:
  310.                                 w1=1;P0=table[16];w2=0; break;        //關閉低一位數(shù)碼管位選;P0口輸出對應數(shù)字的段碼;打開第二位數(shù)碼管位選
  311.                 case 3:
  312.                                 w2=1;P0=table[d2];w3=0;        break;        //關閉低二位數(shù)碼管位選;P0口輸出對應數(shù)字的段碼;打開第三位數(shù)碼管位選
  313.                 case 4:
  314.                                 w3=1;P0=table[d3];w4=0;m=0;if(js<50)js++;break; //關閉低三位數(shù)碼管位選;P0口輸出對應數(shù)字的段碼;打開第四位數(shù)碼管位選
  315.                                                                                                                                 //js變量小于50時,就讓js加,加到50后,主函數(shù)里就會執(zhí)行一次讀取溫度函數(shù)
  316.                 default:;                                                                //其他情況時跳出
  317.         }
  318. }
復制代碼

仿真程序: 仿真程序.7z (124.42 KB, 下載次數(shù): 52)

評分

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

查看全部評分

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

使用道具 舉報

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

本版積分規(guī)則

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

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

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 91精品国产91久久久久福利 | 99久久夜色精品国产亚洲96 | 国产精品久久久久久久久污网站 | 日韩中文字幕在线观看视频 | 美女逼网站 | 欧美亚洲国产一区 | 国产视频1 | 国产免费一区二区三区网站免费 | 天堂一区在线观看 | 黑人巨大精品欧美一区二区免费 | 91亚洲国产亚洲国产 | 欧美一区二区三区在线观看 | 成人av在线播放 | 99re在线视频免费观看 | 国产视频综合 | heyzo在线| 一区二区三区视频在线 | 一二区视频| 欧美一区二区三区视频 | 久久久久91 | 色婷婷一区二区三区四区 | 91免费入口 | 美女视频一区二区三区 | 亚洲图片视频一区 | 91精品国产综合久久久久久丝袜 | 国产精品18久久久久久久 | 日韩视频在线观看 | 成人免费在线视频 | 精品一区二区不卡 | 91精品国产一区二区三区香蕉 | 成人精品国产一区二区4080 | 国产精品1 | 久久免费看 | 欧美一区二区黄 | 亚洲女人的天堂 | 精品产国自在拍 | 日本不卡一区 | 热99| 欧美一级在线观看 | 国产精品久久久久久久久免费丝袜 | 国产高清亚洲 |