永发信息网

基于单片机的电子钟

答案:1  悬赏:50  手机版
解决时间 2021-07-25 07:23

我做的毕业设计是基于单片机的电子钟,主要是用“DS1302时钟芯片”,“AT89C51芯片”。谁有“电子钟的完整程序”,还有“单片机的原理图”和“PCB图”。

有的请加本人

QQ:763527604

谢谢!

最佳答案

#include <REGX51.H>
#include "ds1302.h" //包含DS1302头文件
#define leddata P0 //定义LED数据口
#define sec 0x80 //1302秒寄存器地址
#define min 0x82 //1302分寄存器地址
#define hou 0x84 //1302时寄存器地址
#define read 0x01 //读操作,因为读的时候地址要加1,使最低位为1
sbit MODE=P3^4; //按键定义,下同
sbit SET=P3^5;
sbit UP=P3^6;
sbit DOWN=P3^7;
sbit led0=P2^0; //LED位选,因为布线不是按顺序布的,程序定义一下就可以了,下同
sbit led1=P2^3;
sbit led2=P2^7;
sbit led3=P2^4;
sbit led4=P2^6;
sbit led5=P2^5;
//**************函数声明*****************
void delays(unsigned char);
void display(void);
void Scan_Key(void);
void id_case1_key();
void Set_id(unsigned char ,unsigned char);
//*************变量定义******************
unsigned char id=0,timecount,re_disp=0; //定义用到的变量,id为调整模式用,不为0时表示调整模式,调整哪个量由id值确定
//timecount用于500ms定时记数,时间到取反flag标志位,re_disp记数200次共10s,调整状态下按键无操作10s自动返回正常显示状态
bit hour,minute,second,flag; //定义位变量,hour,minute,second分别为调整时闪烁标志位,flag 500ms取反一次,调整位闪烁及冒号闪烁用
unsigned char code tab[]={0x48,0xEE,0x54,0xC4,0xE2,0xC1,0x41,0xEC,0x40,0xC0,0x60}; //LED码表,根据硬件修改
unsigned char inittime[7]={0x00,0x00,0x12,0x16,0x11,0x06,0x04}; //初始化1302时用到的初始化数据
// 秒 分钟 小时 日 月 年 星期
void t0(void) interrupt 1 using 0 //中断处理程序,主要用于取反标志位,返回正常显示状态
{
TH0=(65535-50000)/256; //50ms定时
TL0=(65535-50000)%256;
timecount++;re_disp++;
if(timecount>9)
{
timecount=0;
flag=~flag;
}
if(re_disp>200){re_disp=0;if(id)id=0;}
}
void delays(unsigned char k) //延时函数
{
unsigned char i,j;
for(i=0;i<k;i++)
for(j=0;j<50;j++);
}
void display(void) //显示函数
{
if(flag&hour) //如hour为1表示调整时,flag为1时不显示
{
led0=0;leddata=0xff;delays(10);led0=1;
led1=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led1=1; //&~((unsigned char)~flag<<6)该句根据flag的值决定来显示小数点,为1时显示,4个小数点组成两对冒号,下同
}
else //flag为0时显示,产生闪烁效果,下同
{
leddata=tab[Read1302(hou|read)/16];led0=0;delays(10);led0=1;
leddata=tab[Read1302(hou|read)%16]&~((unsigned char)~flag<<6);led1=0;delays(10);led1=1;
}
if(flag&minute)
{
led2=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led2=1;
led3=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led3=1;
}
else
{
leddata=tab[Read1302(min|read)/16]&~((unsigned char)~flag<<6);led2=0;delays(10);led2=1;
leddata=tab[Read1302(min|read)%16]&~((unsigned char)~flag<<6);led3=0;delays(10);led3=1;
}
if(flag&second)
{
led4=0;leddata=0xff&~((unsigned char)~flag<<6);delays(10);led4=1;
led5=0;leddata=0xff;delays(10);led5=1;
}
else
{
leddata=tab[Read1302(sec|read)/16]&~((unsigned char)~flag<<6);led4=0;delays(10);led4=1;
leddata=tab[Read1302(sec|read)%16];led5=0;delays(10);led5=1;
}
}
void Scan_Key(void) //键盘检测函数
{
display(); //程序开头调用显示函数
if(!SET)
{
while(!SET)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
re_disp=0; //清除记数,重新开始10s定时
id++;if(id>3)id=0; //id加1,后面根据id值对应调整项目
}
if(id==0){hour=0;minute=0;second=0;} //根据id值跳到相应处理函数
if(id==1){hour=1;id_case1_key();} //id为1,选择调整小时位,闪烁标志位置1,然后跳到键盘处理函数,下同
if(id==2){hour=0;minute=1;id_case1_key();}
if(id==3){minute=0;second=1;id_case1_key();}
}
void id_case1_key(void) //键盘处理函数,只有按下set键时才会进入,
{
display();
if (!DOWN) //减少
{
while(!DOWN)display(); //等待按键释放,如一直按下一直调用显示函数,防止显示中断
re_disp=0; //清除记数,重新开始10s定时
Set_id(id,0); //跳到加减判断函数,下同,
}
if (!UP) //增加
{
while(!UP)display();
re_disp=0;
Set_id(id,1);
}
}


//根据选择调整相应项目并写入DS1302
void Set_id(unsigned char sel,unsigned char sel_1) //执行调整项目的函数
{
signed char max,mini,address,item;
if(sel==1) {address=hou; max=23;mini=0;} //小时 //根据id值确定要调整的项,并确定调整上下限,下同
if(sel==2) {address=min; max=59;mini=0;} //分钟
if(sel==3) {address=sec; max=0;mini=0;} //秒
item=Read1302(address|read)/16*10+Read1302(address|read)%16; //从相应的地址读取当前数据并转换为十进制
if (sel_1==0) item--; else item++; //确定是对项目加还是减,并对越限处理
if(item>max) item=mini;
if(item<mini) item=max;
Write1302(0x8e,0x00);//允许写操作
Write1302(address,item/10*16+item%10); //将调整结果转换成压缩BCD码重新写入1302
Write1302(0x8e,0x80);//写保护,禁止写操作
}
void main() //主函数
{
TMOD=0x01; //初始化定时器
TH0=(65535-50000)/256;
TL0=(65535-50000)%256;
EA=1;
ET0=1;
TR0=1;
Write1302(0x90,0xa0);//关闭充电二级管,不能对后备电池进行充电,防止发胀,原来的程序是打开的请关闭
Write1302(0x8e,0x80);//写保护,禁止写操作
if(!UP&!DOWN)Set1302(inittime); //如果同时按下UP和DOWN键则初始化1302,该语句在while(1)前,只执行一次,需要复位,防止误操作
while(1)
{
Scan_Key(); //主程序一直调用键盘检测函数即可
}
}


图加我Q24045922我可以发给你

我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
这次DNF更新说的送礼品是说的新号达到相应
云南文山是不是有H1N1了?听说有,为什么电视
2010 年的护士资格考试现在可以报名了吗?怎
哪里有win7下载地址啊?
不透明物体的颜色由通过它的放射色光决定定
请问安徽阜阳市民航局各开放几个航线
青县沧州青县中医院在哪里啊,我有事要去这里
600到850的品牌手机哪些好?
qq支付密码怎么找回
吃妇科千金片会推迟月经吗?
chichera为什么打不开
哪个大爷能告诉我,最近农场怎么进去这么慢
北大绿卡英语八上一单元测试卷答案
宝贝和老婆,哪个称呼更暖人一些?
学舞蹈对自己有什么好处
推荐资讯
FLASH 修改大师怎么用?我要修改金庸群侠传2
早恋是对的吗?
简单学习网 能信任嘛??
你说的跑商的方法可能吗?
开茶店取什么名好呢
物理研究的尽头是哲学,这句话是谁说的
红宝石 怎么样让宠物 截断树木
我有一张小时候的照片没有底片我想不它传到QQ
现在手机有5.0声道的麽!
英语能及格的来看这是什么意思。
谁有3级以上蓝钻可以帮下忙?
日本出品的片子哪里有下载
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?