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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機溫度控制報警和時間顯示程序+Proteus仿真

[復制鏈接]
跳轉到指定樓層
樓主
本系統由AT89C51單片機、DS18B20溫度檢測部分、DS1302日期時間記錄部分、數碼管顯示部分、按鍵輸入部分和蜂鳴器報警部分組成。該系統通過按鍵一來調整模式,共五個模式。模式一是DS18B20采集環境溫度并保存在存儲器中通過單片機將溫度顯示在數碼管上,當溫度低于下限或高于上限時蜂鳴器報警;模式二是利用按鍵二和按鍵三調整報警的最高溫度加減;模式三是利用按鍵二和按鍵三調整報警的最低溫度加減;模式四是DS1302記錄的日期通過單片機顯示在數碼管上;模式五是DS1302記錄的時間通過單片機顯示在數碼管上。

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


單片機源程序如下:
  1. #include <reg52.h>
  2. #include"intrins.h"
  3. #define uchar unsigned char
  4. #define uint  unsigned int
  5. sbit dula  = P2^0;        //數碼管引腳定義
  6. sbit wela = P2^1;

  7. sbit DQ = P2^2;         //

  8. sbit key1 = P2^5;
  9. sbit key2 = P2^6;
  10. sbit key3 = P2^7;

  11. sbit buzz = P2^3;
  12. sbit led = P3^7;

  13. sbit RST=P1^0;                        
  14. sbit DSIO=P1^1;                        
  15. sbit SCLK=P1^2;                         //定義ds1302使用的IO口

  16. int bai,shi,ge;
  17. uchar fuhao,flag;
  18. uint ff,Hff=50,Lff=10;

  19. uchar count=0,t100ms=0,t500ms,t1s,t2s;
  20. uchar cishu=0;
  21. uchar jiange=0;
  22. uchar biaozhi1=0;  //由低于下限到高于下限標志
  23. uchar biaozhi2=0;  //有高于上限到低于上限標志
  24. uchar biaozhi3=0;  //2s長鳴標志
  25. uchar biaozhi4=0;

  26. uchar TIMEBCD[7] = {0x00, 0x00, 0x12, 0x1, 0x01, 0x01, 0x18};
  27. //存儲順序是秒分時日月周年,存儲格式是用BCD碼
  28. uchar TIME[7] = {0}; //十進制時間
  29. //DS1302時鐘初始化2018年1月1日星期一12點00分00秒。

  30. uchar code READ_RTC_ADDR[7] = {0x81, 0x83, 0x85, 0x87, 0x89, 0x8b, 0x8d};
  31. uchar code WRITE_RTC_ADDR[7] = {0x80, 0x82, 0x84, 0x86, 0x88, 0x8a, 0x8c};
  32. //DS1302寫入和讀取時分秒的地址命令(最低位控制讀寫)

  33. unsigned char code table[]={
  34. 0x3f,0x06,0x5b,0x4f,
  35. 0x66,0x6d,0x7d,0x07,
  36. 0x7f, 0x6f};
  37. unsigned char code table1[]={
  38. 0xbf,0x86,0xdb,0xcf,
  39. 0xe6,0xed,0xfd,0x87,
  40. 0xff, 0xef};
  41. unsigned char code tablefu[]={
  42. 0x40, 0x76 , 0x38 , 0x39
  43. };                        //數碼管符號 - H L C
  44. /*延時函數*/
  45. void delayms(uint xms)
  46. {
  47.         uint i,j;
  48.         for(i=xms;i>0;i--)
  49.         for(j=114;j>0;j--);
  50. }
  51. /*****溫度延時*****/
  52. void Delaywendu(int num)
  53. {
  54.         while(num--) ;
  55. }
  56. /*****初始化DS18B20*****/
  57. void Init_DS18B20()
  58. {
  59.         DQ = 1;         //DQ復位
  60.         Delaywendu(8);    //稍做延時
  61.         DQ = 0;         //單片機將DQ拉低
  62.         Delaywendu(80);   //精確延時,大于480us
  63.         DQ = 1;         //拉高總線
  64.         Delaywendu(40);
  65. }
  66. /*****讀一個字節*****/
  67. uchar ReadOneChar()
  68. {
  69.         uchar i=0;
  70.         uchar dat = 0;
  71.         for (i=8;i>0;i--)
  72.         {
  73.                 DQ = 0;     // 給脈沖信號
  74.                 dat>>=1;
  75.                 DQ = 1;     // 給脈沖信號
  76.                 if(DQ)
  77.                 dat|=0x80;
  78.                 Delaywendu(4);
  79.         }
  80.         return(dat);
  81. }
  82. /*****寫一個字節*****/
  83. void WriteOneChar(uchar dat)
  84. {
  85.         uchar i=0;
  86.         for (i=8; i>0; i--)
  87.         {
  88.                 DQ = 0;
  89.                 DQ = dat&0x01;
  90.                 Delaywendu(5);
  91.                 DQ = 1;
  92.                 dat>>=1;
  93.         }
  94. }
  95. /*****讀取溫度*****/
  96. uint ReadTemperature()
  97. {
  98.   uint a=0,b=0;
  99.   int temp=0;
  100.   float tt=0;
  101.   Init_DS18B20();
  102.   WriteOneChar(0xCC);  //跳過讀序號列號的操作  1100 1100
  103.   WriteOneChar(0x44);  //啟動溫度轉換     0100 0100
  104.   Init_DS18B20();
  105.   WriteOneChar(0xCC);  //跳過讀序號列號的操作
  106.   WriteOneChar(0xBE);  //讀取溫度寄存器  1011 1110
  107.   a=ReadOneChar();     //讀低8位
  108.   b=ReadOneChar();    //讀高8位
  109.   temp=b;
  110.   temp<<=8;
  111.   temp=temp|a;
  112.   if(temp&0xf800)
  113.   {
  114.         temp=~temp+1;
  115.         fuhao=1;
  116.   }
  117.   else
  118.   fuhao=0;
  119.   tt=temp*0.0625;
  120.   temp=tt*10+0.5;     //放大10倍輸出并四舍五入
  121.   return(temp);
  122. }

  123. /*****讀取溫度*****/
  124. void check_wendu()
  125. {
  126.         uint f;
  127.         f=ReadTemperature();                          //獲取溫度值并減去DS18B20的溫漂誤差
  128.         ff=f;
  129.         bai=f/100;
  130.     shi=f %100/10;
  131.         ge= f%10;                                       
  132. }
  133. /****讀設定值*****/
  134. void check_v_set(int v_set)
  135. {
  136.         int bb;
  137.         bb=v_set*10;   
  138.         bai=bb/100;
  139.     shi=bb %100/10;
  140.         ge= bb %10;                                                               
  141. }
  142. /*****顯示溫度子程序*****/
  143. void display()
  144. {     

  145.         P0=0xff;
  146.         wela=1;
  147.         P0=0xfb;
  148.         wela=0;
  149.         dula=1;
  150.         P0=table[bai];
  151.         dula=0;
  152.         delayms(5);

  153.         P0=0xff;
  154.         wela=1;
  155.         P0=0xf7;
  156.         wela=0;
  157.         dula=1;
  158.         P0=table1[shi];
  159.         dula=0;
  160.         delayms(5);
  161.         
  162.         P0=0xff;
  163.         wela=1;
  164.         P0=0xef;
  165.         wela=0;
  166.         dula=1;
  167.         P0=table[ge];
  168.         dula=0;
  169.         delayms(5);
  170.                
  171.         P0=0xff;
  172.         wela=1;
  173.         P0=0xdf;
  174.         wela=0;
  175.         dula=1;
  176.         P0=tablefu[3];
  177.         dula=0;
  178.         delayms(5);
  179. }
  180. void keyscan()
  181. {
  182.         if(key1==0)
  183.         {
  184.                 delayms(5);
  185.                 if(key1==0)
  186.                 {
  187.                         flag++;
  188.                         if(flag==5)
  189.                                 flag=0;
  190.                         while(!key1);
  191.                 }
  192.         }
  193. }
  194. int keyad(int num)
  195. {
  196.         if(flag!=0)
  197.         {
  198.                 if(key2==0)
  199.                 {
  200.                         delayms(5);
  201.                         if(key2==0)
  202.                         {
  203.                                 num++;
  204.                                 while(!key2);
  205.                         }
  206.                 }
  207.                 if(key3==0)
  208.                 {
  209.                         delayms(5);
  210.                         if(key3==0)
  211.                         {
  212.                                 num--;
  213.                                 while(!key3);
  214.                         }
  215.                 }        
  216.         }
  217.         return num;
  218. }
  219. /**************************************************************/
  220. /**************************日歷計時部分************************/
  221. void Ds1302Write(uchar addr, uchar dat) //向DS1302發送命令(地址+數據)
  222. {
  223.         uchar n;
  224.         RST = 0;
  225.         _nop_();
  226.         SCLK = 0;//先將SCLK置低電平。
  227.         _nop_();
  228.         RST = 1; //然后將RST(CE)置高電平。
  229.         _nop_();

  230.         for (n=0; n<8; n++)//開始傳送八位地址命令
  231.         {
  232.                 DSIO = addr & 0x01;//數據從低位開始傳送
  233.                 addr >>= 1;
  234.                 SCLK = 1;//數據在上升沿時,DS1302讀取數據
  235.                 _nop_();
  236.                 SCLK = 0;
  237.                 _nop_();
  238.         }
  239.         for (n=0; n<8; n++)//寫入8位數據
  240.         {
  241.                 DSIO = dat & 0x01;
  242.                 dat >>= 1;
  243.                 SCLK = 1;//數據在上升沿時,DS1302讀取數據
  244.                 _nop_();
  245.                 SCLK = 0;
  246.                 _nop_();        
  247.         }        
  248.                  
  249.         RST = 0;//傳送數據結束
  250.         _nop_();
  251. }

  252. uchar Ds1302Read(uchar addr) //讀取一個地址的數據
  253. {
  254.         uchar n,dat,dat1;
  255.         RST = 0;
  256.         _nop_();

  257.         SCLK = 0;//先將SCLK置低電平。
  258.         _nop_();
  259.         RST = 1;//然后將RST(CE)置高電平。
  260.         _nop_();

  261.         for(n=0; n<8; n++)//開始傳送八位地址命令
  262.         {
  263.                 DSIO = addr & 0x01;//數據從低位開始傳送
  264.                 addr >>= 1;
  265.                 SCLK = 1;//數據在上升沿時,DS1302讀取數據
  266.                 _nop_();
  267.                 SCLK = 0;//DS1302下降沿時,放置數據
  268.                 _nop_();
  269.         }
  270.         _nop_();
  271.         for(n=0; n<8; n++)//讀取8位數據
  272.         {
  273.                 dat1 = DSIO;//從最低位開始接收
  274.                 dat = (dat>>1) | (dat1<<7);
  275.                 SCLK = 1;
  276.                 _nop_();
  277.                 SCLK = 0;//DS1302下降沿時,放置數據
  278.                 _nop_();
  279.         }

  280.         RST = 0;
  281.         _nop_();        //以下為DS1302復位的穩定時間
  282.         SCLK = 1;
  283.         _nop_();
  284.         DSIO = 0;
  285.         _nop_();
  286.         DSIO = 1;
  287.         _nop_();
  288.         return dat;        
  289. }

  290. void Ds1302ReadTime()  //讀取時鐘信息
  291. {
  292.         uchar n;
  293.         for (n=0; n<7; n++)//讀取7個字節的時鐘信號:分秒時日月周年
  294.         {
  295.                 TIMEBCD[n] = Ds1302Read(READ_RTC_ADDR[n]);
  296.                 TIME[n] = TIMEBCD[n]/16*10+TIMEBCD[n]%16;
  297.         }
  298. }

  299. void Ds1302Init() // 初始化DS1302
  300. {        
  301.         uchar n;
  302.         Ds1302ReadTime();                           //首次讀取時間
  303.         if(TIME[5]==0)                                   //判斷時間值是否有效
  304.         {
  305.                 Ds1302Write(0x8E,0X00);                 //禁止寫保護,就是關閉寫保護功能
  306.                 for (n=0; n<7; n++)//寫入7個字節的時鐘信號:分秒時日月周年
  307.                 {
  308.                         Ds1302Write(WRITE_RTC_ADDR[n],TIMEBCD[n]);        
  309.                 }
  310.                 Ds1302Write(0x8E,0x80);                 //打開寫保護功能
  311.         }
  312. }
  313. void displaytime()
  314. {     

  315.         P0=0xff;
  316.         wela=1;
  317.         P0=0xfe;
  318.         wela=0;
  319.         dula=1;
  320.         P0=table[TIME[2]/10];
  321.         dula=0;
  322.         delayms(5);

  323.         P0=0xff;
  324.         wela=1;
  325.         P0=0xfd;
  326.         wela=0;
  327.         dula=1;
  328.         P0=table1[TIME[2]%10];
  329.         dula=0;
  330.         delayms(5);
  331.         
  332.         P0=0xff;
  333.         wela=1;
  334.         P0=0xfb;
  335.         wela=0;
  336.         dula=1;
  337.         P0=table[TIME[1]/10];
  338.         dula=0;
  339.         delayms(5);
  340.                
  341.         P0=0xff;
  342.         wela=1;
  343.         P0=0xf7;
  344.         wela=0;
  345.         dula=1;
  346.         P0=table1[TIME[1]%10];
  347.         dula=0;
  348.         delayms(5);

  349.         P0=0xff;
  350.         wela=1;
  351.         P0=0xef;
  352.         wela=0;
  353.         dula=1;
  354.         P0=table[TIME[0]/10];
  355.         dula=0;
  356.         delayms(5);

  357.         P0=0xff;
  358.         wela=1;
  359.         P0=0xdf;
  360.         wela=0;
  361.         dula=1;
  362.         P0=table1[TIME[0]%10];
  363.         dula=0;
  364.         delayms(5);
  365. }
  366. void displaydate()
  367. {     

  368.         P0=0xff;
  369.         wela=1;
  370.         P0=0xfe;
  371.         wela=0;
  372.         dula=1;
  373.         P0=table[TIME[6]/10];
  374.         dula=0;
  375.         delayms(5);

  376.         P0=0xff;
  377.         wela=1;
  378.         P0=0xfd;
  379.         wela=0;
  380.         dula=1;
  381.         P0=table1[TIME[6]%10];
  382.         dula=0;
  383.         delayms(5);
  384.         
  385.         P0=0xff;
  386.         wela=1;
  387.         P0=0xfb;
  388.         wela=0;
  389.         dula=1;
  390.         P0=table[TIME[4]/10];
  391.         dula=0;
  392.         delayms(5);
  393.                
  394.         P0=0xff;
  395.         wela=1;
  396.         P0=0xf7;
  397.         wela=0;
  398.         dula=1;
  399.         P0=table1[TIME[4]%10];
  400.         dula=0;
  401.         delayms(5);

  402.         P0=0xff;
  403.         wela=1;
  404.         P0=0xef;
  405.         wela=0;
  406.         dula=1;
  407.         P0=table[TIME[3]/10];
  408.         dula=0;
  409.         delayms(5);

  410.         P0=0xff;
  411.         wela=1;
  412.         P0=0xdf;
  413.         wela=0;
  414.         dula=1;
  415.         P0=table1[TIME[3]%10];
  416.         dula=0;
  417.         delayms(5);
  418. }
  419. /*主函數*/
  420. void main()
  421. {
  422.         
  423.         int z;
  424.         buzz=1;         //低電平響,
  425.         led=0;
  426.         TMOD=0x01;//設置定時器0工作模式1
  427.         TH0=(65536-50000)/256;//定時器裝初值
  428.         TL0=(65536-50000)%256;
  429.         EA=1; //開總中斷
  430.         ET0=1; //開定時器0中斷

  431.         Ds1302Init( );
  432.         for(z=0;z<100;z++)
  433.         {
  434.         check_wendu();
  435.         }               
  436.         TR0=1;
  437.         while(1)
  438.         {
  439.                 keyscan();
  440.                 if(flag==0)
  441.                 {
  442.                         check_wendu();
  443.                         if(fuhao==1)                                //當溫度值為負數
  444.                           {
  445.                                 P0=0xff;
  446.                                 wela=1;
  447.                                 P0=0xfd;
  448.                                 wela=0;
  449.                                 dula=1;
  450.                                 P0=tablefu[0];
  451.                                 dula=0;
  452.                                 delayms(5);                //顯示負
  453.                           }
  454.                          else
  455.                           {                        
  456.                                   P0=0xff;
  457.                                 wela=1;
  458.                                 P0=0xfd;
  459.                                 wela=0;
  460.                                 dula=1;
  461.                                 P0=0x00;
  462.                                 dula=0;
  463.                                 delayms(5);                        //顯示正
  464.                         }
  465.                         display();
  466.                 }
  467.                 else if(flag==1)
  468.                 {
  469.                         Hff=keyad(Hff);
  470.                         check_v_set(Hff);
  471.                         
  472.                         P0=0xff;
  473.                         wela=1;
  474.                         P0=0xfe;
  475.                         wela=0;
  476.                         dula=1;
  477.                         P0=tablefu[1];
  478.                         dula=0;
  479.                         delayms(5);                //顯示H

  480.                         display();        
  481.                 }
  482.                 else if(flag==2)
  483.                 {
  484.                          Lff=keyad(Lff);
  485.                         check_v_set(Lff);

  486.                         P0=0xff;
  487.                         wela=1;
  488.                         P0=0xfe;
  489.                         wela=0;
  490.                         dula=1;
  491.                         P0=tablefu[2];
  492.                         dula=0;
  493.                         delayms(5);                //顯示L

  494.                         display();
  495.                 }
  496.                 else if(flag==3)
  497.                 {
  498.                         Ds1302ReadTime();
  499.                     delayms(10);
  500.                         displaydate();
  501.                 }
  502.                 else if(flag==4)
  503.                 {
  504.                         Ds1302ReadTime();
  505.                     delayms(10);
  506.                         displaytime();
  507.                         
  508.                 }
  509.         }
  510. }
  511. /*中斷函數*/
  512. void timer0() interrupt 1//定時器0中斷服務程序
  513. {
  514.         TH0=(65536-50000)/256;//再次裝定時器初值
  515.         TL0=(65536-50000)%256;
  516.         count++; //中斷次數累加         //50毫秒
  517. //        ff=ReadTemperature();
  518.         if(count%2==0)
  519.         {        
  520.                 t100ms = 1;                        
  521.         }
  522.         if(count%10==0)
  523.         {        
  524.                 t500ms = 1;                        
  525.         }
  526.         if(count%20==0)
  527.         {        
  528. ……………………

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

所有資料51hei提供下載:
test1.zip (156.81 KB, 下載次數: 173)

評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:496609 發表于 2019-11-7 15:41 來自手機 | 只看該作者
感謝      
回復

使用道具 舉報

板凳
ID:649621 發表于 2019-11-26 09:04 | 只看該作者
感謝!
回復

使用道具 舉報

地板
ID:649921 發表于 2019-12-3 15:21 | 只看該作者
。。。。我怎么打不開 仿真圖片???
回復

使用道具 舉報

5#
ID:651767 發表于 2019-12-4 12:33 | 只看該作者
為啥程序導進去后 仿真數碼管會不亮 端口也是灰色 連著數碼管的兩個 端口也是灰色的
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日韩毛片免费视频 | 久久丝袜视频 | 成人精品免费 | 亚洲欧美一区二区三区在线 | 国产黄色一级电影 | 亚洲精品福利在线 | 91热在线 | 国产精品久久久久久久久久 | wwww.xxxx免费 | 午夜一区二区三区视频 | 国产在线播| 婷婷福利视频导航 | 一区二区三区中文字幕 | 四虎免费视频 | 亚洲国产精品视频一区 | 欧美日韩精品一区二区天天拍 | 亚洲啊v在线 | 欧美一区二区三区久久精品 | 一区二区三区四区视频 | 操久久| 日韩成人精品视频 | 成人毛片在线视频 | 成人午夜免费福利视频 | 黄色91在线 | 国产一级视频在线 | 久久久久久综合 | 久久99精品久久久 | 国产精品久久久久无码av | 精品国产一区二区在线 | av黄色在线 | 日韩av免费在线电影 | www.狠狠干| 精品亚洲永久免费精品 | 久久久69| 97人人草 | 美日韩中文字幕 | 国产一级免费视频 | 开操网 | 成人伊人| 欧美成人一区二区 | 亚洲精品久久久久久一区二区 |