基于stc89c52单片机,DS1302芯片,通过LCD1602显示日期和时间,并且通过按键对日期和时间进行调整。有闹钟功能,当时间到时蜂鸣器提醒,设计一个电子时钟代码。
时间: 2023-12-24 17:05:22 浏览: 155
DS1302 带按键电子钟程序代码
以下是stc89c52单片机和DS1302芯片的电子时钟代码,其中包括了LCD1602和蜂鸣器的控制以及按键的检测和调整日期时间:
```
#include <reg52.h>
#include <intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit SCLK=P1^0; //DS1302时钟信号
sbit IO=P1^1; //DS1302数据信号
sbit RST=P1^2; //DS1302复位信号
sbit beep=P1^3; //蜂鸣器
uchar code table[]="0123456789";
uchar year,month,day,week,hour,minute,second;
uchar year1,month1,day1,hour1,minute1,second1;
uchar flag1,flag2,flag3;//flag1-年月日标志,flag2-时分秒标志,flag3-闹钟标志
uchar num;//调整数值
uchar keynum;//按键扫描返回值
//延时函数
void delay(uint z)
{
uint x,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
//DS1302写一个字节
void DS1302WriteByte(uchar dat)
{
uchar i;
for(i=0;i<8;i++)
{
SCLK=0;
IO=dat&0x01;
dat>>=1;
SCLK=1;
}
}
//DS1302读一个字节
uchar DS1302ReadByte()
{
uchar i,dat=0;
for(i=0;i<8;i++)
{
SCLK=0;
dat>>=1;
if(IO)
dat|=0x80;
SCLK=1;
}
return dat;
}
//DS1302初始化
void DS1302Init()
{
RST=0;
delay(10);
RST=1;
delay(10);
DS1302WriteByte(0x8e);//写控制寄存器
DS1302WriteByte(0x00);//禁止写保护
}
//DS1302读取时间日期
void DS1302ReadTime()
{
uchar i;
DS1302WriteByte(0xbe);//读取命令
for(i=0;i<7;i++)
{
switch(i)
{
case 0:second=DS1302ReadByte();break;
case 1:minute=DS1302ReadByte();break;
case 2:hour=DS1302ReadByte();break;
case 3:day=DS1302ReadByte();break;
case 4:month=DS1302ReadByte();break;
case 5:week=DS1302ReadByte();break;
case 6:year=DS1302ReadByte();break;
}
}
}
//DS1302设置时间日期
void DS1302SetTime()
{
uchar i;
DS1302WriteByte(0x8e);//写控制寄存器
DS1302WriteByte(0x80);//使能写保护
for(i=0;i<7;i++)
{
switch(i)
{
case 0:DS1302WriteByte(second1);break;
case 1:DS1302WriteByte(minute1);break;
case 2:DS1302WriteByte(hour1);break;
case 3:DS1302WriteByte(day1);break;
case 4:DS1302WriteByte(month1);break;
case 5:DS1302WriteByte(week);break;
case 6:DS1302WriteByte(year1);break;
}
}
DS1302WriteByte(0x8e);//写控制寄存器
DS1302WriteByte(0x00);//禁止写保护
}
//LCD1602写命令
void LCD_WriteCommand(uchar com)
{
P0=com;
RS=0;
RW=0;
EN=1;
_nop_();
_nop_();
EN=0;
delay(5);
}
//LCD1602写数据
void LCD_WriteData(uchar dat)
{
P0=dat;
RS=1;
RW=0;
EN=1;
_nop_();
_nop_();
EN=0;
delay(5);
}
//LCD1602初始化
void LCD_Init()
{
LCD_WriteCommand(0x38); //8位,双行,5×7点阵
LCD_WriteCommand(0x0c); //显示开,光标关,不闪烁
LCD_WriteCommand(0x06); //文字从左到右,不移动屏幕
LCD_WriteCommand(0x01); //清屏,光标回到原点
}
//显示当前时间日期
void DisplayTime()
{
uchar shi,ge;
LCD_WriteCommand(0x80);//第一行第一列
shi=hour/10;
ge=hour%10;
LCD_WriteData(table[shi]);
LCD_WriteData(table[ge]);
LCD_WriteData(':');
shi=minute/10;
ge=minute%10;
LCD_WriteData(table[shi]);
LCD_WriteData(table[ge]);
LCD_WriteData(':');
shi=second/10;
ge=second%10;
LCD_WriteData(table[shi]);
LCD_WriteData(table[ge]);
LCD_WriteCommand(0xc0);//第二行第一列
shi=year/10;
ge=year%10;
LCD_WriteData('2');
LCD_WriteData('0');
LCD_WriteData(table[shi]);
LCD_WriteData(table[ge]);
LCD_WriteData('-');
shi=month/10;
ge=month%10;
LCD_WriteData(table[shi]);
LCD_WriteData(table[ge]);
LCD_WriteData('-');
shi=day/10;
ge=day%10;
LCD_WriteData(table[shi]);
LCD_WriteData(table[ge]);
}
//蜂鸣器响
void Beep()
{
uchar i;
for(i=0;i<20;i++)
{
beep=~beep;
delay(50);
}
}
//按键扫描函数
uchar KeyScan()
{
uchar temp=0;
P3=0xff;
if(P3!=0xff)
{
delay(5);
if(P3!=0xff)
{
switch(P3)
{
case(0x7f):temp=1;break;
case(0xbf):temp=2;break;
case(0xdf):temp=3;break;
case(0xef):temp=4;break;
}
while(P3!=0xff);
}
}
return temp;
}
//调整时间日期
void AdjustTime()
{
switch(keynum)
{
case 1:
if(flag1==0)
{
flag1=1;
flag2=0;
flag3=0;
num=year;
}
else if(flag1==1)
{
year1=num;
flag1=0;
DS1302SetTime();
}
break;
case 2:
if(flag1==0)
{
flag1=1;
flag2=0;
flag3=0;
num=month;
}
else if(flag1==1)
{
month1=num;
flag1=0;
DS1302SetTime();
}
break;
case 3:
if(flag1==0)
{
flag1=1;
flag2=0;
flag3=0;
num=day;
}
else if(flag1==1)
{
day1=num;
flag1=0;
DS1302SetTime();
}
break;
case 4:
if(flag2==0)
{
flag1=0;
flag2=1;
flag3=0;
num=hour;
}
else if(flag2==1)
{
hour1=num;
flag1=0;
flag2=0;
DS1302SetTime();
}
break;
case 5:
if(flag2==0)
{
flag1=0;
flag2=1;
flag3=0;
num=minute;
}
else if(flag2==1)
{
minute1=num;
flag1=0;
flag2=0;
DS1302SetTime();
}
break;
case 6:
if(flag2==0)
{
flag1=0;
flag2=1;
flag3=0;
num=second;
}
else if(flag2==1)
{
second1=num;
flag1=0;
flag2=0;
DS1302SetTime();
}
break;
case 7:
if(flag3==0)
{
flag1=0;
flag2=0;
flag3=1;
num=0;
}
else if(flag3==1)
{
flag1=0;
flag2=0;
flag3=0;
}
break;
}
}
//闹钟功能
void Alarm()
{
if(hour==hour1 && minute==minute1 && second==0 && flag3==1)
{
Beep();
flag3=0;
}
}
//主函数
void main()
{
LCD_Init();
DS1302Init();
while(1)
{
DS1302ReadTime();
DisplayTime();
keynum=KeyScan();
if(keynum!=0)
AdjustTime();
Alarm();
}
}
```
在代码中,我们首先定义了单片机端口引脚和DS1302芯片的连接方式,然后定义了一些常量、全局变量、函数等。
在程序中,我们通过DS1302芯片来获取时间日期,通过LCD1602显示时间日期,并且通过按键来进行时间日期的调整。同时,我们还添加了闹钟功能,当时间到达预设的时间时,蜂鸣器会响起提醒。
需要注意的是,我们在代码中使用了延时函数来控制时间,这种方式并不是很准确,实际应用中需要使用定时器来控制时间。
此外,我们还需要将代码烧录到单片机中,并将单片机、DS1302芯片、LCD1602和蜂鸣器等连接起来才能进行测试。
阅读全文