/**************************************************//*基于STC12C5A60S2系列单片机+595驱动五个数码管+165按键输入+1302实时时钟+18B20温度传感器的万年历时钟功能键:0xfe:实现温度,时间,年月日,周的转换显示0xdf:实现每按一次可以一次更改小时,分,年,月,日,周的闪烁,而实现加减按键对其改变数值0xfb:加功能键,在0xdf有效的情况下才能生效0xfd:减功能键,在0xdf有效的情况下才能生效数码管亮度有点不一致,还希望高手能帮忙解决,其他功能都是正常的,也可以给各位爱好单片机的新人们一个互相交流的一段小程序,后面付有图片*/#include12C5A60S2.h//头文件#includeintrins.h#defineucharunsignedchar//宏定义#defineuintunsignedintuchartime_tuf[]={0x14,0x04,0x10,0x12,0x30,0x00,0x5};//年月日时分秒周ucharcodeweima[]={0x20,0x10,0x08,0x04,0x02,0x01};//数码管位选ucharcodeduan_ma[]={0xee,0x88,0xd6,0xdc,0xb8,0x7c,0x7e,0xc8,0xfe,0xfc};//数码管段选信号ucharsec,min,hour,day,month,year,week,num,flag,flag1,flag2,flag3,Flicker,di,x,h;//时间变量及标志位变量uinttt,tvalue;//变量voidyueri_work(void);//月日显示程序voidnian_work(void);//年显示程序voidShow_pass(uchardss);//不显示程序voidzhou_work(void);//周显示程序voiddelay_18B20(uinti);//温度延时显示程序voidwendu_work(void);//温度显示程序voidshow_work(void);//显示程序voidKEY(void);//按键显示程序sbitRCLK=P0^2;//595输出存储器锁存时钟线/165装载移位控制锁存信号sbitSRCLK=P0^0;//595数据输入时钟线sbitSER=P0^3;//595数据线sbitSO=P0^4;//165数据输出数据线sbitCLK=P0^1;//165时钟信号sbitRST=P0^5;//1302复位引脚,高电平有效sbitIO=P0^6;//1302数据输入输出引脚sbitSCL=P0^7;//1302串行时钟输入,控制数据线的输入输出sbitDQ=P1^0;//18B20数字温度传感器,输入输出口voidDelayms(uintz)//1毫秒1T时钟模式下{uintx,y;for(x=z;x0;x--)for(y=848;y0;y--);}/********************595驱动程序*********************/voidwr595(uchardate)//595写入一个字节{uchari;for(i=0;i8;i++){SRCLK=1;SER=date&0x80;date=1;SRCLK=0;}}voidsend2baty(uchardate1,uchardate2)//写入双字节程序{wr595(date1);wr595(date2);}voidout595(void)//595输出锁存程序{RCLK=0;RCLK=1;}/****************************************************//**************165移位寄存器并转串驱动***************/ucharseries_165(){uchari;ucharBYTE=1;//最终接收到得字符RCLK=0;//将165外部端口数据装入内部寄存器RCLK=1;//抬高为移位准备for(i=0;i8;i++){BYTE=1;//1CLK=1;//时钟低BYTE=BYTE|SO;//先接收高位CLK=0;//时钟高,上升沿下一个数据移出//5}returnBYTE;//返回接收字符}/****************************************************//***************18B20数字传感器驱动程序**************/voiddelay_18B20(uinti)//延时1微秒{i=i*12;//由于我用的是1T51单片机如果用普通51请把这句话屏蔽while(i--);}voidds1820rst(void)//ds1820初始化{ucharx=0;DQ=1;//DQ复位delay_18B20(4);//延时DQ=0;//DQ拉低delay_18B20(100);//精确延时大于480usDQ=1;//拉高delay_18B20(40);}uchards1820rd(void)//读数据{uchari=0;uchardat=0;for(i=8;i0;i--){DQ=0;//给脉冲信号dat=1;DQ=1;//给脉冲信号if(DQ)//如果DQ==1,执行下面语句{dat|=0x80;}delay_18B20(10);}return(dat);}voidds1820wr(ucharwdata)//写数据{uchari=0;for(i=8;i0;i--){DQ=0;DQ=wdata&0x01;delay_18B20(10);DQ=1;wdata=1;}}read_temp(void)//读取温度值并转换{uchara,b;ds1820rst();ds1820wr(0xcc);//跳过读序列号ds1820wr(0x44);//启动温度转换ds1820rst();ds1820wr(0xcc);//跳过读序列号ds1820wr(0xbe);//读取温度a=ds1820rd();b=ds1820rd();tvalue=b*16+a/16;//转换为十进制数returntvalue;}/****************1302实时时钟驱动程序****************/voidwrite_baty(uchardat)//1302写入一个字节{uchari;SCL=0;for(i=0;i8;i++){IO=dat&0x01;//先写入低位SCL=1;SCL=0;dat=1;}}voidwrite_addbaty(ucharaddress,uchardat)//向1302地址写入一个字节的数据{RST=0;SCL=0;RST=1;write_baty(address);write_baty(dat);SCL=1;RST=0;}ucharread_baty(void)//1302读取一个字节{uchari,temp;for(i=0;i8;i++){temp=1;if(IO){temp=temp|0x80;}else{temp=temp&0x7f;}SCL=1;SCL=0;}returntemp;}ucharread_adddaty(ucharaddress)//向1302地址读取一个字节的数据{uchartemp;RST=0;SCL=0;RST=1;write_baty(address);temp=read_baty();SCL=1;RST=0;returntemp;}voidInit_1302time(void)//1302初始化{write_addbaty(0x8e,0x00);write_addbaty(0x80,time_tuf[5]);write_addbaty(0x82,time_tuf[4]);write_addbaty(0x84,time_tuf[3]);write_addbaty(0x86,time_tuf[2]);write_addbaty(0x88,time_tuf[1]);write_addbaty(0x8a,time_tuf[6]);write_addbaty(0x8c,time_tuf[0]);write_addbaty(0x8e,0x80);}voidread_1302time(void)//读1302时间{sec=read_adddaty(0x81);min=read_adddaty(0x83);hour=read_adddaty(0x85);day=read_adddaty(0x87);month=read_adddaty(0x89);week=read_adddaty(0x8b);year=read_adddaty(0x8d);}/****************************************************//********************定时器0程序*********************/voidTimer0Init(void)//2毫秒@11.0592MHz1T时钟模式下{AUXR|=0x80;//定时器时钟1T模式TMOD|=0x01;//设置定时器模式TL0=0x9A;//设置定时初值TH0=0xA9;//设置定时初值TR0=1;//定时器0开始计时ET0=1;//定时器0中断打开EA=1;//总中断打开}voidtimer0()interrupt1using1{TL0=0x9A;//设置定时初值TH0=0xA9;//设置定时初值tt++;if(tt==500){tt=0;x++;if(x==10)//20毫秒自动跳会无按键时显示{x=0;di=0;}}if(tt250){Flicker=0;}else{Flicker=1;}}/********************时间调整程序********************/voidset(ucharsel,ucharsal){ucharaddress,time;ucharmax,min;if(sel==7){address=0x80;max=59;min=0;}//秒if(sel==6){address=0x8a;max=7;min=1;}//星期if(sel==2){address=0x82;max=59;min=0;}//分钟if(sel==1){address=0x84;max=23;min=0;}//小时if(sel==5){address=0x86;max=31;min=1;}//日if(sel==4){address=0x88;max=12;min=1;}//月if(sel==3){address=0x8c;max=99;min=0;}//年time=read_adddaty(address+1)/16*10+read_adddaty(address+1)%16;//时间BCD转换if(sal==0)time++;elsetime--;if(timemax)time=min;if(timemin)time=max;write_addbaty(0x8e,0x00);write_addbaty(address,time/10*16+time%10);write_addbaty(0x8e,0x80);}/**********************显示程序**********************/voidwendu_work(void){send2baty(0x10,0x00);out595();Delayms(2);send2baty(0x08,0x00);out595();Delayms(2);if(tvalue/10==0x00){Show_pass(0x04);}else{send2baty(0x04,duan_ma[tvalue/10]);out595();Delayms(2)