找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5067|回复: 8
打印 上一主题 下一主题
收起左侧

有温度湿度显示的单片机万年历

  [复制链接]
跳转到指定楼层
楼主
    这是一款有温度湿度显示的单片机万年历程序,程序来源于本坛,修改了一些原程序在KEIL4编译环境下的编译出出的警造,程序修改后用单片机开发板进行验证,功能正常。
这是修改完善后的程序:
单片机开发板完成的单片机试验_带温度湿度的多功能万年历.zip (2.72 MB, 下载次数: 130)

下面是试验时的照片:






单片机源码:
  1. #include <REGX52.H>                                          
  2. typedef  unsigned int u16;         
  3. typedef  unsigned char u8;
  4. sbit k2=P3^2;                                            //K1 K2 K3 K4按键接口,建议从左到右接K1-K4
  5. sbit k1=P3^5;
  6. sbit k3=P3^3;
  7. sbit k4=P3^4;
  8. sbit DQ=P3^7;
  9. sbit beep=P1^6;   
  10. sbit Data=P1^1;                                             //有源蜂鸣器在P16口
  11. sbit lcden=P0^5;                                                //LCD1602接口定义
  12. sbit lcdrs=P0^7;                                                   
  13. sbit lcdrw=P0^6;
  14. sbit bg=P1^7;                                                //背光变量接入LCD1602的K极,通过bg的高低电平就可控制自动熄灭与点亮
  15. u8 k,e,d,o=1,p=1,temp,nxflag=0,mbflag=0,tianmax;      
  16. float temperature;                                           //温度变量,18B20接收时为浮点数
  17. u8 miao1,miao2,fen1,fen2,shi1,shi2,tian1,tian2,wk,tem1,tem2,tem3,wendufu;
  18. u8 day=1,mon=1,day1,day2,yue1,yue2,mbw,n=0,m=0,beiguang,RH,RL,TH,TL,tempH,tempL;
  19. u8 se1,se2,mon1,mon2,hou1,hou2,min1,min2,MB2,nian1,nian2,nian3,nian4;
  20. u16 y,MB1;
  21. u16 temper,buchang,tempwarn=0,tempwarn1=500;                //tempwarn为温度下限,1为温度上限
  22. u8 code set[]={"NaoZhong  Status"};                                    //上电后傻瓜调节模块
  23. u8 code tempwarng[]={"Wendu Waring!"};
  24. u8 code temmin[]={"Min"};
  25. u8 code temmax[]={"Max"};               
  26. u8 code naozhongON[]={" ON"};
  27. u8 code naozhongOFF[]={"OFF"};
  28. u8 code setsucces[]={"Set Success!"};
  29. u8 code thanks[]={"Welcome to use !"};
  30. u8 code thanksu[]={"thanks for using"};
  31. u8 code make[]={"Designed by LY"};
  32. u8 code MB[]={"Stopwatch"};
  33. u8 code week1[]={"[MON]"};
  34. u8 code week2[]={"[TUE]"};
  35. u8 code week3[]={"[WED]"};
  36. u8 code week4[]={"[THU]"};
  37. u8 code week5[]={"[FRI]"};
  38. u8 code week6[]={"[SAT]"};
  39. u8 code week7[]={"[SUN]"};                        
  40. void delay(unsigned int z)                                   //定义延时函数
  41. {                                          
  42.   unsigned int x,y;                        
  43.   for(x=z;x>0;x--)
  44.   for(y=1;y>0;y--);
  45. }
  46. void DHT11_delay_us(u8 n)
  47. {
  48.     while(--n);
  49. }
  50. void DHT11_delay_ms(u16 z)               //定义DHT11延迟函数
  51. {
  52.    u16 i,j;
  53.    for(i=z;i>0;i--)
  54.       for(j=110;j>0;j--);
  55. }

  56.          void DHT11_start()
  57. {
  58.    Data=1;
  59.    DHT11_delay_us(2);
  60.    Data=0;
  61.    DHT11_delay_ms(20);   //延时18ms以上
  62.    Data=1;
  63.    DHT11_delay_us(30);
  64. }
  65. u8 DHT11_rec_byte()      //接收一个字节
  66. {
  67.   u8 i,dat=0;
  68.   for(i=0;i<8;i++)       //从高到低依次接收8位数据
  69.    {         
  70.       while(!Data);       //等待50us低电平过去
  71.       DHT11_delay_us(8);   //延时60us,如果还为高则数据为1,否则为0
  72.       dat<<=1;           //移位使正确接收8位数据,数据为0时直接移位
  73.       if(Data==1)        //数据为1时,使dat加1来接收数据1
  74.          dat+=1;
  75.       while(Data);       //等待数据线拉低   
  76.     }  
  77.     return dat;
  78. }
  79. void DHT11_receive()      //接收40位的数据
  80.         {
  81.     u8 R_H,R_L,T_H,T_L,revise;
  82.     DHT11_start();
  83.     if(Data==0)
  84.     {
  85.         while(Data==0);   //等待拉高     
  86.         DHT11_delay_us(40);      //拉高后延时80us
  87.         R_H=DHT11_rec_byte();    //接收湿度高八位  
  88.         R_L=DHT11_rec_byte();    //接收湿度低八位  
  89.         T_H=DHT11_rec_byte();    //接收温度高八位  
  90.         T_L=DHT11_rec_byte();    //接收温度低八位
  91.         revise=DHT11_rec_byte(); //接收校正位
  92.         DHT11_delay_us(25);      //结束
  93.         if((R_H+R_L+T_H+T_L)==revise)      //校正
  94.         {
  95.             RH=R_H;
  96.             RL=R_L;
  97.                         TH=T_H;
  98.                         TL=T_L;
  99.         }
  100.     }
  101.   }
  102. void beepon()                                                //PWM(如果你是无源蜂鸣器,这里写PWM函数)
  103. {                                                             //当前为有源蜂鸣器,有源蜂鸣器无需更改
  104.    beep=0;
  105.    delay(1200);
  106.    beep=1;     
  107. }         
  108. void write_nian();                                  //预定义
  109. void write_yue();
  110. void write_tian();
  111. void write_shi();
  112. void write_fen();
  113. void write_miao();
  114. void write_week();
  115. void zhuanhuan();
  116. void write_temp();
  117. void write_nz();
  118. void nzON();
  119. void write_setsuccess();
  120. void beiguangpd();

  121. void write_com(u8 com)                                    //LCD1602初始化程序,了解1602时序图后新手的话可以直接照搬使用                                    
  122. {
  123. lcdrs=0;
  124. P2=com;
  125. delay(5);
  126. lcden=1;
  127. delay(5);
  128. lcden=0;
  129. }
  130. void write_data(u8 date)
  131. {
  132. lcdrs=1;
  133. P2=date;
  134. delay(5);
  135. lcden=1;
  136. delay(5);
  137. lcden=0;
  138. }
  139. void init()
  140. {
  141. lcdrw=0;
  142. lcden=0;
  143. write_com(0x38);
  144. write_com(0x0c);
  145. write_com(0x06);
  146. write_com(0x01);
  147. write_com(0x80+0x10);  
  148. }
  149.         
  150. void TimerInit()                                                    //定时器0工作方式1 中断初始化,923位12M晶振在KEIL仿真后的计算结果
  151. {   
  152.     TMOD=0X01;
  153.         TH0=(65535-901)/256;        
  154.         TL0=(65535-901)%256;        
  155.         ET0=1;                                          //打开定时器0中断允许位
  156.         EA=1;                                         //打开总中断允许
  157.         TR0=1;                                                 //打开 定时器0,开始计时
  158. }
  159. Init_DS18B20(void)                                    //DS18B20初始化与时序图程序,仿真时温度问题改进这个初始化程序就解决了
  160.   {
  161.        DQ=1;
  162.        delay(70);
  163.        DQ=0;
  164.        delay(485);
  165.        DQ=1;
  166.        delay(50);
  167.            return(1);
  168.   }
  169. ReadOneChar(void)                                      //18B20读一个字节
  170.   {  
  171.     unsigned char i=0;
  172.     unsigned char dat=0;
  173.        for (i=8;i>0;i--)
  174.      {
  175.          DQ=1;
  176.          delay(1);
  177.          DQ=0;
  178.          dat>>=1;
  179.          DQ=1;
  180.          if(DQ)
  181.          dat|=0x80;
  182.          delay(4);
  183.        }
  184.     return(dat);
  185.    }  
  186. WriteOneChar(unsigned char dat)                     //18B20写一个字节
  187.    {
  188.          unsigned char i=0;
  189.          for(i=8;i>0;i--)
  190.         {
  191.              DQ=0;
  192.              DQ=dat&0x01;
  193.              delay(5);
  194.              DQ=1;
  195.              dat>>=1;
  196.         }
  197.           delay(4);
  198.             return(1);
  199.     }
  200. ReadTemperature(void)                           //读取温度函数定义,返回值为浮点数
  201.    {
  202.         Init_DS18B20();
  203.         WriteOneChar(0xcc);
  204.         WriteOneChar(0x44);
  205.         delay(125);
  206.         Init_DS18B20();
  207.         WriteOneChar(0xcc);
  208.         WriteOneChar(0xbe);
  209.         tempL=ReadOneChar();
  210.         tempH=ReadOneChar();
  211.             if(tempH>0x7f)
  212.                 {
  213.                 tempH=~tempH;
  214.                 tempL=~tempL+1;
  215.                 wendufu=1;
  216.                 }
  217.                 else
  218.                 wendufu=0;
  219.                 temperature=(((tempH*256)+tempL)*0.0625)*10;
  220.         delay(200);
  221.         return(temperature);
  222.     }
  223. void welcome()                                       //定义欢迎函数
  224. { static u8 i;
  225.   init();                                              //初始化1602
  226.   delay(5000);
  227.   for(i=0;i<16;i++)
  228.   {
  229.   write_com(0x80+i);
  230.   write_data(thanks[i]);
  231.   delay(4000);
  232.   }
  233.   delay(50000);
  234.   for(i=0;i<14;i++)
  235.   {
  236.   write_com(0x81+0x40+i);
  237.   write_data(make[i]);
  238.   delay(4000);
  239.   }
  240.   delay(50000);
  241.   delay(50000);
  242. }

  243. void pdtian1()                          //PD在上电后设置完毕主界面处的天数判断
  244. {
  245. if((p==1||p==3)||(p==5||p==7)||(p==8||p==10)||p==12)        
  246.                 tianmax=31;
  247.           if((p==4||p==6)||(p==9||p==11))
  248.            tianmax=30;

  249.           if(p==2)
  250.           {
  251.             if(((y%4==0)&&(y%100!=0))||(y%400==0))
  252.                   tianmax=29;
  253.                 else
  254.                   tianmax=28;
  255.           }
  256. }
  257. void pdxingqi1()                     //PD在上电后设置完毕至主界面处的星期判断
  258. {
  259.   static char c,yi,mt,xwk1,xwk2,xwk3;
  260.   static int xwk,yn,xwk4;
  261.   yn=y;
  262.   if(p==1||p==2)
  263.           { yn=yn-1;
  264.             mt=p+12;
  265.          }
  266.           else
  267.       mt=p;
  268.    yi=yn%100;
  269.    c=yn/100;
  270.   xwk1=yi+(yi/4);
  271.   xwk2=c/4;
  272.   xwk3=2*c;
  273.   xwk4=(26*mt+26)/10;
  274.   xwk=xwk1+xwk2-xwk3+xwk4+o-1;
  275.   while(xwk<0)
  276.   {xwk+=7; }
  277.   wk=xwk%7;
  278. }
  279. void Display()                                //定义主程序 显示部分函数模块
  280. {           static u16 xunhuan;
  281.      RH=RH%100;
  282.      write_nian();                          //1602写入显示年
  283.      write_com(0x84);
  284.      write_data('-');                              
  285.      write_yue();                        //写入月
  286.             write_com(0x87);
  287.      write_data('-');
  288.             write_com(0x88);
  289.      write_tian();                         //写入天
  290.      write_week();
  291.      write_shi();
  292.          write_com(0x82+0x40);
  293.      write_data(':');
  294.      write_fen();
  295.          write_com(0x85+0x40);
  296.      write_data(':');
  297.          write_miao();                           //写入温度,温度TEM1与2与3是温度的三位数                                                         
  298.          xunhuan++;
  299.          if(xunhuan<180)
  300.         {if(wendufu==1)
  301.          {        
  302.          if((temper/100)!=0)
  303.          {
  304.          write_com(0x89+0x40);
  305.          write_data('-');
  306.          write_com(0x8a+0x40);
  307.          write_data(tem1);   
  308.          }
  309.          else
  310.          {
  311.          write_com(0x89+0x40);
  312.          write_data(' ');  
  313.          write_com(0x8a+0x40);
  314.          write_data('-');  
  315.          }
  316.          }

  317.          else
  318.          {
  319.          write_com(0x89+0x40);
  320.          write_data(' ');
  321.          
  322.          if((temper/100)!=0)  
  323.          {
  324.          write_com(0x8a+0x40);
  325.          write_data(tem1);
  326.          }
  327.          else
  328.          {
  329.          write_com(0x8a+0x40);
  330.          write_data(' ');
  331.          } }
  332.          write_com(0x8b+0x40);
  333.          write_data(tem2);
  334.          write_com(0x8c+0x40);
  335.          write_data('.');
  336.          write_com(0x8d+0x40);
  337.          write_data(tem3);
  338.          write_com(0x8e+0x40);
  339.          write_data(0xdf);
  340.          write_com(0x8f+0x40);
  341.          write_data('C');
  342.          }
  343.          if(xunhuan>180)
  344.          {
  345.          write_com(0x89+0x40);
  346.          write_data(' ');
  347.          write_com(0x8a+0x40);
  348.          write_data(' ');
  349.          write_com(0x8b+0x40);
  350.          write_data(RH/10+0x30);
  351.          write_com(0x8c+0x40);
  352.          write_data(RH%10+0x30);
  353.          write_com(0x8d+0x40);
  354.          write_data('%');
  355.          write_com(0x8e+0x40);
  356.           write_data('R');
  357.           write_com(0x8f+0x40);
  358.          write_data('H');
  359.          }
  360.          if(xunhuan==360)
  361.          xunhuan=0;         
  362. }
  363. void NZdisplay()                                    //定义闹钟模块
  364. {
  365.    static u8 nzflag=2,nzwei;                        
  366.    delay(2000);
  367.    init();
  368.    delay(2000);
  369.    nzON();                                         //闹钟开关选择模块
  370.    while(k4)                                     //没有检测到K4键退出时无限循环
  371.     {  
  372. ...........................................................................................................................................
  373. 由于程序较长,需要的可以自己下载。
复制代码



带温度补偿超声波测距:http://www.51hei.com/bbs/dpj-89712-1.html

单片机DHT11温度湿度程序:http://www.51hei.com/bbs/dpj-89543-1.html



评分

参与人数 2黑币 +105 收起 理由
liuchang9117 + 5
admin + 100 共享资料的黑币奖励!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏6 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:218373 发表于 2017-7-9 22:54 | 只看该作者
说的见解到位,不错
回复

使用道具 举报

板凳
ID:34643 发表于 2017-10-12 07:35 | 只看该作者
liuchang9117 发表于 2017-7-9 22:54
说的见解到位,不错

谢谢你的鼓励,我会继续努力。
回复

使用道具 举报

地板
ID:848824 发表于 2021-1-28 15:05 | 只看该作者
请问断电保存数据吗
回复

使用道具 举报

5#
ID:848824 发表于 2021-1-28 19:51 | 只看该作者
有原理图就好了
回复

使用道具 举报

6#
ID:848824 发表于 2021-1-29 21:57 | 只看该作者
屏幕接线图给个就好了
回复

使用道具 举报

7#
ID:972742 发表于 2021-12-2 17:00 来自手机 | 只看该作者
有仿真就好啦
回复

使用道具 举报

8#
ID:977804 发表于 2021-12-4 20:12 来自手机 | 只看该作者
清翔v2.0同款
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表