您好,欢迎访问三七文档
当前位置:首页 > 电子/通信 > 综合/其它 > 基于C51单片机的数字可调时钟
河南机电高等专科学校《C51程序设计》大作业设计题目:数字可调时钟班级:通技091学号:090413128姓名:成绩:2011年11月1设计任务制作数字可调时钟,要求可以分开调节分、时、年、月、日,能够显示温度。2电路原理图以下为protel99se画的的原理图3系统流程图数字可调时钟分以下四个部分构成:显示部分:此次显示采用了动态扫描显示,采用74ls573进行数据锁存。温度采集:温度采集采用了18b20采集的,18b20转化温度较快,精度高。时钟:采用普通的ds1302芯片。数据运算:单片机用普通的8051单片机(12M晶振)。4源程序/*******************************数字可调时钟*********************************//*******************************by:lhc****************************************/#includereg51.h#defineDataPortP0voiddelayms(unsignedchari);sbitDQ=P1^3;sbitsclk=P1^4;sbitdate=P1^5;sbitrst=P1^6;sbitLATCH1=P2^2;//定义锁存使能端口段锁存sbitLATCH2=P2^3;//位锁存unsignedchartime[8]={20,11,11,27,11,30,00,7};//年月日时分秒周unsignedchartime1[8],readtemflag;unsignedcharcodeDuanMa[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//显示段码值0~9unsignedcharcodeWeiMa[]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};//分别对应相应的数码管点亮,即位码unsignedcharcodepingnian[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};//平年的月份天数unsignedcharcodeyunnian[13]={0,31,29,31,30,31,30,31,31,30,31,30,31};//闰年的月份天数unsignedcharTempData[8];//存储显示值的全局变量voiddelay(unsignedchari){while(--i);//us延时函数}voiddelayms(unsignedchari)//ms延时函数{while(i--){delay(245);delay(245);}}bitrest(void)//18b20重启函数{bitk=0;DQ=1;delay(5);DQ=0;delay(150);delay(200);DQ=1;delay(40);k=DQ;delay(25);return(k);}unsignedcharread()//18b20读数据函数{unsignedchari=0;unsignedchardat=0;for(i=0;i8;i++){DQ=0;dat=1;DQ=1;if(DQ)dat|=0x80;delay(25);}return(dat);}voidwrite(unsignedchardat)//18b20写数据函数{unsignedchari=0;for(i=0;i8;i++)单片机数码管显示模块温度采集模块键盘时钟模块{DQ=0;DQ=dat&0x01;delay(25);DQ=1;dat=1;}delay(25);}unsignedintReadTemperature(void)//读取温度函数{unsignedchara=0;unsignedintkk=0,b=0;LOOP:if(rest()==0){write(0xCC);//跳过ROMwrite(0x44);//初始化温度转换delayms(20);rest();TH1=0XFa;TL1=0Xff;write(0xCC);write(0xBE);//读取温度a=read();b=read();b=8;kk=a+b;return(kk);}elsegotoLOOP;}voidrestds1302(void){sclk=0;rst=0;//ds1302重启}voidwritebyte(unsignedcharaddr,unsignedcharbyte)//写入ds1302一个字节数据{unsignedchari;rst=1;addr=addr&0xfe;for(i=0;i8;i++){date=addr&0x01;sclk=1;sclk=0;addr=1;}for(i=0;i8;i++){date=byte&0x01;sclk=1;sclk=0;byte=1;}rst=0;}unsignedcharreadbyte(unsignedcharaddr)//读取一个字节的数据{unsignedchari,temp;rst=1;addr=addr|0x01;for(i=0;i8;i++)//读函数{date=addr&0x01;sclk=1;sclk=0;addr=addr1;}for(i=0;i8;i++){temp=temp1;if(date)temp|=0x80;elsetemp&=0x7f;sclk=1;sclk=0;}rst=0;returntemp;}voidwritetime(void)//调时函数{unsignedchari,tmp;for(i=0;i8;i++){//BCD处理tmp=time[i]/10;time1[i]=time[i]%10;time1[i]=time1[i]+tmp*16;}writebyte(0x8e,0x00);//关闭写保护writebyte(0x80,0x80);//暂停writebyte(0x8c,time1[1]);//年写入writebyte(0x88,time1[2]);//月写入writebyte(0x86,time1[3]);//日写入//些时间writebyte(0x84,time1[4]);//时写入writebyte(0x82,time1[5]);//分写入writebyte(0x80,time1[6]);//秒写入writebyte(0x8a,time1[7]);//周写入//writebyte(0x80,0x00);//秒写入writebyte(0x8e,0x80);//打开写保护}voidreadtime(void)//读取时间函数{unsignedchari,tmp;time1[1]=readbyte(0x8d);//年读time1[2]=readbyte(0x89);//月读time1[3]=readbyte(0x87);//日读//读时间time1[4]=readbyte(0x85);//时time1[5]=readbyte(0x83);//分time1[6]=readbyte(0x81);//秒time1[7]=readbyte(0x8b);//周for(i=0;i8;i++)//BCD处理{tmp=time1[i]/16;time[i]=time1[i]%16;time[i]=time[i]+tmp*10;}}voidDisplay(unsignedcharFirstBit,unsignedcharNum)//动态显示函数{staticunsignedchari=0;DataPort=0;//清空数据,防止有交替重影LATCH1=1;//段锁存LATCH1=0;DataPort=WeiMa[i+FirstBit];//取位码LATCH2=1;//位锁存LATCH2=0;DataPort=TempData[i];//取显示数据,段码LATCH1=1;//段锁存LATCH1=0;i++;if(i==Num)i=0;}unsignedcharkey(void)//键盘读取函数{unsignedchari;if(P3!=0xff){delay(10);if(P3!=0xff){i=P3;while(P3!=0xff);switch(i){case0xfe:return1;break;case0xfd:return2;break;case0xfb:return3;break;default:return0;break;}}}return0;}voidT1_rest()//定时器1的初始化函数{TMOD|=0X10;TH1=0XF8;TL1=0X30;EA=1;ET1=1;TR1=1;}voidisr0(void)interrupt3{staticunsignedcharqq;TR1=0;TH1=0XF8;TL1=0X30;Display(0,8);//送去显示qq++;if(qq==200){qq=0,readtemflag=1;}TR1=1;}voidmain(){unsignedcharbian=0,k=0;unsignedcharnum=6;unsignedinth,l,tempp,year;bitnianflag;restds1302();writetime();T1_rest();while(1){readtime();year=time[1]*200;if(year%4==0&&year%100!=0||year%400==0)nianflag=1;elsenianflag=0;k=key();if(k!=0){if(k==1){bian++;num=6;k=0;}//调节显示的内容if(bian==3)bian=0;if(k==2){num--;if(num4)bian=1;if(num3)bian=0;//选着调节对象分,时,年月日if(num==0)num=6;k=0;}if(k==4&&num!=6)//调节对象(分时年月日)加一{time[num]++;if(num==5&&time[num]==60)time[num]=0;if(num==4&&time[num]==24)time[num]=0;if(num==3&&nianflag){if(time[3]yunnian[time[2]])time[3]=1;}elseif(num==3){if(time[3]pingnian[time[2]])time[3]=1;}if(num==2&&time[num]==13)time[num]=1;if(num==1&&time[num]==99)time[num]=0;k=0;}if(k==3&&num!=6)//调节对象(分时年月日)减一{time[num]--;if(time[num]==-1&&num==5)time[num]=59;if(time[num]==-1&&num==4)time[num]=23;if(num==3&&nianflag){if(time[3]==0)time[3]=yunnian[time[2]];}elseif(num==3){if(time[3]==0)time[3]=pingnian[time[2]];}if(time[num]==0&&num==2)time[num]=12;if(time[num]==-1&&num==1)time[num]=99;k=0;}if(nianflag){if(time[3]yunnian[time[2]])time[3]=1;}else{if(time[3]pingnian[time[2]])time[3]=1;}writetime();}if(bian==0)//对时,分,秒,显示数据分离处理{TempData[0]=DuanMa[time[4]/10];TempData[1]=DuanMa[time[4]%10];Te
本文标题:基于C51单片机的数字可调时钟
链接地址:https://www.777doc.com/doc-2568763 .html