找回密码
 立即注册

QQ登录

只需一步,快速开始

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

单片机万年历(含闹钟)思路分析及main.c内容(只给出main.c内容)

[复制链接]
跳转到指定楼层
楼主
/*************************************************************************************
*                   实验:万年历(DS1302、LCD1602、AT24C04的综合应用)
* 步骤及现象:程序下载前,stc-isp选择IRC频率:12MHz,程序下载后,LCD1602显示时间‘第一
*     行:“12:00:00     2”,第二行:"2019.01.01     0" ’。第一行最右侧的2是周二
*     (有效范围2000~2100年);第二行最右侧0是关闭闹钟,若是1,则开启闹钟,若是2,则
*     第一行显示闹钟时间,而不是时钟时间。闹钟开关及闹钟时间显示的位选键是按键5。
*   (1)若设置时分秒(按键1是位选,按键2是加,按键3是减)。按按键1,小时的那两位每0.5s
*      闪烁一次,表示可以对时的值按按键2一次加1或按按键3一次减1;再按按键1,分钟的那两
*      位每0.5s闪烁一次,表示可以对分的值进行加或减;再按按键1,秒的那两位每0.5s闪烁一
*      次,表示可以对秒进行加或减。再按按键1或按按键0,退出设置模式。
*   (2)若设置年月日(按键0是位选,按键2是加,按键3是减)。按按键0,年的前两位每0.5s闪烁
*      一次,表示可以对年前两位的值进行加或减;再按按键0,年的后两位每0.5s闪烁一次,表示
*      可以对年后两位的值进行加或减;再按按键0,月的两位每0.5s闪烁一次,表示可以对月的
*      值进行加或减;再按按键0,日的两位每0.5s闪烁一次,表示可以对日的值进行加或减。再
*      按按键0或按按键1,退出设置模式。
*   (3)若设置闹钟(按键4是位选键,按键2是加,按键3是减)。现象和(1)一样。(若开启闹钟
*      后,到达闹钟时间,闹钟鸣叫,而无人去关闭闹钟,则闹钟从响应时间开始,鸣叫5s后,自
*      动关闭,下次时间到达后仍会提醒。)闹钟初始化时间"12:01:00"
*************************************************************************************/
  1. #include <stc8.h>
  2. #include "ds1302.h"
  3. #include "display.h"
  4. #include "key.h"
  5. #include "settime.h"
  6. #include "timer0.h"
  7. #include "1602.h"
  8. #include "i2c.h"
  9. #include "delay.h"

  10. sbit speaker = P1^3;             // 蜂鸣器
  11. char TIMED[7];                   // 用于接收ds1302中的数据,转化为有符号类型,便于界限判定
  12. unsigned char alarm[3]={0,1,12}; // 存放闹钟时间(12:01:00闹钟初始化时间)
  13. unsigned int num2=0;             // 用于无人关闹钟时,计数,当达到5s后,把闹钟响应标志置0
  14. unsigned char Aflag = 0;         // 闹钟开关及闹钟时间显示标志
  15. bit Hflag=0, Tflag=0, Sflag=0;   // Hflag闪烁标志,Tflag闹钟响应标志,Sflag清闹钟响应标志标志
  16. void main()
  17. {
  18.         unsigned char keys, i;
  19.         P1M1=0x00;P1M0=0x08;      // 蜂鸣器配置为强推挽输出
  20.         speaker = 1;              // 关闭蜂鸣器
  21.         Ds1302Init();             // ds1302初始化         
  22.         LCD_Init();               // LCD1602初始化
  23.         Timer0Init();             // 定时器0初始化
  24.         for(i=0;i<3;i++)          // 实验板第一次下载或复位后,往AT24C04中写入闹钟初始化时间
  25.         {
  26.                 write_24c04(0x00+i,alarm[i]);
  27.                 Delay_ms(1);
  28.         }
  29.         while(1)
  30.         {
  31.                 keys = key_scan();    // 获取按键按键值
  32.                 for(i=0;i<3;i++)      // 工作后,读出已存入AT24C04中的闹钟时间
  33.                 {
  34.                         alarm[i] = read_24c04(0x00+i);
  35.                         Delay_ms(1);
  36.                 }
  37.                 settime(keys);                  // 设置时间及闹钟时间函数,keys=0,设置年月日,keys=1,设置时分秒,keys=4,设置闹钟时间
  38.                 Display();            // 工作状态下1602显示函数
  39.                 if(keys == 5)         // 通过按键5设置是否开启闹钟,Aflag=1开启,Aflag=0关闭,Aflag=2查看闹钟时间
  40.                 {
  41.                         Aflag++;
  42.                         if(Aflag==3)      // Aflag累加到3后,归零
  43.                                 Aflag = 0;
  44.                 }
  45.                 if((Aflag==1)&&(TIME[0]==alarm[0])&&(TIME[1]==alarm[1])&&(TIME[2]==alarm[2]))
  46.                 {                     // 判断是否满足闹钟鸣叫条件
  47.                         Tflag = 1;        // 闹钟鸣叫标志置1
  48.                         num2 = 0;         // 鸣叫计数归零
  49.                         Sflag = 0;        // 清闹钟鸣叫标志置0
  50.                 }
  51.                 if((Tflag == 1)&&(Aflag == 1))// 鸣叫需同时满足鸣叫标志为1、闹钟开启
  52.                 {
  53.                         speaker = ~speaker;
  54.                         if(Sflag == 1)            // 判断鸣叫时间是否到5s了
  55.                                 Tflag = 0;            // 5s后,鸣叫标志清0
  56.                 }
  57.                 else
  58.                 {
  59.                         speaker = 0;              // 关闭蜂鸣器
  60.                         Tflag = 0;               
  61.                 }
  62.         }
  63. }
  64. void TM0_Isr() interrupt 1 using 1
  65. {
  66.         static unsigned char num1=0;                  
  67.         num1++;                      // 进一次中断值加1,5ms进一次中断
  68.         if(Tflag == 1)               // 到闹钟时间后,num2开始累加
  69.         {
  70.                 num2++;
  71.         }
  72.         if(100 == num1)              // 选中要调整的时间后,代表这个时间的两位开始每0.5s闪烁一次   
  73.         {
  74.                 num1 = 0;
  75.                 Hflag = ~Hflag;          // 闪烁标志翻转
  76.         }
  77.         if(1000 == num2)             // 闹钟无人关时,鸣叫5s后,自动关闭闹钟,下次时间到时仍会鸣叫      
  78.         {
  79.                 num2 = 0;
  80.                 Sflag = 1;               // 清闹钟标志标志置1
  81.         }
  82. }
复制代码

[我是在我之前发的贴子的基础上,加了闹钟和星期,同时把调整时间选中位改成了闪烁。这个链接是我修改前的模板:(想挑战自己的就拿这个改,看能不能改成我现在这个版本)ds1302用1602实现时间显示及调整的单片机代码
http://www.51hei.com/bbs/dpj-164635-1.html
(出处: 单片机论坛)

P90727-090508.jpg (3.51 MB, 下载次数: 56)

效果图.jpg

效果图.jpg

P90727-091152.jpg (3.39 MB, 下载次数: 57)

闹钟定的时间.jpg

闹钟定的时间.jpg

捕获.PNG (6.27 KB, 下载次数: 56)

用到的模块.jpg

用到的模块.jpg
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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