|
/*************************************************************************************
* 实验:万年历(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"
*************************************************************************************/
- #include <stc8.h>
- #include "ds1302.h"
- #include "display.h"
- #include "key.h"
- #include "settime.h"
- #include "timer0.h"
- #include "1602.h"
- #include "i2c.h"
- #include "delay.h"
- sbit speaker = P1^3; // 蜂鸣器
- char TIMED[7]; // 用于接收ds1302中的数据,转化为有符号类型,便于界限判定
- unsigned char alarm[3]={0,1,12}; // 存放闹钟时间(12:01:00闹钟初始化时间)
- unsigned int num2=0; // 用于无人关闹钟时,计数,当达到5s后,把闹钟响应标志置0
- unsigned char Aflag = 0; // 闹钟开关及闹钟时间显示标志
- bit Hflag=0, Tflag=0, Sflag=0; // Hflag闪烁标志,Tflag闹钟响应标志,Sflag清闹钟响应标志标志
- void main()
- {
- unsigned char keys, i;
- P1M1=0x00;P1M0=0x08; // 蜂鸣器配置为强推挽输出
- speaker = 1; // 关闭蜂鸣器
- Ds1302Init(); // ds1302初始化
- LCD_Init(); // LCD1602初始化
- Timer0Init(); // 定时器0初始化
- for(i=0;i<3;i++) // 实验板第一次下载或复位后,往AT24C04中写入闹钟初始化时间
- {
- write_24c04(0x00+i,alarm[i]);
- Delay_ms(1);
- }
- while(1)
- {
- keys = key_scan(); // 获取按键按键值
- for(i=0;i<3;i++) // 工作后,读出已存入AT24C04中的闹钟时间
- {
- alarm[i] = read_24c04(0x00+i);
- Delay_ms(1);
- }
- settime(keys); // 设置时间及闹钟时间函数,keys=0,设置年月日,keys=1,设置时分秒,keys=4,设置闹钟时间
- Display(); // 工作状态下1602显示函数
- if(keys == 5) // 通过按键5设置是否开启闹钟,Aflag=1开启,Aflag=0关闭,Aflag=2查看闹钟时间
- {
- Aflag++;
- if(Aflag==3) // Aflag累加到3后,归零
- Aflag = 0;
- }
- if((Aflag==1)&&(TIME[0]==alarm[0])&&(TIME[1]==alarm[1])&&(TIME[2]==alarm[2]))
- { // 判断是否满足闹钟鸣叫条件
- Tflag = 1; // 闹钟鸣叫标志置1
- num2 = 0; // 鸣叫计数归零
- Sflag = 0; // 清闹钟鸣叫标志置0
- }
- if((Tflag == 1)&&(Aflag == 1))// 鸣叫需同时满足鸣叫标志为1、闹钟开启
- {
- speaker = ~speaker;
- if(Sflag == 1) // 判断鸣叫时间是否到5s了
- Tflag = 0; // 5s后,鸣叫标志清0
- }
- else
- {
- speaker = 0; // 关闭蜂鸣器
- Tflag = 0;
- }
- }
- }
- void TM0_Isr() interrupt 1 using 1
- {
- static unsigned char num1=0;
- num1++; // 进一次中断值加1,5ms进一次中断
- if(Tflag == 1) // 到闹钟时间后,num2开始累加
- {
- num2++;
- }
- if(100 == num1) // 选中要调整的时间后,代表这个时间的两位开始每0.5s闪烁一次
- {
- num1 = 0;
- Hflag = ~Hflag; // 闪烁标志翻转
- }
- if(1000 == num2) // 闹钟无人关时,鸣叫5s后,自动关闭闹钟,下次时间到时仍会鸣叫
- {
- num2 = 0;
- Sflag = 1; // 清闹钟标志标志置1
- }
- }
复制代码
[我是在我之前发的贴子的基础上,加了闹钟和星期,同时把调整时间选中位改成了闪烁。这个链接是我修改前的模板:(想挑战自己的就拿这个改,看能不能改成我现在这个版本)ds1302用1602实现时间显示及调整的单片机代码
http://www.51hei.com/bbs/dpj-164635-1.html
(出处: 单片机论坛)
|
|