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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機數字溫度計+燈光報警的proteus仿真+注釋詳細的源碼

  [復制鏈接]
跳轉到指定樓層
樓主
制作出來的實物圖如下:


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


單片機源程序如下:
  1. #include<reg52.h>                                                //包含reg52.h庫文件
  2. #include<math.h>                                                //包含絕對值函數
  3. #define uint unsigned int                                //宏定義uint
  4. #define uchar unsigned char                                //宏定義uchar
  5. sbit lcden=P2^0;                                                //液晶使能端
  6. sbit lcdrw=P2^1;
  7. sbit lcdrs=P2^2;                                                //液晶數據命令選擇端選擇寫數據還是寫命令
  8. sbit DQ = P2^3;                         //通過DQ口讀取溫度值
  9. sbit s1=P1^2;                                                        //選擇按鍵
  10. sbit s2=P1^7;                                                        //加按鍵
  11. sbit s3=P3^3;                                                        //減按鍵
  12. sbit D1=P3^4;             //高溫報警燈
  13. sbit D2=P1^3;             //低溫報警燈
  14. uchar temp_value,num,fig,s1num,figh,figl,t;  //設置全局無符號字符型變量
  15. char h,l;                                                                //設置全局有符號字符型變量
  16. void delay(uint z);                                                //申明延時程序
  17. void init();                                                        //申明LCD初始化程序
  18. void write_com(uchar com);                                //申明寫命令程序
  19. void write_data(uchar date);                        //申明寫數據程序
  20. void keyscan();                                                    //申明按鍵掃描程序
  21. void write_hl(uchar add,char date);            //申明設置的最高低溫度值在LCD上顯示程序
  22. void write_temp_value(uchar add,char date);        //申明溫度值在LCD上顯示程序
  23. void delay_18B20(unsigned int i);                //申明延時程序
  24. void Init_DS18B20(void);                                //申明DS18B20初始化程序
  25. unsigned char ReadOneChar(void);                //申明ds18b20讀一個字節
  26. void WriteOneChar(uchar dat);                        //申明ds18b20讀一個字節
  27. void ReadTemp(void);                                        //申明讀取ds18b20當前溫度
  28. void comp();
  29. void main()
  30. {
  31.         init();                                                                //LCD初始化
  32.         Init_DS18B20();                                                //DS18B20初始化
  33.         while(1)                                                        //大循環
  34.         { if(s1==0||s1num>=1)
  35.                 {        keyscan();                                        //按鍵掃描
  36.                 }
  37.         else{        ReadTemp();                                        //讀取溫度值
  38.                         write_temp_value(0,temp_value);        //LCD顯示溫度值
  39.                 }
  40.                 comp();               
  41.         }
  42. }

  43. void delay(uint z)                                                //延時程序
  44. {
  45.         uint x,y;
  46.         for(x=z;x>0;x--)
  47.         for(y=110;y>0;y--);
  48. }



  49. void init()                                                //LCD初始化程序
  50. {   lcden=0;
  51.           lcdrw=0;
  52.         write_com(0x38);                         //設置16x2 顯示5x7 點陣,8 位數據接口
  53.         write_com(0x0c);                 //設置開始顯示不顯示光標
  54.         write_com(0x06);                         //寫一個字符后地址指針加1
  55.         write_com(0x01);                         //顯示清零數據指針清零
  56.         write_com(0x80);                         //將數據指針第一行第一個字處,
  57.        
  58.         write_com(0x80+9);                         //定義當前指針位置
  59.         write_data('H');                                 //寫入
  60.         write_data(':');                                 //寫入
  61.         write_data('+');                                 //寫入
  62.         write_data('2');                                 //寫入
  63.         write_data('0');                                 //寫入
  64.         write_data(0xdf);                                 //寫入°
  65.         write_data('C');                                 //寫入C
  66.         write_com(0x80+9+0x40);                  //定義當前指針位置
  67.         write_data('L');                                 //寫入
  68.         write_data(':');                                 //寫入
  69.         write_data('+');                                 //寫入
  70.         write_data('1');                                 //寫入
  71.         write_data('0');                                 //寫入
  72.         write_data(0xdf);                                 //寫入°
  73.         write_data('C');                                 //寫入C
  74.         h=0x14;                  //h=+20
  75.         l=0+0x0a;                                                     //l=+10
  76.         D1=1;
  77.         D2=1;
  78.         figh=0;                                                         //給正確初始值,便于上電比較
  79.         figl=1;                                                         //給正確初始值,便于上電比較
  80. }
  81. void write_com(uchar com)                //寫命令程序
  82. {        lcdrs=0;                                         //設置為寫入命令
  83.         P0=com;                                         //將命令賦給P0 口
  84.         delay(5);                                         //延時
  85.         lcden=1;                                         //打開LCD使能,輸入一個高脈沖
  86.         delay(5);                                        //延時
  87.         lcden=0;                                         //置低完成高脈沖
  88. }
  89. void write_data(uchar date)                //寫數據程序
  90. {        lcdrs=1;                                         //設置為寫入數據
  91.         P0=date;                                         //將數據賦給P0 口
  92.         delay(5);                                         //延時
  93.         lcden=1;                                         //打開LCD使能,輸入一個高脈沖
  94.         delay(5);                                         //延時
  95.         lcden=0;                                         //置低完成高脈沖
  96. }

  97. void write_temp_value(uchar add,char date)         //讀取的溫度值在LCD上顯示程序
  98. {        uchar bai,shi,ge;
  99.         bai=date/100;
  100.         shi=date%100/10;                                 
  101.         ge=date%10;                                                 //分離出百,十,個位數
  102.         if((bai|shi)==0)                                 //如果百十都等于0
  103.         shi=0x70;                                                 //十賦值0x70,以便十位寫入空字符,write_data(0x30+shi),參考1602字符圖形碼
  104.         if(bai==0)
  105.         bai=0x70;
  106.         write_com(0x80+add);                     //設置當前光標位置,準備寫數據
  107.        
  108.         if(fig==0&&shi!=0x70)                         //如果溫度為負且十位不等于0(如果十位等于0,shi=0x70)
  109.         { write_data('-');                                 //在百位寫入負號
  110.           write_data(0x30+shi);                        //寫入十位數據
  111.         }
  112.         if(fig==0&&shi==0x70)                         //如果溫度為負且百十位都等于0
  113.         { write_data(0x30+0x70);                 //在百位寫入一個空字符
  114.           write_data('-');                                 //在十位寫入負號
  115.         }
  116.         if(fig==1)write_data(0x30+bai);  //溫度正,寫入百位數據
  117.         if(fig==1)write_data(0x30+shi);         //溫度正,寫入十位數據
  118.         write_data(0x30+ge);                         //寫入個位數據
  119.         write_data(0xdf);                                 //寫入°
  120.         write_data('C');                                 //寫入C
  121.        
  122. }
  123. void write_hl(uchar add,char date)         //設置的高低溫度值在LCD上顯示程序
  124. {        uchar bai,shi,ge;
  125.         bai=date/100;
  126.         shi=date%100/10;                                 
  127.         ge=date%10;                                                 //分離出百,十,個位數
  128.         write_com(0x80+add);                     //設置當前光標位置,準備寫數據
  129.        
  130.         if(t==1&&shi!=0)                             //如果溫度為負且十位不等于0(如果十位等于0,shi=0x70)            負數:百位第1種情況,寫-
  131.                 { write_data('-');}                         //在百位寫入負號
  132.         if(t==1&&shi==0)                             //如果溫度為負且百十位都等于0                                                    負數:百位第2種情況,寫空
  133.                 { write_data(0x30+0x70);         //在百位寫入一個空字符
  134.                     write_data('-');                         //在十位寫入負號                                                                            負數:十位第1種情況,寫-
  135.                 }
  136.         if(t==1&&shi!=0)                             //如果溫度為負且十不等于0                                                                負數:十位第2種情況,寫數                                               
  137.             {write_data(0x30+shi);}                 //在十位寫入數據
  138.         if(t==0&&bai==0&&shi!=0)                 //否則溫度為正,如果bai=0且shi!=0                                                  正數:百位第1種情況,寫+
  139.                 {write_data('+');}                         //在百位寫入+
  140.         if(t==0&&bai==0&&shi==0)                 //否則溫度為正,如果bai=0且shi=0                                                           正數:百位第2種情況,寫空
  141.                 {write_data(0x30+0x70);}         //在百位寫入一個空字符
  142.         if(t==0&&bai!=0)       
  143.                 {write_data(0x30+bai);}      //否則百位為正不等于0,寫入百位數                                                           正數:百位第3種情況,寫數
  144.         if(t==0&&bai==0&&shi==0&&ge!=0)         //如果百十等于0,個不等于0                                                                           正數:十位第1種情況,寫+
  145.                 {write_data('+');}                         //在十位寫入+
  146.         if(t==0&&bai==0&&shi==0&&ge==0)         //如果百十個都等于0
  147.             {write_data(' ');}                     //在十位寫入空字符                                                                                           正數:十位第2種情況,寫空
  148.         if(t==0&&shi!=0)       
  149.                 {write_data(0x30+shi);}             //在十位寫入數                                                                                                   正數:十位第3種情況,寫數                    
  150.         write_data(0x30+ge);                         //寫入個位數據
  151. }

  152. /***********ds18b20子程序*************************/

  153. /***********ds18b20延遲子函數(晶振12MHz )*******/

  154. void delay_18B20(unsigned int i)
  155. {
  156.         while(i--);
  157. }

  158. /**********ds18b20初始化函數**********************/

  159. void Init_DS18B20(void)
  160. {
  161.          unsigned char x=0;
  162.          DQ = 1;          //DQ復位
  163.          delay_18B20(8);  //稍做延時
  164.          DQ = 0;          //單片機將DQ拉低
  165.          delay_18B20(80); //精確延時 大于 480us
  166.          DQ = 1;          //拉高總線
  167.          delay_18B20(14);
  168.          x=DQ;            //稍做延時后 如果x=0則初始化成功 x=1則初始化失敗
  169.          delay_18B20(20);
  170. }

  171. /***********ds18b20讀一個字節**************/  

  172. unsigned char ReadOneChar(void)
  173. {
  174.         uchar i=0;
  175.         uchar dat = 0;
  176.         for (i=8;i>0;i--)
  177.          {
  178.                   DQ = 0; // 給脈沖信號
  179.                   dat>>=1;
  180.                   DQ = 1; // 給脈沖信號
  181.                   if(DQ)
  182.                   dat|=0x80;
  183.                   delay_18B20(4);
  184.          }
  185.         return(dat);
  186. }

  187. /*************ds18b20寫一個字節****************/  

  188. void WriteOneChar(uchar dat)
  189. {
  190.         unsigned char i=0;
  191.         for (i=8; i>0; i--)
  192.         {
  193.                   DQ = 0;
  194.                 DQ = dat&0x01;
  195.             delay_18B20(5);
  196.                 DQ = 1;
  197.             dat>>=1;
  198. }
  199. }

  200. /**************讀取ds18b20當前溫度************/

  201. void ReadTemp(void)
  202. {
  203.         unsigned char a=0;
  204.         unsigned char b=0;
  205.         unsigned char t=0;

  206.         Init_DS18B20();
  207.         WriteOneChar(0xCC);            // 跳過讀序號列號的操作
  208.         WriteOneChar(0x44);         // 啟動溫度轉換

  209.         delay_18B20(100);       // this message is very important

  210.         Init_DS18B20();
  211.         WriteOneChar(0xCC);         //跳過讀序號列號的操作
  212.         WriteOneChar(0xBE);         //讀取溫度寄存器等(共可讀9個寄存器) 前兩個就是溫度

  213.         delay_18B20(100);

  214.         a=ReadOneChar();            //讀取溫度值低位
  215.         b=ReadOneChar();                   //讀取溫度值高位
  216. //        a=0xff;                                        //測試無法讀取-16度的問題
  217. //        b=0xfe;
  218.         temp_value=b<<4;                  //temp_value=b左移動4位  ,                         轉換成10進制
  219.         temp_value+=(a&0xf0)>>4;  //temp_value=temp_value+((a&0xf0)>>4) 轉換成10進制
  220.         fig=0x01;                                  //設置fig=1溫度正
  221.         if(temp_value>0x7f)                  //如果temp_value大于0x7f,即為負數區,參考DS18B20datasheet
  222.         {fig=0;                                          //設置fig=0溫度負,以便判斷顯示
  223.          a=~a+1;                                  //將讀取的溫度轉換成10進制數
  224.          b=~b;
  225.          temp_value=b<<4;                  //temp_value=b左移動4位  ,                         轉換成10進制
  226.          temp_value+=(a&0xf0)>>4; //temp_value=temp_value+((a&0xf0)>>4) 轉換成10進制
  227.         }            
  228. }

  229. void keyscan()                                                 //按鍵掃描
  230. {        if(s1==0)                                                 //如果s1按下,執行下面程序
  231.         {   delay(5);                                         //        延時一會
  232.                 if(s1==0)                                         //如果s1確實按下,執行下面程序
  233.                 {        s1num++;                                 //s1num自加1
  234.                         while(!s1);                                 //如果s1松開,執行下面程序,否則一直停在這
  235.                         if(s1num==1)                         //如果s1只按一次,執行下面
  236.                         {
  237.                                 write_com(0x80+13);       //設置當前指針位置
  238.                                 write_com(0x0f);                  //寫入光標閃爍命令
  239.                         }
  240.                         if(s1num==2)                                  //如果s1按2次,執行下面
  241.                         {
  242.                                 write_com(0x80+0x40+13);  //設置當前指針位置,光標閃
  243.                         }
  244.                         if(s1num==3)                                  //如果s1按3次,執行下面
  245.                         {        s1num=0;                                  //s1num清0
  246.                                 write_com(0x0c);              //寫入光標不閃爍命令
  247.                         }
  248.                 }
  249.         }
  250.        
  251.         if(s2==0)                                                          //如果s2按下,執行下面程序
  252.         {        delay(5);                                                  //延時
  253.                 if(s2==0);                                                  //如果s2按下,執行下面程序
  254.                 {               
  255.                                 while(!s2);                                  //如果s2松開,執行下面程序,否則一直停在這
  256.                                 if(s1num==1)                          //如果光標在h的位置閃爍,執行下面程序
  257.                                 {        h++;                                  //h加1
  258.                                         if(h==127)                            //=127清0
  259.                                         h=0;                                  
  260.                                         figh=0;                                  //設置figh=0,符號為正
  261.                                         t=figh;                                  //賦值給t,以便液晶顯示
  262.                                         if(h<=-1)                          //如果h為負數
  263.                                         {figh=1;                          //設置figh=0
  264.                                          t=figh;                          //賦值給t,以便液晶顯示
  265.                                          h=abs(h);                          //h取絕對值
  266.                                          write_hl(11,h);          //h寫入LCD
  267.                                          h=0-h;                                  //把h變回原來的負數
  268.                                         }
  269.                                         else{write_hl(11,h);} //否則h寫入LCD
  270.                                         write_com(0x80+13);          //光標在溫度值位置閃爍
  271.                                 }
  272.                                 if(s1num==2)                          //如果光標在l的位置閃爍,執行下面程序
  273.                                 {        l++;                                  
  274.                                         if(l==127)                            
  275.                                         l=0;
  276.                                         figl=0;
  277.                                         t=figl;
  278.                                         if(l<=-1)
  279.                                         {figl=1;
  280.                                          t=figl;
  281.                                          l=abs(l);
  282.                                          write_hl(0x40+11,l);          
  283.                                          l=0-l;
  284.                                         }
  285.                                         else{write_hl(0x40+11,l);}          
  286.                                         write_com(0x80+0x40+13);       
  287.                                 }
  288.                 }
  289.         }
  290.         if(s3==0)                                                          //如果s3按下,執行下面程序
  291.         {        delay(5);                                                  //延時
  292.                 if(s3==0);
  293.                 {
  294.                                 while(!s3);                                  //s3松開后,執行下面程序
  295.                                 if(s1num==1)                          //如果光標在h的位置閃爍,執行下面程序
  296.                                 {        h--;                                  //h自減1
  297.                                         if(h==-55)                          //如果h=-55清0
  298.                                         h=0;
  299.                                         figh=0;                                  //設置figh=0,溫度值為正
  300.                                         t=figh;                                  //賦值給t,以便液晶顯示
  301.                                         if(h<=-1)                          //如果h溫度值為負數
  302.                                         {figh=1;                          //設置figh=1
  303.                                          t=figh;                          //賦值給t,以便液晶顯示
  304.                                          h=abs(h);                          //h取絕對值
  305.                                          write_hl(11,h);          //h寫入LCD
  306.                                          h=0-h;                                  //把h變回原來的負數
  307.                                         }
  308.                                         else{write_hl(11,h);} //否則h寫入LCD          
  309.                                         write_com(0x80+13);          //光標在溫度值位置閃爍
  310.                                 }                 
  311.                                 if(s1num==2)
  312.                                 {        l--;
  313.                                         if(l==-55)
  314.                                         h=0;
  315.                                         figl=0;
  316.                                         t=figl;
  317.                                         if(l<=-1)
  318.                                         {figl=1;
  319.                                          t=figl;
  320.                                          l=abs(l);
  321.                                          write_hl(0x40+11,l);          
  322.                                          l=0-l;
  323. ……………………

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

所有資料51hei提供下載:
數字溫度計+報警HENRY.rar (343.8 KB, 下載次數: 453)


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

使用道具 舉報

來自 2#
ID:574538 發表于 2019-11-23 11:23 | 只看該作者
為啥這個調試的時候,提示出現關鍵性錯誤呢?

可以了,原來這個仿真必須要用Proteus7.5這個版本才可以,其他版本都不行
回復

使用道具 舉報

來自 3#
ID:701702 發表于 2020-3-4 08:04 | 只看該作者
上面給的是lcd顯示,下面資料變成了數碼管,而且protues仿真圖一點都不一樣.
回復

使用道具 舉報

地板
ID:261715 發表于 2018-9-13 10:52 | 只看該作者
贊,清晰明了
回復

使用道具 舉報

5#
ID:399283 發表于 2018-9-17 22:42 來自手機 | 只看該作者
樓主你這個用stm32做要改程序嗎
回復

使用道具 舉報

6#
ID:303383 發表于 2018-9-17 23:38 | 只看該作者
提示: 作者被禁止或刪除 內容自動屏蔽
回復

使用道具 舉報

7#
ID:443403 發表于 2018-12-12 21:07 | 只看該作者
用c52改成c51ma?
回復

使用道具 舉報

8#
ID:401785 發表于 2019-1-14 18:24 | 只看該作者
大佬我想問一下你這個DS18B20_V1.3.c文件打不開,我該怎么做
回復

使用道具 舉報

9#
ID:401785 發表于 2019-1-14 18:32 | 只看該作者
請問文件溫度HENRY.c和DS18B20_V1.3.c怎么打開,我用AltiumDesigner打不開
回復

使用道具 舉報

10#
ID:401785 發表于 2019-1-14 18:37 | 只看該作者
樓主請問一下你有沒有ad制圖文件
回復

使用道具 舉報

11#
ID:522603 發表于 2019-4-29 14:11 | 只看該作者
贊,這篇文章很收益 謝謝UP主
回復

使用道具 舉報

12#
ID:489394 發表于 2019-10-31 14:52 | 只看該作者
好東西~感謝樓主~
回復

使用道具 舉報

13#
ID:576716 發表于 2019-11-8 17:51 | 只看該作者
請問樓主,圖中的PNP有沒有具體型號呢,還是其他型號的也可以?
回復

使用道具 舉報

14#
ID:650126 發表于 2019-11-26 21:10 來自手機 | 只看該作者
請問樓主,把DS18B20換成熱敏電阻,需要改哪些程序,謝謝
回復

使用道具 舉報

15#
ID:648563 發表于 2019-11-26 23:51 來自手機 | 只看該作者
樓主辛苦了,感謝分享
回復

使用道具 舉報

16#
ID:723469 發表于 2020-4-13 21:46 | 只看該作者
這個程序不動
回復

使用道具 舉報

17#
ID:723469 發表于 2020-4-13 21:48 | 只看該作者
這個程序不動
回復

使用道具 舉報

18#
ID:787934 發表于 2020-6-23 17:40 | 只看該作者
真是好厲害
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 午夜一区二区三区视频 | 成人精品啪啪欧美成 | 午夜免费福利影院 | 国产成人综合网 | 99视频在线免费观看 | 日韩一区二区视频 | 久久久久一区 | 欧美成年人视频在线观看 | 五月天激情综合网 | 美日韩视频 | 久久综合一区 | 干一干操一操 | 韩日免费视频 | 日本在线视频中文字幕 | 九九亚洲精品 | 日韩免费网站 | 羞羞的视频在线 | 91资源在线 | 久久久久久成人 | 久久久.com| av在线免费不卡 | 欧美成人精品欧美一级 | 日韩综合在线 | 国产激情一区二区三区 | 日韩成人精品一区 | 美女黄频 | 91免费电影 | 久久久www成人免费无遮挡大片 | 亚洲美女视频 | 亚洲精品区 | 国产 欧美 日韩 一区 | 一区二区影视 | 日日干夜夜操 | 亚洲欧美国产精品一区二区 | 亚洲精品日日夜夜 | 免费看片在线播放 | 午夜精品一区二区三区在线播放 | 丁香五月缴情综合网 | 无码一区二区三区视频 | 久久精品成人 | 国产在线观看一区二区三区 |