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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

51單片機5110液晶顯示屏實現時間溫度串口發送(附Proteus仿真程序)

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


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

單片機源程序如下:
  1. /**
  2. P2.7置低電平時,開機接入串口,自動進入時間設置界面
  3. 每秒鐘自動檢測溫度一次,并在LCD上顯示
  4. 每分鐘自動刷新日期、時間、溫度,在LCD上顯示,并在串口中輸出(方便電腦讀取)

  5. */


  6. #include <stdio.h>
  7. //#include <AT89X51.H>
  8. #include<reg51.h>
  9. #include"ds1302.h"
  10. #include"temp.h"
  11. #include <nokia_5110.h>


  12. //***********************************
  13. #define                delay_time        25767

  14. sbit SETTIME = P2^7;        //為0時,開機進入設置時間界面
  15. uchar TIME[7];
  16. char word2[10];

  17. //毫秒級延時函數
  18. void delay(unsigned int x)
  19. {
  20.         unsigned char i;
  21.         while(x--)
  22.         {
  23.                 for(i = 0;i < 120;i++);
  24.         }
  25. }

  26. char* tempDisplay(int temp)          //lcd顯示
  27. {
  28.    
  29.          unsigned char datas[5]; //定義數組
  30.         float tp;
  31.         unsigned char ReturnTemp[9],x;  
  32.         if(temp< 0)                                //當溫度值為負數
  33.           {

  34.                 ReturnTemp[0]='-';
  35.                 //因為讀取的溫度是實際溫度的補碼,所以減1,再取反求出原碼
  36.                 temp=temp-1;
  37.                 temp=~temp;
  38.                 tp=temp;
  39.                 temp=tp*0.0625*100+0.5;        
  40.                 //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
  41.                 //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
  42.                 //算由?.5,還是在小數點后面。

  43.           }
  44.          else
  45.           {                        
  46. //                  LcdWriteCom(0x80);                //寫地址 80表示初始地址
  47. //            LcdWriteData('+');                 //顯示正
  48.                 ReturnTemp[0]='+';
  49.                 tp=temp;//因為數據處理有小數點所以將溫度賦給一個浮點型變量
  50.                 //如果溫度是正的那么,那么正數的原碼就是補碼它本身
  51.                 temp=tp*0.0625*100+0.5;        
  52.                 //留兩個小數點就*100,+0.5是四舍五入,因為C語言浮點數轉換為整型的時候把小數點
  53.                 //后面的數自動去掉,不管是否大于0.5,而+0.5之后大于0.5的就是進1了,小于0.5的就
  54.                 //算加上0.5,還是在小數點后面。
  55.         }
  56.         datas[0] = temp / 10000;
  57.         datas[1] = temp % 10000 / 1000;
  58.         datas[2] = temp % 1000 / 100;
  59.         datas[3] = temp % 100 / 10;
  60.         datas[4] = temp % 10;           

  61. //        LcdWriteCom(0x82);                  //寫地址 80表示初始地址
  62. //        LcdWriteData('0'+datas[0]); //百位
  63. //        ReturnTemp[1]=datas[0]+48;
  64.         if(datas[0]!=0)
  65.         {
  66.         ReturnTemp[1]=48+datas[0];
  67.         x=1;
  68.         } else {
  69.         x=0;
  70.         }
  71.         //putchar(ReturnTemp[1]);
  72. //        LcdWriteCom(0x83);                 //寫地址 80表示初始地址
  73. //        LcdWriteData('0'+datas[1]); //十位
  74.         if(( datas[1])!=0)
  75.         {
  76.         ReturnTemp[1+x]=datas[1]+48;
  77.         x=x+1;
  78.         } else {
  79.                 if(x!=0)
  80.                 {
  81.                         ReturnTemp[1+x]='0';
  82.                         x=x+1;
  83.                 }
  84.         }        

  85. //        LcdWriteCom(0x84);                //寫地址 80表示初始地址
  86. //        LcdWriteData('0'+datas[2]); //個位
  87.         ReturnTemp[1+x]='0'+datas[2];
  88. //        putchar(ReturnTemp[1+x]);
  89. //        LcdWriteCom(0x85);                //寫地址 80表示初始地址
  90. //        LcdWriteData('.');                 //顯示 ‘.’
  91.         ReturnTemp[2+x]='.';

  92. //        LcdWriteCom(0x86);                 //寫地址 80表示初始地址
  93. //        LcdWriteData('0'+datas[3]); //顯示小數點
  94.         ReturnTemp[3+x]=48+datas[3];
  95. //        putchar(ReturnTemp[3+x]);
  96. //        LcdWriteCom(0x87);                 //寫地址 80表示初始地址
  97. //        LcdWriteData('0'+datas[4]); //顯示小數點
  98.         ReturnTemp[4+x]=datas[4]+48;
  99.         ReturnTemp[5+x]='C';
  100.         ReturnTemp[6+x]='\0';
  101. //        printf("\n xx %s\n",ReturnTemp);
  102.         return ReturnTemp;

  103. }


  104. //設置日期,格式為: setdate 2015-2-21, 可以省略0
  105. int setdate()
  106. {
  107.         char year[5],month[3],day[3],i,
  108.                  y,m,d;                                                                   //y存放年,m存放月, d存放日
  109.         for(i=0;i<4;i++)        
  110.                  year[i]=word2[i];
  111.                
  112.         for(i=0; i<10; i++)                                                //檢查WORD2中字符的合法性,只能有數字或者-
  113.         {
  114.                 if((word2[i]-48)<0 | word2[i]-48>9)
  115.                 {
  116.                         if(word2[i] == '\0')
  117.                                 break;
  118.                         if(word2[i] != '-')
  119.                         {
  120.                                 return 0;
  121.                         }
  122.                 }
  123.         }        

  124.         if(word2[7]!='-' & word2[6] != '-')
  125.         {
  126.                 return 0;
  127.         }

  128.         if(word2[7] == '-')
  129.         {
  130.                 month[0]=word2[5];
  131.                 month[1]=word2[6];
  132.                 m = 1;         //m=1的話,表示月份是2位,否則是1位,節約內存,借變量用一下
  133.         }

  134.         if(word2[6] == '-')
  135.         {
  136.                 month[0] = '0';
  137.                 month[1] = word2[5];
  138.                 m = 0;
  139.         }

  140.         if(word2[9+m]!='\0' & word2[8+m] != '\0')
  141.         {
  142.                 return 0;
  143.         }

  144.         if(word2[9+m] == '\0')                        //處理日期,因為要考慮1位的情況,使情況復雜多了
  145.         {
  146.                 day[0] = word2[7+m];
  147.                 day[1] = word2[8+m];
  148.         }

  149.         if(word2[8+m]=='\0')
  150.         {
  151.                 day[0] = '0';
  152.                 day[1] = word2[7+m];
  153.         }

  154.         year[4]='\0',month[2]='\0',day[2]='\0';
  155.         y = (year[2]-48)*10 + (year[3]-48);
  156.         m = (month[0]-48)*10 + (month[1]-48);
  157.         d = (day[0]-48)*10 + day[1]-48;                 //先獲取年月日的值,再判斷合法性

  158.         if(year[0] != (2+48) | year[1] != (0+48) |        //這個簡單,必須是20XX年
  159.         y > 100 | y < 1 | m > 12 | m <1)                //年與月都簡單,日最麻煩
  160.         {
  161.                 return 0;
  162.         }

  163.         if(!(m==1|m==3|m==5|m==7|m==8|m==10|m==12) & (d>=31)) //除了大月外都不能有31號
  164.         {
  165.                 return 0;
  166.         }

  167.         if(d>31)
  168.         {
  169.                 return 0;
  170.         }

  171.         if(m==2 & d>28)
  172.         {
  173.                 if(!(((y%4)==0) & (d==29)))        //2月是很蛋痛的,好在只是100年內
  174.                 {
  175.                         return 0;
  176.                 }
  177.         }

  178.         TIME[6]=(year[2]-48)*16+(year[3]-48);
  179.         TIME[4]=(month[0]-48)*16+(month[1]-48);
  180.         TIME[3]=(day[0]-48)*16+(day[1]-48);

  181.         
  182.         //下面這段把設置的日期寫入到DS1302中
  183.         Ds1302Write(0x8E,0X00);                 //禁止寫保護,就是關閉寫保護功能
  184.         for (i=0; i<7; i++)//寫入7個字節的時鐘信號:分秒時日月周年
  185.         {
  186.                 Ds1302Write(WRITE_RTC_ADDR[i],TIME[i]);        
  187.         }
  188.         Ds1302Write(0x8E,0x80);                 //打開寫保護功能
  189. /*
  190.         putstring(year);
  191.         putstring(month);
  192.         putstring(day);
  193.         putstring("\r\n");
  194. */
  195.         Ds1302ReadTime();
  196.         return 1;
  197. }

  198. //設置時間,格式為settimer 02:22, 不支持省略0
  199. int settime()
  200. {
  201.         char minutes[3],hour[3],i,
  202.                  h,m;                                                                   //h存放小時,m存放分
  203.                                                    
  204.         for(i=0; i<6; i++)                                                //檢查WORD2中字符的合法性,只能有數字或者:
  205.         {
  206.                 if((word2[i]-48)<0 | word2[i]-48>9)
  207.                 {
  208.                         if(word2[i] == '\0')
  209.                                 break;
  210.                         if(word2[i] != ':')
  211.                         {
  212.                                 return 0;
  213.                         }
  214.                 }
  215.         }        
  216.         


  217.         if(word2[2]!=':' & word2[1] != ':')
  218.         {
  219.                 return 0;
  220.         }

  221.         if(word2[2] == ':')
  222.         {
  223.                 hour[0]=word2[0];
  224.                 hour[1]=word2[1];
  225.                 m = 1;         //m=1的話,表示小時是2位,=0是1位
  226.         }

  227.         if(word2[1] == ':')
  228.         {
  229.                 hour[0] = '0';
  230.                 hour[1] = word2[0];
  231.                 m = 0;
  232.         }

  233.         if(word2[4+m]!='\0' & word2[3+m] != '\0')
  234.         {
  235.                 return 0;
  236.         }

  237.         if(word2[4+m] == '\0')                        //要考慮小時1位的情況
  238.         {
  239.                 minutes[0] = word2[2+m];
  240.                 minutes[1] = word2[3+m];
  241.         }

  242.         if(word2[3+m]=='\0')
  243.         {
  244.                 minutes[0] = '0';
  245.                 minutes[1] = word2[2+m];
  246.         }


  247.         minutes[2]='\0',hour[2]='\0';
  248.         h = (hour[0]-48)*10 + (hour[1]-48);
  249.         m = (minutes[0]-48)*10 + (minutes[1]-48);


  250.         if(h > 23 | h <= 0 | m > 59 | m < 0)                //這個比日期簡單多了
  251.         {
  252.                 return 0;
  253.         }


  254.         Ds1302ReadTime();
  255.         TIME[2]=(hour[0]-48)*16+(hour[1]-48);                 //BCD碼
  256.         TIME[1]=(minutes[0]-48)*16+(minutes[1]-48);
  257.         TIME[0]=0;
  258.         Ds1302Write(0x8E,0X00);                 //禁止寫保護,就是關閉寫保護功能
  259.         for (i=0; i<7; i++)//寫入7個字節的時鐘信號:分秒時日月周年
  260.         {
  261.                 Ds1302Write(WRITE_RTC_ADDR[i],TIME[i]);        
  262.         }
  263.         Ds1302Write(0x8E,0x80);                 //打開寫保護功能
  264.         Ds1302ReadTime();
  265. //        printf("\nThe current time: ");
  266.         return 1;
  267. }        

  268. void main()
  269. {
  270.         char         Secondcheck,           //檢查秒有沒有改變
  271.                           Mincheck,                    //檢查分有沒有改變
  272.                         date[11];                           

  273.         SCON = 0x50; //串口方式1,允許接收
  274.         TMOD = 0x20; //定時器1定時方式2
  275.         TCON = 0x40; //設定時器1開始計數
  276.         TH1 = 0xFD;        //11.0592MHz 1200波特率 只有9600能用未找原因
  277.         TL1 = 0xFD;
  278.         TI = 1;
  279.         TR1 = 1; //啟動定時器
  280.         printf ("Initing.... \n");
  281.         tempDisplay(Ds18b20ReadTemp());
  282.         LCD_init(); //初始化液晶   
  283.         LCD_clear();
  284.         LCD_write_english_string(0,1," Initing.... ");
  285.         delay(1000);  
  286.         Mincheck=11;        //解決分鐘為0時初始化過久的問題
  287.         if(SETTIME==0)
  288.         {
  289.                 for(Mincheck=3;Mincheck>0;Mincheck--)
  290.                 {
  291.                         printf("\nPlease Set Date:");
  292.                         scanf("%s",word2);
  293.                         //printf("%s",word2);
  294.                         if(setdate())
  295.                                 break;
  296.                 }
  297.                 for(Mincheck=3;Mincheck>0;Mincheck--)
  298.                 {
  299.                         printf("\nPlease Set Time:");
  300.                         scanf("%s",word2);
  301.                         //printf("%s\n",word2);
  302.                         if(settime())
  303.                                 break;
  304.                 }
  305.         }
  306.         LCD_clear();//清除LCD
  307.         while(1)
  308.                 {
  309.                         Ds1302ReadTime();//讀取時間1302
  310.                                                 
  311.                 delay(500);//多給點時間發送,但是影響秒的同步看來要改定時器發送        
  312.                         
  313.                         
  314.                                        
  315.                         if(Mincheck!=TIME[0])////如果時間秒變化就發送一次串口數據               
  316.                         
  317.                         {
  318.                                 
  319.                                 Mincheck=TIME[0];//讓Mincheck等于秒,用于下次發送檢測
  320.                                 
  321.                                 date[0]='2',//發送年
  322.                                 date[1]='0',
  323.                                 date[2]=TIME[6]/16+48,//發送年
  324.                                 date[3]=TIME[6]%16+48;
  325.                                 date[4]='-',
  326.                                 date[5]=(TIME[4]/16+48),//發送月
  327.                                 date[6]=(TIME[4]%16+48),
  328.                                 date[7]='-',
  329.                                 date[8]=(TIME[3]/16+48),//發送日
  330.                                 date[9]=TIME[3]%16+48;               
  331.                                 printf("%s",date);//發送以上全部的 date               
  332.                                 
  333.                                 printf("  Time: ");
  334.                                 putchar(TIME[2]/16+48);//發送時
  335.                                 putchar(TIME[2]%16+48);
  336.                                 putchar(':');//發送“ :”
  337.                                 putchar(TIME[1]/16+48);//發送分
  338.                                 putchar(TIME[1]%16+48);
  339.                                 putchar(':');//發送“ :”
  340.                                 putchar(TIME[0]/16+48);//發送秒
  341.                                 putchar(TIME[0]%16+48);

  342.                                 printf("  WD: ");
  343.                                 printf(tempDisplay(Ds18b20ReadTemp()));
  344.                                 putchar('\n');//結束串口開始符號
  345.                                 
  346.                                 
  347.         LCD_write_english_string(25,1," bbjj  ");
  348.                                 LCD_write_english_string(8,0,date);
  349.                                 LCD_write_chinese_string(0,3,12,1,TIME[2]/16,5);//顯示時
  350.                                 LCD_write_chinese_string(10,3,12,1,TIME[2]%16,5);
  351.                                 LCD_write_chinese_string(20,3,12,1,11,5);
  352.                                 LCD_write_chinese_string(30,3,12,1,TIME[1]/16,5);//顯示分
  353.                                 LCD_write_chinese_string(40,3,12,1,TIME[1]%16,5);
  354.                                 LCD_write_chinese_string(50,3,12,1,11,5);
  355.                                 LCD_write_chinese_string(60,3,12,1,TIME[0]/16,5);//顯示秒
  356.                                 LCD_write_chinese_string(70,3,12,1,TIME[0]%16,5);
  357.                                 
  358.                                          
  359.                         }
  360.                         
  361.                           
  362.                         if(Secondcheck!=TIME[0])//如果溫度變化就顯示一下
  363.                         {
  364.                                 Secondcheck=TIME[0];
  365.                                 LCD_write_english_string(10,5,"WD:");
  366.                                 LCD_write_english_string(30,5,tempDisplay(Ds18b20ReadTemp()));//讀取溫度顯示18B20
  367.                         }
  368.                         
  369.                 }                                                                                                        

  370. }
復制代碼

所有資料51hei提供下載:
51單片機&amp;5110液晶顯示屏實現時間溫度串口發送(附仿真截圖).7z (544.03 KB, 下載次數: 60)

評分

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

查看全部評分

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

使用道具 舉報

沙發
ID:853104 發表于 2020-12-22 23:36 | 只看該作者
大佬有LCD1602的程序和仿真嗎
回復

使用道具 舉報

板凳
ID:832201 發表于 2020-12-23 22:33 | 只看該作者
很棒,寫的真棒
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 日本在线视 | 亚洲国产精品久久久久秋霞不卡 | 天天操精品视频 | 一区二区在线不卡 | 精品国产网 | 亚洲人在线播放 | 秋霞电影一区二区 | 亚洲精品aⅴ | 成人av电影在线 | 国产综合精品一区二区三区 | 国产精品a久久久久 | 国产激情免费视频 | 亚州成人| 国产精品九九 | 天天天操操操 | 国产精品亚洲一区二区三区在线 | 免费成人在线网站 | 精品久久久久久久久久久久久久 | 91激情视频 | 日本在线视频一区二区 | 中文福利视频 | 久久精品视频在线观看 | 一二三四av | 久久精品成人 | 久草.com| 中文在线一区二区 | 久草中文在线观看 | 日韩无 | 999精品在线 | 性生活毛片 | 亚洲国产成人精品在线 | 日本小电影在线 | 国产精品欧美一区二区 | 小h片免费观看久久久久 | 欧美日韩1区2区3区 欧美久久一区 | 在线一级片 | av一级在线观看 | 国产成人亚洲精品自产在线 | 午夜视频在线免费观看 | 精品国产乱码久久久久久丨区2区 | 中文字幕亚洲精品 |