目录
具体实现功能
系统由STC89C52单片机+DS1302时钟芯片+按键模块+LCD1602显示+电源构成。
具体功能:
1、可以显示年、月、日、时、分、秒、星期、农历;
2、按键可以设置闹钟及报警;
3、按键可以调整时间,显示是平年还是闰年。
共4个按键:设置、加、减、切换。
设计介绍
51单片机简介
51单片是一种低功耗、高性能CMOS-8位微控制器,具有8K可编程Flash存储器,使得其为众多嵌入式控制应用系统提供高灵活、超有效的解决方案。
51系列单片机具有以下标准功能:
8k字节Flash,512字节RAM,
32位I/O口线,看门狗定时器,
内置4KB EEPROM,
MAX810复位电路,
三个16位定时器/计数器,
一个6向量2级中断结构,
全双工串行口。
另外, 51系列在空闲模式下,CPU停止工作,允许RAM、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机停止工作,直到下一个中断或硬件复位为止。本设计所使用的芯片可兼容以下所有的51系列单片机(包括AT系列和STC系列)。
设计思路
文献研究法:搜集整理相关研究资料,阅读文献,为研究做准备;
调查研究法:通过调查、分析、具体实验等方法,发现相关存在问题和解决办法;
比较分析法:比较不同设计的具体原理,以及同一类传感器性能的区别,分析系统的研究现状与发展前景;
软硬件设计法:通过软硬件设计实现硬件,最后测试各项功能是否满足要求。
设计内容
原理图(AD19)
本系统原理图设计采用Altium Designer19,具体如图。
程序(Keil5)
本设计利用KEIL5软件实现程序设计,主函数如下:
//*******************主函数**************************
//***************************************************
void main()
{
init_eeprom(); //开始初始化保存的数据
P1=0xff;
// delay(2000);
lcd_init(); //调用液晶屏初始化子函数
ds1302_init(); //调用DS1302时钟的初始化子函数
init(); //调用定时计数器的设置子函数
led1=0; //打开LCD的背光电源
buzzer=0; //蜂鸣器长响一次
delay(100);
buzzer=1;
init_eeprom();
while(1) //无限循环下面的语句:
{
keyscan(); //调用键盘扫描子函数
led=led1;
if(timerOn==1)
alarm(); //闹钟输出
if((fen==0)&&(miao==0))
{
if(shi>12)
temp_hour=shi-12;
else
{
if(shi==0)
temp_hour=12;
else
temp_hour=shi;
}
shangyimiao=miao;
baoshi=1;
}
if(baoshi==1)
{
ZD_baoshi();
do
keyscan();
while(shangyimiao==miao);
shangyimiao=miao;
}
}
}
void timer0() interrupt 1 //取得并显示日历和时间
{
//读取秒时分周日月年七个数据(DS1302的读寄存器与写寄存器不一样):
miao = BCD_Decimal(read_1302(0x81));
fen = BCD_Decimal(read_1302(0x83));
shi = BCD_Decimal(read_1302(0x85));
ri = BCD_Decimal(read_1302(0x87));
yue = BCD_Decimal(read_1302(0x89));
nian=BCD_Decimal(read_1302(0x8d));
//week=BCD_Decimal(read_1302(0x8b)); //不读取,直接通过日期计算得到
if((led1==0))
{
if(temp_miao!=miao)
{
temp_miao=miao;
bltime++;
}
if(bltime==10)
{
led1=1;
bltime=0;
}
}
if(T_NL_NZ==1) //显示农历
{
uint nian_temp,temp12;
temp12=nian;
nian_temp=2000+(temp12&0xF0)*10+temp12&0x0F;
if((nian_temp%400==0)||((nian_temp%100!=0)&&(nian_temp%4==0))) //判断是否为闰年
p_r=1;
else
p_r=0;
Conversion(0,nian,yue,ri);
write_1602com(er);//时间显示固定符号写入位置?
for(a=0;a<16;a++)
{
if(p_r==0)
write_1602dat(nlp[a]);//写显示时间固定符号,两个冒号
else
write_1602dat(nlr[a]);
}
write_nl(3,year_moon);//农历 年
write_nl(6,month_moon);//农历 月
write_nl(9,day_moon);//农历 日
do
keyscan();
while(T_NL_NZ==1);
write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<16;a++)
{
write_1602dat(qk[a]);//写显示时间固定符号,两个冒号
}
write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号
}
}
if(T_NL_NZ==2) //显示闹钟时间,
{
write_1602com(er);//时间显示固定符号写入位置?
for(a=0;a<16;a++)
write_1602dat(NZd[a]);//写显示时间固定符号,两个冒号
write_sfm(7,nz_shi);//农历 年
write_sfm(10,nz_fen);//农历 月
write_1602com(er+13);
if(timerOn==1)
{
write_1602dat('O');
write_1602dat('N');
write_1602dat(' ');
}
else
{
write_1602dat('O');
write_1602dat('F');
write_1602dat('F');
}
do
keyscan();
while(T_NL_NZ==2);
write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<16;a++)
{
write_1602dat(qk[a]);//写显示时间固定符号,两个冒号
}
write_1602com(er);//时间显示固定符号写入位置,从第2个位置后开始显示
for(a=0;a<8;a++)
{
write_1602dat(tab2[a]);//写显示时间固定符号,两个冒号
}
}
else
{
write_sfm(6,miao);//秒,从第二行第8个字后开始显示(调用时分秒显示子函数)
write_sfm(3,fen);//分,从第二行第5个字符后开始显示
write_sfm(0,shi);//小时,从第二行第2个字符后开始显示
}
//显示日、月、年数据:
write_nyr(9,ri);//日期,从第二行第9个字符后开始显示
write_nyr(6,yue);//月份,从第二行第6个字符后开始显示
write_nyr(3,nian);//年,从第二行第3个字符后开始显示
Conver_week(nian,yue,ri);
write_week(week);
}
代码运行截图:
仿真实现(protues8.7)
本设计利用protues8.7软件实现仿真设计。
全部资料
全部资料包括程序(KEIL5)、AD原理图(AD19)、PCB源文件(AD19)、参考论文(仅供参考)、开题报告、任务书、实物图、实物演示视频、软硬件设计框图等,具体如图,全网最全!!
资料获取:【腾讯文档】21-基于51单片机的数字时钟(万年历)
https://docs.qq.com/doc/DSVdlVmNRS0pmcXNn