打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
多种定时电子钟

多种定时电子钟

/*===================================
/--------------------------------------
项目名称:多种定时电子钟89s52+ds1302+24c02
//-----------------------------------
//=============================================
功能说明:6位数码管显示-时--分--秒,如:12-36-57
设置说明:
P0--段,P2--位(p2.5为个位),自带充电功能(470UF电容作为电源)
k1
作者:朱世民
说明:通过实验板验证通过 2010-03-22
==========================================*/
#include "reg51.h"
#include "ds1302.h" //自建库文件
#include "24c02.h"
#define uchar unsigned char
unsigned char code tab[]={0x28,0x7E,0xA2,0x62,0x74,0x61,0x21,0x7A,
0x20,0x60,0xFF,0x25,0xA9,0x26,0xA1,0xf7};
// 学林电子 //0~~9段码 abcdefgh,共阳
//unsigned char code tab[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
// 0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};
// 师大版显示代码
/*************************ds1302与at89s52引脚连接********************/
sbit k1=P1^0; //按住---调时间 +时、分、秒 调试完后再按下k3写入
sbit k2=P1^1; //按住---调定时 +时、分、秒 调试完后再按下k3写入
sbit k3=P1^2; //按住---定时查看,+k4,chakancishu
sbit beep=P3^2; //定时蜂鸣器输出
bit flag,bz; //秒显标志

unsigned char i,tiaobuf,n,buf1,hm,key,dingshi,ckcs,shi,fen,week,dskg,addr24c,tiaobian;
unsigned int num;//计数定时蜂鸣器次数
unsigned char data time[4]={0x55,0x00,0x00,0x02}; //秒,分,时,星期,寄存器初始值
unsigned char data lst[4];//临时缓存
unsigned char data ds[4]={0x52,0x56,0x12,0x02};//定时时间
unsigned char data dispbuf[4];timebuf[4];//显示缓存、定时蜂鸣器输出

/***********************显示程序**********************************************/
/* 动态扫描条件(单个LED在1秒内): count >=50次 //点亮次数 */
/* */
/* DS1302秒,分,时寄存器是BCD码形式: 用16求商和余进行"高4位"和"低4位"分离 */
/* 0xdf,0xef,0xf7,0xfb,0xfd,0x7e : 位选 */
/****************************************************************************/
void disp()//
{ unsigned char m,aim; //m为缓冲;
if(dingshi==0) //若没调定时,则显示时间
for(aim=0;aim<4;aim++)
{dispbuf[aim]=time[aim];} //送显示缓存

m=dispbuf[1]; //把

P0=tab[m%16]; //取分低4位BCD码
P2=0x7f; //显示秒(个位);
delay(200); //持续2ms
P2=0xff; //消影

P0=tab[m/16]; //取高4位BCD码:显示分(十位);
P2=0xbf;
delay(200);
P2=0xff;

if(flag)P0=255; //关闭显示
else
P0=tab[15]; //显示 -
P2=0xdf;
delay(200);
P2=0xff;
/////////////////////////////////////
m=dispbuf[2]; //把分--送缓存
P0=tab[m%16]; //第3个数码管:显示时(个位)
P2=0xef;
delay(200);
P2=0xff;

P0=tab[m/16]; //第4个数码管:显示时(十位)
P2=0xf7;
delay(200);
P2=0xff;
/////////////////////////////////////

P0=tab[15]; //取高4位BCD码:显示秒(十位);
P2=0xfb;
delay(200);
P2=0xff;
///////////////////////////////////////


//第5个数码管:显示定时次数(个位)
if(dingshi==0) //若mei查看定时
P0=tab[15]; //显示 -
else //若查看定时
P0=tab[dingshi];//显示定时次数 ;
P2=0xfd;
delay(200);
P2=0xff;


m=dispbuf[3]; //把周--送缓存
if(dingshi==0)
P0=tab[m%16]; //第6个数码管:显示星期
else P0=tab[dskg]; //否则显示定时(1)开(0)关
P2=0xfe;
delay(200);
P2=0xff;

}

//=========================
//=======写入ds1302=======
//=========================
void Write_time()
{
write_1302(0x8e,0x00); //WP=0 写操作
write_1302(0x80,time[0]); //写秒
write_1302(0x82,time[1]); //写分
write_1302(0x84,time[2]); //写时
write_1302(0x8a,time[3]); //写周
write_1302(0x8e,0x80); //WP=1 写保护
}
//============================
////ten--bcd转换 因为1302是以bcd码存放的
//==========================
void ten_bcd()
{unsigned char j,buf3,buf4;
for(j=0;j<4;j++)
{buf3=lst[j];
buf4=lst[j];
buf3=buf3/10; //取出十位
buf4=buf4%10; //取出个位
buf3=(buf3*16); //把十位转换为高四位
lst[j]=buf4|buf3; //把个位并入
}
}
//===================================
// 按键检测程序 用来保存、查看定时
//===================================
bit testk3()
{k3=1; bz=0;
if(!k3)
{ disp();
if(!k3)
{bz=1;}
return bz;
}
}
//========================
// 按键检测程序
//========================
uchar testkey()
{unsigned char sscs;//显示次数
P1|=0Xff;key=0;
if((P1&0xf8)!=0xf8)
{for(sscs =15;sscs>0;sscs--)
disp(); //显示15次数
if((P1&0xf8)!=0xf8)
{key=P1;key|=0x07; key=~key; }
}
return key;
}

void getkey()
{ switch(key)
{
case 0x08:if(++dingshi>4)dingshi=0; break;//定时组数,进入调定时
case 0x10:if(++dskg>1)dskg=0; break; //为1,为定时开;为0,为定时关
case 0x20:if(++week>7)week=1; break; //星期加1
case 0x40:if(++shi>23)shi=0; break; //时 加1
case 0x80:if(++fen>59)fen=0; break; //分加1
default: break;
}

lst[0]=0; lst[1]=fen;lst[2]=shi;lst[3]=week;//送临时缓存
ten_bcd(); //转换为BCD吗
}
//============================
////从1302读取时、分、秒并显示
//==========================
void read_ds1302time()
{ unsigned char s;
time[0]=read_1302(0x81);// 读出时间
if(time[0]!=s) // 读出秒,和上次比较不等
{flag=!flag;//秒闪指示(变化一次闪一次)
s=time[0]; // 将秒的值送入缓存,以便下次比较,取出跳变

// if(time[0]==0x00) //当秒=0时,减少读1302的时间
time[1]=read_1302(0x83);//读分 一分钟读一次分
// if(time[1]==0x00) //当分=0时,一小时读一次时
time[2]=read_1302(0x85);//读时(一小时读一次,减少读取次数和时间)
// if(time[2]==0x00)
time[3]=read_1302(0x8b);//读取周

}

}
//=========================
// 调定时
//==========================
void tiaodingshi()
{disp();
if(testkey())
{ getkey();
for(n=0;n<4;n++)
{ds[n]=lst[n];dispbuf[n]=lst[n];}//获得定时缓存
disp();
}
}
//===========================
//定时时间---写入24c02中
//===========================
void dswrite_24c02()
{
// addr24c=(dingshi*5+n);定时次数*5,每次占5个单元
x24c02_write((dingshi*5+1),ds[1]);disp();//写入--分
x24c02_write((dingshi*5+2),ds[2]);disp();//写入--时
x24c02_write((dingshi*5+3),dskg);disp();//写入--定时开.关
}

/************************主程序**********************************************/
/************************主程序**********************************************/
/************************主程序**********************************************/

void main(void)
{
n=0;beep=1;addr24c=1;
TH0=0X3C;
TL0=0XB4;

TH1=0XFF;
TL1=0X38;
TMOD=0X11;
EA=0; //中断用来调时间产生 闪烁哦
ET0=1; TR0=1;
ET1=1; TR1=0;//中断1用来产生2kHZ方波,驱动蜂鸣器

/* write_1302(0x8e,0x84); //WP=0 写操作
write_1302(0x90,0x35); // 开涓流充电
write_1302(0x8e,0x80); //WP=1 写保护
write_1302(0x80,0x00);*/

while(1)
{ P1=0xff; //按键端口置1
disp();
if((P1&0XFF)!=0XFF) //若有键按下
{
while(!k1) //若进入调 //若进入调时间DS1302
{ disp();
if(testkey())
{ getkey();
for(i=0;i<4;i++)
{time[i]=lst[i];dispbuf[i]=time[i];}
}
if(testk3()) Write_time(); //若k3按下,写入时间DS1302
}

//若调定时。总共可设5次定时
while(!k2)//
{ tiaodingshi(); //检测按键
disp(); //显示
if(dingshi==1){ if(testk3()){dswrite_24c02();} }
//若k3按下,写入第1次定时时间,此时dingshi=1
if(dingshi==2){ if(testk3()){dswrite_24c02();}}

if(dingshi==3){ if(testk3()){dswrite_24c02();}}
if(dingshi==4){ if(testk3()){dswrite_24c02();} }
}
//=====查看定时
while(!k3)
{
for(n=0;n<4;n++)
{ addr24c=dingshi*5+n; dispbuf[n]=x24c02_read(addr24c);}
disp();
if(testkey())
getkey();

} } //调节完毕后

else //若没键按下。则读时显示
{read_ds1302time(); // 利用跳变时读取,可以大大提高效率

if(tiaobian!=tiaobuf) //若比较两次不同,取出跳变
{ tiaobuf=tiaobian; //把当前值缓存,以便下次比较
if(++addr24c>3)addr24c=1; //每次 地址加1;每组定时逐步比较

for(n=0;n<4;n++)
{timebuf[n]=x24c02_read(addr24c*5+n);}//读取定时值
disp();
if(timebuf[3]==1) //若,定时为1.开
if(timebuf[2]==time[2]) //则比较时
if(timebuf[1]==time[1]) //再比较分
TR1=1; //以上三个相同,启动中断1,beep发声
}

}}}



//=================================
//中断0,产生20s定时。用来产生跳变,来读取比较定时时间
//==================================
void time50ms() interrupt 1 using 1
{TH0=0X3C;
TL0=0XB4;
if(++hm==200)
{hm=0;if(++tiaobian>1)tiaobian=0;}
}
//=================================
//中断1,产生2khz eep发声
//==================================
void time02ms() interrupt 3 using 2
{TH1=0XFF;
TL1=0X08;
beep=!beep;
if(++num>30000)
{num=0;TR1=0;beep=1;}
}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
89s52+ds1302电子钟
018.任意进制数的转换
PID温度控制系统源序程序
多个74HC595级联+并联驱动电路方案
【TI博客大赛】MSP430单片机定时器A
linux下arp攻击的实现
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服