找回密码
 立即注册

QQ登录

只需一步,快速开始

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

基于单片机多功能电子钟 课程设计报告书下载

[复制链接]
跳转到指定楼层
楼主
一、 设计任务及要求:
  (1)    1602液晶上显示年、月、日、时、分、秒,并且按秒实时更新显示。
  (2)    1602液晶上显示当前采集到的环境温度。
  (3)    当环境温度低于0℃和高于34℃时,蜂鸣器报警。
  (4)    每次开机时,蜂鸣器响。
  (5)    能够使用板上的按键调节各参数,按键可设计4个有效键,分别为切换键、加键、减键、跳出键。
  (6)    利用 DS1302时钟芯片通过简单的串行通信与单片机进行通信,时钟/日历电路能够实时提供年、月、日、时、分、秒信息,采用双电源供电,当外部电源掉电时能够利用后备电池准确计时的特性,设计实现断电时间不停、再次上电时时间仍然准确显示在液晶上的功能。



  1. /***************************************************************************************************************
  2.                            基于DS18B20、DS1302、单片机的时钟与温度测控

  3. ***************************************************************************************************************/
  4. #include <REG52.H>
  5. #include "LCD1602.H"
  6. #include "DS18B20.H"
  7. #include "DS1302.H"

  8. #define uint unsigned int
  9. #define uchar unsigned char
  10. #define TH 35              //设置温度上限

  11. extern unsigned char week_value[2],TempBuffer[5];          //声明外部变量
  12. extern int temp_value;
  13. char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year;  //秒,分,时到日,月,年位闪的计数
  14. sbit Set  = P3^0;       //模式切换键
  15. sbit Up   = P3^1;        //加法按钮
  16. sbit Down = P3^2;      //减法按钮
  17. sbit out  = P3^3;       //立刻跳出调整模式按钮
  18. sbit deng = P1^1;
  19. char done,count,temp,flag,up_flag,down_flag;
  20. char  SD=1;
  21. void show_time();   //液晶显示函数声明

  22. /**************************************************************
  23. 延时子程序
  24. **************************************************************/
  25. void mdelay(uint delay)
  26. {        uint i;
  27.         for(;delay>0;delay--)
  28.                    {for(i=0;i<62;i++) //1ms延时.
  29.                        {;}
  30.                    }
  31. }
  32. /**************************************************************
  33. 升序按键
  34. **************************************************************/
  35. void Upkey()
  36. {          
  37.                 Up=1;
  38.                 if(Up==0)
  39.                           {
  40.                                    mdelay(8);
  41.                                        switch(count)
  42.                                           {case 1:
  43.                                   temp=Read1302(DS1302_SECOND);  //读取秒数
  44.                                                                   temp=temp+1;  //秒数加1
  45.                                   up_flag=1;    //数据调整后更新标志
  46.                                                                   if((temp&0x7f)>0x59)   //超过59秒,清零
  47.                                   temp=0;                                                                  
  48.                                                                   break;
  49.                                            case 2:
  50.                                   temp=Read1302(DS1302_MINUTE);  //读取分数
  51.                                                                   temp=temp+1;  //分数加1
  52.                                   up_flag=1;
  53.                                                                   if(temp>0x59)          //超过59分,清零
  54.                                                                   temp=0;
  55.                                                                   break;
  56.                                            case 3:
  57.                                   temp=Read1302(DS1302_HOUR);  //读取小时数
  58.                                                                   temp=temp+1;  //小时数加1
  59.                                   up_flag=1;
  60.                                                                   if(temp>0x23)   //超过23小时,清零
  61.                                                                   temp=0;
  62.                                                                   break;
  63.                                            /*case 4:
  64.                                   temp=Read1302(DS1302_WEEK);  //读取星期数
  65.                                                                   temp=temp+1;  //星期数加1
  66.                                   up_flag=1;
  67.                                                                   if(temp>0x7)  
  68.                                                                   temp=1;
  69.                                                                   break; */
  70.                                            case 5:
  71.                                   temp=Read1302(DS1302_DAY);  //读取日数
  72.                                                                   temp=temp+1;  //日数加1
  73.                                   up_flag=1;
  74.                                                                   if(temp>0x31)
  75.                                                                   temp=1;
  76.                                                                   break;
  77.                                            case 6:
  78.                                   temp=Read1302(DS1302_MONTH);  //读取月数
  79.                                                                   temp=temp+1;  //月数加1
  80.                                   up_flag=1;
  81.                                                                   if(temp>0x12)
  82.                                                                   temp=1;
  83.                                                                   break;
  84.                                            case 7:
  85.                                   temp=Read1302(DS1302_YEAR);  //读取年数
  86.                                                                   temp=temp+1;  //年数加1
  87.                                   up_flag=1;
  88.                                                                   if(temp>0x85)
  89.                                                                   temp=0;
  90.                                                                   break;
  91.                                                default:break;
  92.                                           }
  93.                                           
  94.                                    while(Up==0);
  95.                    
  96.                                   }
  97. }

  98. /**************************************************************
  99. 降序按键
  100. **************************************************************/
  101. void Downkey()
  102. {            
  103.                 Down=1;
  104.             if(Down==0)
  105.                           {
  106.                                    mdelay(8);
  107.                                      switch(count)
  108.                                           {case 1:
  109.                                   temp=Read1302(DS1302_SECOND);  //读取秒数
  110.                                                                   temp=temp-1;                                                    //秒数减1
  111.                                   down_flag=1;       //数据调整后更新标志
  112.                                                                   if(temp==0x7f)     //小于0秒,返回59秒
  113.                                                                   temp=0x59;
  114.                                                                   break;
  115.                                            case 2:
  116.                                   temp=Read1302(DS1302_MINUTE);  //读取分数
  117.                                                                   temp=temp-1;  //分数减1
  118.                                   down_flag=1;
  119.                                                                   if(temp==-1)
  120.                                                                   temp=0x59;      //小于0分,返回59分
  121.                                                                   break;
  122.                                            case 3:
  123.                                   temp=Read1302(DS1302_HOUR);  //读取小时数
  124.                                                                   temp=temp-1;  //小时数减1
  125.                                   down_flag=1;
  126.                                                                   if(temp==-1)
  127.                                                                   temp=0x23;
  128.                                                                   break;
  129.                                            /*case 4:
  130.                                   temp=Read1302(DS1302_WEEK);  //读取星期数
  131.                                                                   temp=temp-1;  //星期数减1
  132.                                   down_flag=1;
  133.                                                                   if(temp==0)
  134.                                                                   temp=0x7;;
  135.                                                                   break;                        */
  136.                                            case 5:
  137.                                   temp=Read1302(DS1302_DAY);  //读取日数
  138.                                                                   temp=temp-1;  //日数减1
  139.                                   down_flag=1;
  140.                                                                   if(temp==0)
  141.                                                                   temp=31;
  142.                                                                   break;
  143.                                            case 6:
  144.                                   temp=Read1302(DS1302_MONTH);  //读取月数
  145.                                                                   temp=temp-1;  //月数减1
  146.                                   down_flag=1;
  147.                                                                   if(temp==0)
  148.                                                                   temp=12;
  149.                                                                   break;
  150.                                            case 7:
  151.                                   temp=Read1302(DS1302_YEAR);  //读取年数
  152.                                                                   temp=temp-1;  //年数减1
  153.                                   down_flag=1;
  154.                                                                   if(temp==-1)
  155.                                                                   temp=0x85;
  156.                                                                   break;
  157.                                               default:break;
  158.                                          }
  159.                                          
  160.                                    while(Down==0);
  161.                                   
  162.                                   }
  163. }
  164. /**************************************************************
  165. 模式选择按键
  166. **************************************************************/
  167. void Setkey()
  168. {
  169.                 Set=1;
  170.                 if(Set==0)
  171.             {
  172.            mdelay(8);
  173.            count=count+1;         //Setkey按一次,count就加1
  174.                    done=1;                         //进入调整模式
  175.            while(Set==0);
  176.            
  177.                  }

  178. }
  179. /**************************************************************
  180. 跳出调整模式,返回默认显示
  181. **************************************************************/
  182. void outkey()                    
  183. { uchar Second;
  184.   out=1;
  185.   if(out==0)         
  186.   {  
  187.         count=0;
  188.         hide_sec=0,hide_min=0,hide_hour=0,hide_day=0,hide_week=0,hide_month=0,hide_year=0;
  189.         Second=Read1302(DS1302_SECOND);
  190.     Write1302(0x8e,0x00);          //写入允许
  191.         Write1302(0x80,Second&0x7f);
  192.         Write1302(0x8E,0x80);          //禁止写入
  193.         done=0;           
  194.         while(out==0);
  195.   }
  196. }
  197. /**************************************************************
  198. 按键功能执行
  199. **************************************************************/
  200. void keydone()
  201. {        uchar Second;
  202.                  if(flag==0)    //关闭时钟,停止计时
  203.          { Write1302(0x8e,0x00); //写入允许
  204.            temp=Read1302(0x80);
  205.            Write1302(0x80,temp|0x80);
  206.                Write1302(0x8e,0x80); //禁止写入
  207.            flag=1;
  208.          }
  209.          Setkey();                                            //扫描模式切换按键
  210.                  switch(count)
  211.                  {case 1:do                                                //count=1,调整秒
  212.                           {
  213.                    outkey();                           //扫描跳出按钮
  214.                                    Upkey();                //扫描加按钮
  215.                                    Downkey();              //扫描减按钮
  216.                                    if(up_flag==1||down_flag==1)  //数据更新,重新写入新的数据
  217.                                    {
  218.                                    Write1302(0x8e,0x00); //写入允许
  219.                                    Write1302(0x80,temp|0x80); //写入新的秒数
  220.                                    Write1302(0x8e,0x80); //禁止写入
  221.                                    up_flag=0;
  222.                                    down_flag=0;
  223.                                    }

  224.                                    hide_sec++;          //位闪计数
  225.                                    if(hide_sec>3)
  226.                                      hide_sec=0;
  227.                    show_time();         //液晶显示数据
  228.                                   }while(count==2);break;  
  229.                   case 2:do                                                //count=2,调整分
  230.                           {
  231.                                    hide_sec=0;
  232.                                    outkey();
  233.                                    Upkey();
  234.                                    Downkey();
  235.                                    if(temp>0x60)
  236.                                      temp=0;
  237.                                    if(up_flag==1||down_flag==1)
  238.                                    {
  239.                                    Write1302(0x8e,0x00); //写入允许
  240.                                    Write1302(0x82,temp); //写入新的分数
  241.                                    Write1302(0x8e,0x80); //禁止写入
  242.                                    up_flag=0;
  243.                                    down_flag=0;
  244.                                    }
  245.                                    hide_min++;
  246.                                    if(hide_min>3)
  247.                                      hide_min=0;
  248.                    show_time();
  249.                                   }while(count==3);break;
  250.                   case 3:do                                                //count=3,调整小时
  251.                           {
  252.                    hide_min=0;
  253.                                    outkey();
  254.                                    Upkey();
  255.                                    Downkey();
  256.                                    if(up_flag==1||down_flag==1)
  257.                                    {
  258.                                    Write1302(0x8e,0x00); //写入允许
  259.                                    Write1302(0x84,temp); //写入新的小时数
  260.                                    Write1302(0x8e,0x80); //禁止写入
  261.                                    up_flag=0;
  262.                                    down_flag=0;
  263.                                    }
  264.                                    hide_hour++;
  265.                                    if(hide_hour>3)
  266.                                      hide_hour=0;
  267.                    show_time();
  268.                                   }while(count==4);break;
  269.                 /*  case 4:do                                                //count=4,调整星期
  270.                           {
  271.                    hide_hour=0;
  272.                                    outkey();
  273.                                    Upkey();
  274.                                    Downkey();
  275.                                    if(up_flag==1||down_flag==1)
  276.                                    {
  277.                                    Write1302(0x8e,0x00); //写入允许
  278.                                    Write1302(0x8a,temp); //写入新的星期数
  279.                                    Write1302(0x8e,0x80); //禁止写入
  280.                                    up_flag=0;
  281.                                    down_flag=0;
  282.                                    }
  283.                                    hide_week++;
  284.                                    if(hide_week>3)
  285.                                      hide_week=0;
  286.                    show_time();
  287.                                   }while(count==5);break;          */
  288.                   case 5:do                                                //count=5,调整日
  289.                           {
  290.                                    hide_week=0;
  291.                                    outkey();
  292.                                    Upkey();
  293.                                    Downkey();
  294.                                    if(up_flag==1||down_flag==1)
  295.                                    {
  296.                                    Write1302(0x8e,0x00); //写入允许
  297.                                    Write1302(0x86,temp); //写入新的日数
  298.                                    Write1302(0x8e,0x80); //禁止写入
  299.                                    up_flag=0;
  300.                                    down_flag=0;
  301.                                    }
  302.                                    hide_day++;
  303.                                    if(hide_day>3)
  304.                                      hide_day=0;
  305.                    show_time();
  306.                                   }while(count==6);break;
  307.                   case 6:do                                                //count=6,调整月
  308.                           {
  309.                    hide_day=0;
  310.                                    outkey();
  311.                                    Upkey();
  312.                                    Downkey();
  313.                                    if(up_flag==1||down_flag==1)
  314.                                    {
  315.                                    Write1302(0x8e,0x00); //写入允许
  316.                                    Write1302(0x88,temp); //写入新的月数
  317.                                    Write1302(0x8e,0x80); //禁止写入
  318.                                    up_flag=0;
  319.                                    down_flag=0;
  320.                                    }
  321.                                    hide_month++;
  322.                                    if(hide_month>3)
  323.                                      hide_month=0;
  324.                    show_time();
  325.                                   }while(count==7);break;
  326.                   case 7:do                                                //count=7,调整年
  327.                           {
  328.                    hide_month=0;
  329.                                    outkey();
  330.                                    Upkey();
  331.                                    Downkey();
  332.                                    if(up_flag==1||down_flag==1)
  333.                                    {
  334.                                    Write1302(0x8e,0x00); //写入允许
  335.                                    Write1302(0x8c,temp); //写入新的年数
  336.                                    Write1302(0x8e,0x80); //禁止写入
  337.                                    up_flag=0;
  338.                                    down_flag=0;
  339.                                    }
  340.                                    hide_year++;
  341.                                    if(hide_year>3)
  342.                                      hide_year=0;
  343.                    show_time();
  344.                                   }while(count==8);break;
  345.                   case 8: count=0;hide_year=0;  //count8, 跳出调整模式,返回默认显示状态
  346.                       Second=Read1302(DS1302_SECOND);
  347.                   Write1302(0x8e,0x00); //写入允许
  348.                       Write1302(0x80,Second&0x7f);
  349.                       Write1302(0x8E,0x80);          //禁止写入
  350.                                   done=0;
  351.                   break; //count=7,开启中断,标志位置0并退出
  352.                   default:break;

  353.                  }

  354. }
  355. /**************************************************************
  356. 液晶显示程序
  357. **************************************************************/
  358. void show_time()   
  359. {
  360.   DS1302_GetTime(&CurrentTime);  //获取时钟芯片的时间数据
  361.   TimeToStr(&CurrentTime);       //时间数据转换液晶字符
  362.   DateToStr(&CurrentTime);       //日期数据转换液晶字符
  363.   ReadTemp();                    //开启温度采集程序
  364.   temp_to_str();                 //温度数据转换成液晶字符
  365.   GotoXY(12,1);                  //液晶字符显示位置
  366.   Print(TempBuffer);             //显示温度
  367.   GotoXY(0,1);
  368.   Print(CurrentTime.TimeString); //显示时间
  369.   GotoXY(0,0);
  370.   Print(CurrentTime.DateString); //显示日期
  371.   GotoXY(15,0);
  372.   /*Print(week_value);             //显示星期
  373.   GotoXY(11,0);
  374.   Print("Week");        //在液晶上显示 字母 week        */
  375.   mdelay(500);                 //扫描延时         
  376. }
  377. /**************************************************************
  378. 报警检测与取消
  379. **************************************************************/
  380. void warming()
  381. {
  382.   if(temp_value>=TH)
  383.      {if(SD==1&&SD!=0)ET0=1;}
  384. else {deng=0;ET0=0;SD=1;}
  385. out=1;
  386. if(out==0){ET0=0;SD=0;}
  387. }
  388. /**************************************************************
  389. 主程序
  390. **************************************************************/
  391. main()
  392. {       
  393.     TMOD=0x02;              //设置模式为定时器T0的模式2 (8位自动重装计数初值的计数值)        
  394.     TH0=0x03;               //设置计数器初值,靠TH0存储重装的计数值
  395.     TL0=0x03;
  396.     TR0=1;                  //启动T0
  397.     ET0=0;                  //关定时器T0中断
  398.         EA=1;

  399.     P1=0;
  400.     flag=1;           //时钟停止标志
  401.         LCD_Initial();    //液晶初始化
  402.         Init_DS18B20( ) ;      //DS18B20初始化
  403.         Initial_DS1302(); //时钟芯片初始化
  404.         up_flag=0;                  //调整标志位置零
  405.         down_flag=0;         
  406.         done=0;           //进入默认液晶显示

  407.         while(1)
  408.         {   
  409.         while(done==1)
  410.           {keydone();         //进入调整模式
  411.                    warming();
  412.                    }   
  413.                 while(done==0)
  414.             {  
  415.             show_time();                //液晶显示数据
  416.             flag=0;                  
  417.                       Setkey();                                 //扫描各功能键
  418.                         warming();                               
  419.                 }
  420.            warming();
  421.         }
  422. }
  423. /**************************************************************
  424. 定时器中断
  425. **************************************************************/
  426. void t0 (void) interrupt 1 using 1
  427. {deng=!deng;}
复制代码






多功能电子钟课程设计.rar

487.29 KB, 下载次数: 46, 下载积分: 黑币 -5

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

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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