基于单片机的时钟温度显示器制作报告1

合集下载

基于单片机的时钟、温度显示

基于单片机的时钟、温度显示

#include <reg52.h>#include <intrins.h>#define uchar unsigned char#define uint unsigned intsbit rs=P1^0;//寄存器选择sbit rw=P1^1;//读写信号线sbit lcden=P1^2;//led使能端sbit scl=P1^3;//时钟线sbit rst=P1^5;//复位线sbit io=P1^4;//数据口sbit key_set_time=P3^4;//设置时间键sbit key_add=P3^5;//加键sbit key_minus=P3^6;//减键sbit key_set_alarm=P3^7;//设置闹钟键sbit bee=P1^6;//蜂鸣器接口sbit dq=P1^7;//ds18b20测温uchar getTimebuf[7];//存放时间数据uchar time[]={" : : "};//时间格式字符串uchar date[]={"20 --"};//日期格式字符串uchar weeklist[]={"SunMonTueWedThuFriSat"};//星期字符列表uchar week[]={" "};//星期格式字符串int count;//设定秒分时日月星期年的时候count的值分别为1235647 int alarm;//是否进入闹钟设置界面123分别代表开关分小时的设置int isOpen;//闹钟是否开启默认不开启int fen,shi;//闹钟的分钟小时int isRing;//闹钟是否在响uchar isInit_1302;//是否初始化时钟完毕int num;int temperature;//温度int temp_flag;//温度正负标志void delay(uint x){int y;while(x--){for(y=100;y>0;y--);}}void write_1602com(uchar com){//1602写指令rs=0;lcden=0;P2=com;delay(5);lcden=1;delay(5);lcden=0;}void write_1602data(uchar dat){//1602写数据rs=1;lcden=0;P2=dat;delay(5);lcden=1;delay(5);lcden=0;}void init_1602(){//初始化1602液晶rw=0;lcden=0;write_1602com(0x38);//设置显示模式write_1602com(0x0c);//显示开关及光标是否显示和闪动write_1602com(0x06);//光标移动方向write_1602com(0x01);//清屏}void write_ds1302_byte(uchar temp){//ds1302写一个字节数据uchar i;for(i=0;i<8;i++){io=temp&0x01;//将数据放到IO口上scl=0;//scl为低时准备数据scl=1;//上升沿写入temp>>=1;}}void write_ds1302(uchar add,uchar dat){//向地址add写入数据datrst=0;scl=0;rst=1;write_ds1302_byte(add);write_ds1302_byte(dat);scl=1;rst=0;}uchar read_ds1302(uchar add){//ds1302读数据uchar i,dat;rst=0;scl=0;rst=1;write_ds1302_byte(add);//首先写入要读的数据处的地址for(i=0;i<8;i++){if(io==1){dat|=0x80;}scl=1;scl=0;//下降沿读取数据dat>>=1;}scl=1;rst=0;return dat;}void read_time(uchar curr_time[]){uchar i;uchar ucAddr = 0x81;for (i=0;i<7;i++){curr_time[i] = read_ds1302(ucAddr);//格式为: 秒分时日月星期年ucAddr += 2;}}void set_time(uchar *pSecDa){//设定时间uchar i;uchar ucAddr = 0x80;write_ds1302(0x8e,0x00);for(i =7;i>0;i--){write_ds1302(ucAddr,*pSecDa); //秒分时日月星期年pSecDa++;ucAddr+=2;}write_ds1302(0x8e,0x80);}void init_ds1302(){//ds1302初始化isInit_1302=read_ds1302(0x81);//读出时钟状态if(isInit_1302&0x80){//说明没有初始化write_ds1302(0x8e,0x00);//关闭写保护以后一直开着write_ds1302(0x90,0xa5); //辅助电源充电命令一个二极管一个2K电阻write_ds1302(0x80,0x00);//秒CH置0 开启时钟write_ds1302(0x82,0x59);//分write_ds1302(0x84,0x10);//时write_ds1302(0x86,0x07);//日write_ds1302(0x88,0x05);//月write_ds1302(0x8a,0x04);//星期write_ds1302(0x8c,0x14);//年write_ds1302(0x8e,0x80);}}char int_to_char(int temp){//把0到9对应的数字转为字符char x='0';switch(temp){case 0:x='0';break;case 1:x='1';break;case 2:x='2';break;case 3:x='3';break;case 4:x='4';break;case 5:x='5';break;case 6:x='6';break;case 7:x='7';break;case 8:x='8';break;case 9:x='9';break;}return x;}int ds18b20_read_temp();void display(){uchar bai,shi,ge,point,fuhao;read_time(getTimebuf);//时时读取时间time[6]=(getTimebuf[0])/16+48;//格式化时间秒time[7]=(getTimebuf[0])%16+48;time[3]=(getTimebuf[1])/16+48;//格式化时间分time[4]=(getTimebuf[1])%16+48;time[0]=(getTimebuf[2])/16+48;//格式化时间小时time[1]=(getTimebuf[2])%16+48;date[8]=getTimebuf[3]/16+48;//格式化日期日date[9]=getTimebuf[3]%16+48;date[5]=getTimebuf[4]/16+48;//格式化日期月date[6]=getTimebuf[4]%16+48;date[2]=getTimebuf[6]/16+48;//格式化日期年date[3]=getTimebuf[6]%16+48;week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期week[1]=weeklist[(getTimebuf[5]%10)*3+1];week[2]=weeklist[(getTimebuf[5]%10)*3+2];write_1602com(0x80+1);for(num=0;num<10;num++){write_1602data(date[num]);}write_1602data(' ');for(num=0;num<3;num++){write_1602data(week[num]);}write_1602com(0x80+0x40);for(num=0;num<8;num++){write_1602data(time[num]);}//显示温度值write_1602com(0x80+0x40+8);//设置数据指针temperature=ds18b20_read_temp();bai=temperature/1000+0x30;shi=temperature%1000/100+0x30;ge=temperature%100/10+0x30;point=temperature%100%10+0x30;if(temp_flag==1){//说明为正数不显示符号位两种fuhao=0x20;//显示空白if(bai==0x30){bai=0x20;//如果百位为0 不显示if(shi==0x30){shi=0x20;//如果百位为0 十位也为0 都不显示}}write_1602data(fuhao);write_1602data(bai);write_1602data(shi);}else{fuhao=0x2d;//显示负号两种write_1602data(0x20);//因为负数最低到55,所以不显示百位if(shi==0x30){write_1602data(0x20);write_1602data(fuhao);}else{write_1602data(fuhao);write_1602data(shi);}}write_1602data(ge);write_1602data('.');write_1602data(point);write_1602data(0xdf);write_1602data('C');}void display_alarm(uchar add,int dat){//把设定的时分显示出来int x,y;x=dat/10;y=dat%10;write_1602com(add);write_1602data(int_to_char(x));write_1602com(add+1);//防止写后地址自动向后加一光标闪烁看不到write_1602data(int_to_char(y));write_1602com(add+1);}void init_alarm(){//闹钟设置界面只有首次进入才执行uchar code x[]="SET ALARM";uchar i;if(alarm==0){write_1602com(0x01);//清屏write_1602com(0x80+3);//设置数据指针for(i=0;i<9;i++){write_1602data(x[i]);}display_alarm(0x80+0x40+5,shi);//载入闹钟的时分write_1602com(0x80+0x40+7);write_1602data(':');display_alarm(0x80+0x40+8,fen);if(isOpen){//初始化的时候如果已经设定闹钟则显示ONwrite_1602com(0x80+0x40+13);write_1602data(' ');write_1602data('O');write_1602data('N');}else{write_1602com(0x80+0x40+13);write_1602data('O');write_1602data('F');write_1602data('F');}}}void key_scan(){int i;uchar code tips1[]="SET SUCCESS";//闹钟设置成功的提示uchar code tips2[]="CANCEL SUCCESS";//取消闹钟的提示if(key_set_time==0){//检测是否按下delay(10);//消抖if(key_set_time==0){//再次检测是否按下while(!key_set_time);//检测是否松开delay(10);//延时消抖while(!key_set_time);//再次检测是否松开if(alarm==0){//当没有显示闹钟界面时才显示时间设定count++;write_ds1302(0x80,0x80);//让时钟停止if(count==8){//继续走时,说明时间已经设定好了write_1602com(0x0c);//让光标消失write_ds1302(0x80,0);//让时钟继续set_time(getTimebuf);//写入新的时间count=0;return;}switch(count){case 1:write_1602com(0x80+0x40+7);//在秒的位置break;case 2:write_1602com(0x80+0x40+4);//在分的位置break;case 3:write_1602com(0x80+0x40+1);//在时的位置break;case 4:write_1602com(0x80+14);//在星期的位置break;case 5:write_1602com(0x80+10);//在日的位置break;case 6:write_1602com(0x80+7);//在月的位置break;case 7:write_1602com(0x80+4);//在年的位置break;}write_1602com(0x0f);//让光标闪烁}}}if(key_add==0){//检测是否按下delay(10);//消抖if(key_add==0){//再次检测是否按下while(!key_add);//检测是否松开delay(10);//延时消抖while(!key_add);//再次检测是否松开if(count!=0){switch(count){case 1://在秒的位置getTimebuf[0]++;if(getTimebuf[0]==0x5a){getTimebuf[0]=0;}if(getTimebuf[0]==0x4a){getTimebuf[0]=0x50;}if(getTimebuf[0]==0x3a){getTimebuf[0]=0x40;}if(getTimebuf[0]==0x2a){getTimebuf[0]=0x30;}if(getTimebuf[0]==0x1a){getTimebuf[0]=0x20;}getTimebuf[0]=0x10;}time[6]=(getTimebuf[0])/16+48;//格式化时间秒time[7]=(getTimebuf[0])%16+48;write_1602com(0x80+0x40+6);//在秒的位置write_1602data(time[6]);write_1602com(0x80+0x40+7);//在秒的位置write_1602data(time[7]);write_1602com(0x80+0x40+7);//让光标在秒的位置闪烁break;case 2://在分的位置getTimebuf[1]++;if(getTimebuf[1]==0x5a){getTimebuf[1]=0;}if(getTimebuf[1]==0x4a){getTimebuf[1]=0x50;}if(getTimebuf[1]==0x3a){getTimebuf[1]=0x40;}if(getTimebuf[1]==0x2a){getTimebuf[1]=0x30;}if(getTimebuf[1]==0x1a){getTimebuf[1]=0x20;}if(getTimebuf[1]==0x0a){getTimebuf[1]=0x10;}time[3]=(getTimebuf[1])/16+48;//格式化时间分time[4]=(getTimebuf[1])%16+48;write_1602com(0x80+0x40+3);//在分的位置write_1602data(time[3]);write_1602com(0x80+0x40+4);//在分的位置write_1602data(time[4]);write_1602com(0x80+0x40+4);//让光标在分的位置闪烁break;case 3://在时的位置getTimebuf[2]++;if(getTimebuf[2]==0x24){}if(getTimebuf[2]==0x1a){getTimebuf[2]=0x20;}if(getTimebuf[2]==0x0a){getTimebuf[2]=0x10;}time[0]=(getTimebuf[2])/16+48;//格式化时间小时time[1]=(getTimebuf[2])%16+48;write_1602com(0x80+0x40+0);//在小时的位置write_1602data(time[0]);write_1602com(0x80+0x40+1);write_1602data(time[1]);write_1602com(0x80+0x40+1);break;case 4://在星期的位置getTimebuf[5]++;if(getTimebuf[5]==0x08){getTimebuf[5]=0x01;}if((getTimebuf[5]%10)*3==21){//轮完了重新开始week[0]=weeklist[0];week[1]=weeklist[1];week[2]=weeklist[2];}else{week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期week[1]=weeklist[(getTimebuf[5]%10)*3+1];week[2]=weeklist[(getTimebuf[5]%10)*3+2];}write_1602com(0x80+12);write_1602data(week[0]);write_1602com(0x80+13);write_1602data(week[1]);write_1602com(0x80+14);write_1602data(week[2]);write_1602com(0x80+14);break;case 5://在日的位置getTimebuf[3]++;if(getTimebuf[3]==0x32){getTimebuf[3]=0x01;}if(getTimebuf[3]==0x2a){getTimebuf[3]=0x30;}if(getTimebuf[3]==0x1a){getTimebuf[3]=0x20;}if(getTimebuf[3]==0x0a){getTimebuf[3]=0x10;}date[8]=(getTimebuf[3])/16+48;date[9]=(getTimebuf[3])%16+48;write_1602com(0x80+9);write_1602data(date[8]);write_1602com(0x80+10);write_1602data(date[9]);write_1602com(0x80+10);break;case 6://在月的位置getTimebuf[4]++;if(getTimebuf[4]==0x13){getTimebuf[4]=0x01;}if(getTimebuf[4]==0x0a){getTimebuf[4]=0x10;}date[5]=(getTimebuf[4])/16+48;date[6]=(getTimebuf[4])%16+48;write_1602com(0x80+6);write_1602data(date[5]);write_1602com(0x80+7);write_1602data(date[6]);write_1602com(0x80+7);break;case 7://在年的位置getTimebuf[6]++;if(getTimebuf[6]==0x9a){getTimebuf[6]=0x00;}if(getTimebuf[6]==0x8a){getTimebuf[6]=0x90;}if(getTimebuf[6]==0x7a){getTimebuf[6]=0x80;}if(getTimebuf[6]==0x6a){getTimebuf[6]=0x70;}if(getTimebuf[6]==0x5a){getTimebuf[6]=0x60;}if(getTimebuf[6]==0x4a){getTimebuf[6]=0x50;}if(getTimebuf[6]==0x3a){getTimebuf[6]=0x40;}if(getTimebuf[6]==0x2a){getTimebuf[6]=0x30;}if(getTimebuf[6]==0x1a){getTimebuf[6]=0x20;}if(getTimebuf[6]==0x0a){getTimebuf[6]=0x10;}date[2]=(getTimebuf[6])/16+48;date[3]=(getTimebuf[6])%16+48;write_1602com(0x80+3);write_1602data(date[2]);write_1602com(0x80+4);write_1602data(date[3]);write_1602com(0x80+4);break;}}if(alarm!=0){switch(alarm){case 1://调节闹钟的开与关if(isOpen==0){isOpen=1;write_1602com(0x80+0x40+13);write_1602data(' ');write_1602data('O');write_1602data('N');}else{isOpen=0;write_1602com(0x80+0x40+13);write_1602data('O');write_1602data('F');write_1602data('F');}//防止写后地址自动向后加一光标闪烁看不到write_1602com(0x80+0x40+15);break;case 2://调节闹钟的分fen++;if(fen==60){fen=0;}display_alarm(0x80+0x40+8,fen);break;case 3://调节闹钟的小时shi++;if(shi==24){shi=0;}display_alarm(0x80+0x40+5,shi);break;}}}}if(key_minus==0){//检测是否按下delay(10);//消抖if(key_minus==0){//再次检测是否按下while(!key_minus);//检测是否松开delay(10);//延时消抖while(!key_minus);//再次检测是否松开if(count!=0){switch(count){case 1://在秒的位置getTimebuf[0]--;if(getTimebuf[0]==0xff){getTimebuf[0]=0x59;}if(getTimebuf[0]==0x4f){getTimebuf[0]=0x49;}if(getTimebuf[0]==0x3f){getTimebuf[0]=0x39;}if(getTimebuf[0]==0x2f){getTimebuf[0]=0x29;}if(getTimebuf[0]==0x1f){getTimebuf[0]=0x19;}if(getTimebuf[0]==0x0f){getTimebuf[0]=0x09;}time[6]=(getTimebuf[0])/16+48;//格式化时间秒time[7]=(getTimebuf[0])%16+48;write_1602com(0x80+0x40+6);//在秒的位置write_1602data(time[6]);write_1602com(0x80+0x40+7);//在秒的位置write_1602data(time[7]);write_1602com(0x80+0x40+7);//让光标在秒的位置闪烁break;case 2://在分的位置getTimebuf[1]--;if(getTimebuf[1]==0xff){getTimebuf[1]=0x59;}if(getTimebuf[1]==0x4f){getTimebuf[1]=0x49;}if(getTimebuf[1]==0x3f){getTimebuf[1]=0x39;}if(getTimebuf[1]==0x2f){getTimebuf[1]=0x29;}if(getTimebuf[1]==0x1f){getTimebuf[1]=0x19;}if(getTimebuf[1]==0x0f){getTimebuf[1]=0x09;}time[3]=(getTimebuf[1])/16+48;//格式化时间分time[4]=(getTimebuf[1])%16+48;write_1602com(0x80+0x40+3);//在分的位置write_1602data(time[3]);write_1602com(0x80+0x40+4);//在分的位置write_1602data(time[4]);write_1602com(0x80+0x40+4);//让光标在分的位置闪烁break;case 3://在时的位置getTimebuf[2]--;if(getTimebuf[2]==0xff){getTimebuf[2]=0x23;}if(getTimebuf[2]==0x1f){getTimebuf[2]=0x19;}if(getTimebuf[2]==0x0f){getTimebuf[2]=0x09;}time[0]=(getTimebuf[2])/16+48;//格式化时间小时time[1]=(getTimebuf[2])%16+48;write_1602com(0x80+0x40+0);//在小时的位置write_1602data(time[0]);write_1602com(0x80+0x40+1);write_1602data(time[1]);write_1602com(0x80+0x40+1);break;case 4://在星期的位置getTimebuf[5]--;if(getTimebuf[5]==0){getTimebuf[5]=0x07;}if((getTimebuf[5]%10)*3==21){//轮完了重新开始week[0]=weeklist[0];week[1]=weeklist[1];week[2]=weeklist[2];}else{week[0]=weeklist[(getTimebuf[5]%10)*3];//格式化星期week[1]=weeklist[(getTimebuf[5]%10)*3+1];week[2]=weeklist[(getTimebuf[5]%10)*3+2];}write_1602com(0x80+12);write_1602com(0x80+13);write_1602data(week[1]);write_1602com(0x80+14);write_1602data(week[2]);write_1602com(0x80+14);break;case 5://在日的位置getTimebuf[3]--;if(getTimebuf[3]==0){getTimebuf[3]=0x31;}if(getTimebuf[3]==0x2f){getTimebuf[3]=0x29;}if(getTimebuf[3]==0x1f){getTimebuf[3]=0x19;}if(getTimebuf[3]==0x0f){getTimebuf[3]=0x09;}date[8]=(getTimebuf[3])/16+48;date[9]=(getTimebuf[3])%16+48;write_1602com(0x80+9);write_1602data(date[8]);write_1602com(0x80+10);write_1602data(date[9]);write_1602com(0x80+10);break;case 6://在月的位置getTimebuf[4]--;if(getTimebuf[4]==0){getTimebuf[4]=0x12;}if(getTimebuf[4]==0x0f){getTimebuf[4]=0x09;}date[5]=(getTimebuf[4])/16+48;date[6]=(getTimebuf[4])%16+48;write_1602com(0x80+6);write_1602data(date[5]);write_1602com(0x80+7);write_1602com(0x80+7);break;case 7://在年的位置getTimebuf[6]--;if(getTimebuf[6]==0xff){getTimebuf[6]=0x99;}if(getTimebuf[6]==0x8f){getTimebuf[6]=0x89;}if(getTimebuf[6]==0x7f){getTimebuf[6]=0x79;}if(getTimebuf[6]==0x6f){getTimebuf[6]=0x69;}if(getTimebuf[6]==0x5f){getTimebuf[6]=0x59;}if(getTimebuf[6]==0x4f){getTimebuf[6]=0x49;}if(getTimebuf[6]==0x3f){getTimebuf[6]=0x39;}if(getTimebuf[6]==0x2f){getTimebuf[6]=0x29;}if(getTimebuf[6]==0x1f){getTimebuf[6]=0x19;}if(getTimebuf[6]==0x0f){getTimebuf[6]=0x09;}date[2]=(getTimebuf[6])/16+48;date[3]=(getTimebuf[6])%16+48;write_1602com(0x80+3);write_1602data(date[2]);write_1602com(0x80+4);write_1602data(date[3]);write_1602com(0x80+4);break;}}if(alarm!=0){switch(alarm){case 1://调节闹钟的开与关if(isOpen==0){isOpen=1;write_1602com(0x80+0x40+13);write_1602data(' ');write_1602data('O');write_1602data('N');}else{isOpen=0;write_1602com(0x80+0x40+13);write_1602data('O');write_1602data('F');write_1602data('F');}//防止写后地址自动向后加一光标闪烁看不到write_1602com(0x80+0x40+15);break;case 2://调节闹钟的分fen--;if(fen<0){fen=59;}display_alarm(0x80+0x40+8,fen);break;case 3://调节闹钟的小时shi--;if(shi<0){shi=23;}display_alarm(0x80+0x40+5,shi);break;}}}}if(key_set_alarm==0){//检测是否按下delay(10);//消抖if(key_set_alarm==0){//再次检测是否按下while(!key_set_alarm);//检测是否松开delay(10);//延时消抖while(!key_set_alarm);//再次检测是否松开if(count==0){//时间在正常走动的时候才能设置闹钟init_alarm();alarm++;//说明进入闹钟设置界面if(alarm==4){alarm=0;//说明闹钟设置完毕write_1602com(0x01);//清屏以便显示时间write_1602com(0x0c);//关闭光标//显示设置成功或取消的提示if(isOpen){write_1602com(0x80+2);for(i=0;i<11;i++){write_1602data(tips1[i]);}}else{write_1602com(0x80+1);for(i=0;i<14;i++){write_1602data(tips2[i]);}}//延时2ms后清屏显示时间delay(2000);write_1602com(0x01);}else{switch(alarm){case 1:write_1602com(0x80+0x40+15);break;case 2:write_1602com(0x80+0x40+9);break;case 3:write_1602com(0x80+0x40+6);break;}write_1602com(0x0f);}}}}}void beep(){//检测闹钟并且报警if(time[0]==int_to_char(shi/10)&&time[1]==int_to_char(shi%10)&&time[3]==int_to_char(fe n/10)&&time[4]==int_to_char(fen%10)){isRing=1;//闹钟响起,此时如果进入闹钟设置界面改变时分,闹钟就关闭了bee=0;delay(250);bee=1;delay(250);}else{isRing=0;//关闭闹钟或者一分钟后闹钟自动关闭bee=1;}}void delay1(int i){while(i--);}void ds18b20_init(){uchar x=0;dq = 1; //DQ复位delay1(8); //稍做延时dq = 0; //单片机将DQ拉低delay1(80); //精确延时大于480usdq = 1; //拉高总线delay1(14);x=dq; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay1(20);}uchar ds18b20_read(){//读一个字节uchar i=0;uchar dat = 0;for (i=8;i>0;i--){dq = 0; // 给脉冲信号dat>>=1;dq = 1; // 给脉冲信号if(dq)dat|=0x80;delay1(4);}return(dat);}void ds18b20_write(char dat){//写一个字节uchar i=0;for (i=8; i>0; i--){dq = 0;dq = dat&0x01;delay1(5);dq = 1;dat>>=1;}}int ds18b20_read_temp(){//读取温度uchar low;uchar high;unsigned long tmp;float value;int t;//温度ds18b20_init();ds18b20_write(0xCC); //跳过读序列号的操作ds18b20_write(0x44); //启动温度转换ds18b20_init();ds18b20_write(0xCC); //跳过读序列号的操作ds18b20_write(0xBE); //读取温度寄存器共九个前两个代表温度low=ds18b20_read();//低八位数据high=ds18b20_read();//高八位数据tmp=high;tmp<<=8;tmp=tmp|low;//此处有正负之分if(tmp>=63488){//ffff f000 0000 0000-->(f800)temp_flag=0;//8位全为1时,加1才进位if((~low)==0xff){//判断low取反加1之后是否进位high=(~high)+1;low=0;}else{high=~high;low=(~low)+1;}tmp=high*256+low;}else{temp_flag=1;}value=tmp*0.0625;t=value*10+((temp_flag==1)?+0.5:-0.5);//放大十倍输出并四舍五入return t;}void main(){init_1602();init_ds1302();while(1){if(isOpen){//只有开启闹钟的时候才检测beep();//不断检测闹钟}key_scan();if(count==0&&alarm==0){//没有设定时间也没有在闹钟界面的时候时间才显示display();}}}。

基于单片机的具备温度显示的数字时钟设计

基于单片机的具备温度显示的数字时钟设计

研究探讨1. 绪论时代的进步和发展的迅速崛起,单片机技术在生活工作、科研等各个领域已经引起了人们的广泛关注,现在已经是一种比较成熟的技术。

单片机主控芯片可控制数字温度计和数字钟,数字温度计属于功能较多的温度计,可以设置任意温度的上下限,而且还具有报警功能,当温度不在设定范围内时,也可以报警;数字钟可以同步显示时间日历,日期和时间,这些都可以通过按键进行调整。

本文所论述的系统采用的DS1302可为掉电保护电源提供可编程的充电功能,并且可以关闭充电功能。

系统显示部分可用LCD液晶显示屏显示,工作方便,外表美观。

2. 系统组成数字温度计和数字时钟电路的总体设计方框图如图所示:2.1主控制模块主控制模块采用单片机AT89S51,AT89S51是由P0,P1,P2,P3四个通用8位I/O口 以及中断控制口,复位,写选通,接地,电源等引脚组成,其中,P0口是地址/数据总线复用口,P1口是一个含有上拉电阻的双向的I/O口,在校验程序中接收低8位地址,P2口与P1口的区别是在校验程序中接收高八位地址,P3口除了一般I/O口的功能外,还具有第二功能,这是其他I/O所不具有的功能,中断控制口可以控制中断的优先级。

AT89S51内部图如下:2.2温度传感器DS18B20温度传感器DS18B20包括温度传感器,高温触发器TH,低温触发器TL,配置寄存器,以及8位CRC发生器。

DS18B20具有单线接口的优点,一个端口引脚就可以进行通信,而且多个DS18B20可以并联在三线上,多点组网功能就可以得以实现;用户同时还可以根据自己的要求进行报警设置,设计起来十分方便。

DS18B20具有很多优点,例如像耐碰耐磨,小体积,方便使用,封装形式多样化等优点。

DS18B20内部结构框图如下图所示:2.3液晶显示屏LCD1602液晶显示器的优点有很多,功耗微小、小体积、内容显示丰富、轻巧超薄等都是它明显的优势,很多地方都开始了对其越来越多的使用。

基于单片机的带温度显示的数字钟设计(c51语言编程)【开题报告】

基于单片机的带温度显示的数字钟设计(c51语言编程)【开题报告】

开题报告电气工程及其自动化基于单片机的带温度显示的数字钟设计(c51语言编程)一、课题研究意义及现状1980年因特尔公司推出了MCS-51单片机,近30年来,其衍生系列不断出现,从Atmel加入FLASH ROM,到philips加入各种外设,再到后来的Cygnal推出C8051F,使得以8051为核心的单片机在各个发展阶段的低端产品应用中始终扮演着一个重要的角色,其地位不断升高,资源越来越丰富,历经30年仍在生机勃勃地发展,甚至在SoC时代仍占有重要的一席之地。

单片机具有体积小、功能强、低功耗、可靠性高、价格低廉等一系列优点,不仅已成为工业测控领域智能仪表、机电一体化、实时控制、国防工业普遍采用的智能化控制工具,而且已渗入到人们工作和和生活的各个角落,有力地推动了各行业的技术改造和产品的更新换代,应用前景广阔。

C语言已经成为当前举世公认的高效简洁而又贴近硬件的编程语言之一。

将C语言向单片机8051上移植十余20世纪80年代的中后期,经过几十年的努力,C语言已成为专业化单片机上的实用高级语言。

C语言是一种编译型程序设计语言,它兼顾了多种高级语言的特点,并具备汇编语言的功能。

此外,C语言程序具有完善的模块程序结构,从而为软件开发中采用模块化程序设计方法提供了有力的保障。

与汇编语言相比,C51在功能、结构、可读性、可维护性上有明显的优势,因而易学易用。

另外C51可以缩短开发周期,降低成本,可靠性,可移植性好。

因此,使用C语言进行程序设计已成为软件开发的一个主流,用C语言进行8051单片机程序设计是单片机开发与应用的必然趋势。

随着人们生活水平的提高,对物质需求也越来越高,人们已不再满足于钟表原先简单的报时功能,希望出现一些新的功能,诸如环境温度显示、日历的显示、重要日期倒计时、显示跑表功能等,用以带来更大的方便。

而所有这些,又都是以数字化的电子时钟为基础的,不仅应用了数字电路技术,而且还加入了需要模拟电路技术和单片机技术。

单片机电子时钟课程设计实验报告(1)

单片机电子时钟课程设计实验报告(1)

单片机电子时钟课程设计实验报告(1)单片机电子时钟课程设计实验报告一、实验内容本次实验的主要内容是使用单片机设计一个电子时钟,通过编程控制单片机,实现时钟的显示、报时、闹钟等功能。

二、实验步骤1.硬件设计根据实验要求,搭建电子时钟的硬件电路,包括单片机、时钟模块、显示模块、按键模块等。

2.软件设计通过C语言编写单片机程序,用于实现时钟功能。

3.程序实现(1)时钟显示功能通过读取时钟模块的时间信息,在显示模块上显示当前时间。

(2)报时功能设置定时器,在每个整点时,通过发出对应的蜂鸣声,提示时间到达整点。

(3)闹钟功能设置闹钟时间和闹铃时间,在闹钟时间到达时,发出提示蜂鸣,并在屏幕上显示“闹钟时间到了”。

(4)时间设置功能通过按键模块实现时间的设置,包括设置小时数、分钟数、秒数等。

(5)年月日设置功能通过按键模块实现年月日的设置,包括设置年份、月份、日期等。

三、实验结果经过调试,电子时钟的各项功能都能够正常实现。

在运行过程中,时钟能够准确、稳定地显示当前时间,并在整点时提示时间到达整点。

在设定的闹铃时间到达时,能够发出提示蜂鸣,并在屏幕上显示“闹钟时间到了”。

同时,在需要设置时间和年月日信息时,也能够通过按键进行相应的设置操作。

四、实验感悟通过本次实验,我深刻体会到了单片机在电子设备中的广泛应用以及C 语言在程序设计中的重要性。

通过实验,我不仅掌握了单片机的硬件设计与编程技术,还学会了在设计电子设备时,应重视系统的稳定性与可靠性,并善于寻找调试过程中的问题并解决。

在今后的学习和工作中,我将继续加强对单片机及其应用的学习与掌握,努力提升自己的实践能力,为未来的科研与工作做好充分准备。

单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码..

单片机课程设计实验报告 基于单片机的数字时钟 含完整实验代码..

单片机课程设计报告基于单片机的数字时钟姓名:班级:学号:一、前言利用实验板上的4个LED数码管,设计带有闹铃、秒表功能的数字时钟。

功能要求:a)计时并显示(LED)。

由于实验板上只有4位数码管,可设计成显示“时分”和显示“分秒”并可切换。

b)时间调整功能。

利用4个独立按钮,实现时钟调整功能。

这4个按钮的功能为工作模式切换按钮(MODE),数字加(INC),数字减(DEC)和数字移位(SHITF)。

c)定闹功能。

利用4个独立按钮设定闹钟时间,时间到以蜂鸣器响、继电器动作作为闹铃。

d)秒表功能。

最小时间单位0.01秒。

二、硬件原理分析1.电源部分电源部份采用两种输入接口(如上图)。

a)外电源供电,采用2.1电源座,可接入电源DC5V,经单向保护D1接入开关S1。

b)USB供电,USB供电口输入电源也经D1单向保护,送到开关S1。

注:两路电源输入是并连的,因此只选择一路就可以了,以免出问题。

S1为板子工作电源开关,按下后接通电源,提供VCC给板子各功能电路。

电路采用两个滤波电容,给板子一个更加稳定的工作电源。

LED为电源的指示灯,通电后LED灯亮。

2.蜂鸣器蜂鸣器分为有源和无源两种,有源即两引脚有一个直流电源就可以长鸣,无源则需要一个1K左右的脉冲才可以蜂鸣,因此对于按键的提示音及报警蜂鸣使用有源来得方便。

有源也可以当无源使用,而无源则不能当有源使用,当然用有源蜂鸣器作音乐发声会失真厉害。

如上图:单片机P15输出高低电平经R21连接三极管B极,控制三极管的导通与截止,从而控制蜂鸣器的工作。

低电平时三极管导通,蜂鸣器得电蜂鸣,高电平时三极管截止,蜂鸣器失电关闭蜂鸣。

电路使用一个四位共阳型数码管,四个公共阳级由三极管放大电流来驱动,三极管由P10-P13控制开与关。

数码管的阴级由P0口经过电阻限流连接。

例如,要十位的数码管工作,P12输出0,使三极管Q12导通,8脚得电,当P0口相应位有输出0时,点亮相应的LED灯组合各种字符数字。

基于单片机的电子时钟设计报告(LCD显示)

基于单片机的电子时钟设计报告(LCD显示)

单片机原理及应用课程设计任务书题目:电子时钟(LCD显示)1、设计要求以AT89C51单片机为核心的时钟,在LCD显示器上显示当前的时间:使用字符型LCD显示器显示当前时间。

显示格式为“时时:分分:秒秒”。

用3个功能键操作来设置当前时间。

功能键K1~K4功能下。

K1—设置小时。

K2—设置分钟。

K3—设置秒。

程序执行后工作指示灯LED发光,表示程序开始执行,LCD显示“23:59:00”,然后开始计时。

2、工作原理本课题难点在于键盘的指令输入,由于每个按键都具有相应的一种功能,程序中有较多的循环结构用以判断按键是否按下,以及判断按键是否抬起,以及LCD显示器的初始化。

3、参考电路硬件设计电路图如下图所示:硬件电路原理图单片机原理及应用课程设计任务书题目:电子时钟(LCD显示)1、设计要求以AT89C51单片机为核心的时钟,在LCD显示器上显示当前的时间:使用字符型LCD显示器显示当前时间。

显示格式为“时时:分分:秒秒”。

用3个功能键操作来设置当前时间。

功能键K1~K4功能下。

K1—设置小时。

K2—设置分钟。

K3—设置秒。

程序执行后工作指示灯LED发光,表示程序开始执行,LCD显示“23:59:00”,然后开始计时。

2、工作原理本课题难点在于键盘的指令输入,由于每个按键都具有相应的一种功能,程序中有较多的循环结构用以判断按键是否按下,以及判断按键是否抬起,以及LCD显示器的初始化。

3、参考电路硬件设计电路图如下图所示:硬件电路原理图基于AT89C51单片机的电子时钟设计报告一、设计要求与目的1)设计要求以AT89C51单片机为核心的时钟,在LCD显示器上显示当前的时间。

2)、使用字符型LCD显示器显示当前时间。

显示格式为“时时:分分:秒秒”。

3)、用3个功能键操作来设置当前时间。

4)、熟悉掌握proteus编成软件以及keil软件的使用二、本设计原理本设计以AT89C51单片机为核心,通过时钟程序的编写,并在LCD显示器上显示出来。

基于单片机的电子时钟设计(带定时功能和温度显示)

基于单片机的电子时钟设计(带定时功能和温度显示)

基于单片机的电子时钟设计——带定时功能和温度显示班级: 11级质量2班学号: 1110132217姓名: 詹超专业: 产品质量指导老师: 王正家二零一四年六月摘要传统的数字电子时钟采用了较多的分立元器件,不仅占用了很大的空间而且利用率也比很低,随着系统设计复杂度的不断提高,用传统时钟系统设计方法很难满足设计需求。

单片机是集CPU、RAM、ROM、定时器/计数器和多种接口于一体的微控制器。

它体积小、成本低、功能强,广泛应用于智能产品和工业自动化上。

而51系列的单片机是各单片机中最为典型和最有代表性的一种。

,本次设计提出了系统总体设计方案,并设计了各部分硬件模块和软件流程,在用C语言设计了具体软件程序后,将各个模块完全编译通过过后,结果证明了该设计系统的可行性。

该设计给出了以AT89C51为核心,利用单片机的运算和控制功能,并采用系统化LED显示模块实时显示数字的设计方案,适当地解决了实际生产和日常生活中对计时高精确度的要求,因此该设计在现代社会中具有广泛的应用性。

关键词:电子时钟,单片机,C语言。

AbstractConventional digital electronic clock USES more discrete component, not only takes up a lot of space but also utilization ratio is low, with the constant improvement of the system design complexity, usingtraditional clock system design method is difficult to meet the design requirements.SCM is a set of CPU, RAM, ROM and timer/counter and a variety of interface in the integration of micro controller. Small volume, low cost, strong function, it is widely used in intelligent products andindustrial automation. And 51 series microcontroller is the single chip microcomputer in one of the most typical and most representative. , the design put forward the system overall design scheme, and designs the hardware modules and software process, the parts after using C language design a specific software program, the various modules after fully compiled through, the results proved the feasibility of the design system.This design USES AT89C51 as the nucleus is presented, the calculation and control function of microcontroller, and USES the systematic design of real-time display of digital LED display module, appropriate solutions to the practical production and daily life to therequirement of high precision timing, therefore the design has wide application in the modern society.Keywords: Electronic clock, SCM, C language。

基于单片机上实现的数字温度计设计报告

基于单片机上实现的数字温度计设计报告

摘要本系统以AT89S52为核心,选用符合测量温度范围要求的DS18B20单总线数字温度传感器,DS1302串行时钟芯片,RT1602液晶显示器实现液晶显示当前日期、时间、星期和温度。

当测量温度超过设定的温度上下限时,启动蜂鸣器和指示灯报警。

温度显示稳定,且温度测量误差≤±1℃,温度值小数部分保留两位有效数字。

增加了摄氏温度与华氏温度转换对比显示功能,设定了整点语音自动播报时间温度,手动实时播报时间温度功能。

AbstractBased on the microintrollers,AT89S52, the system is composed of single bus temperature sensor DS18B20, serial clock chip DS1302 and liquid crystal display rt1602,which can display current date, time, week and temperature. Beep and indicating led are run when the measuring temperature is out of the range of the setting temperature. The system can display temperature stably, and the measuring error is less than and equal to ±1℃. It remains the two Significant digit after the decimal point. The system extends the functions of conversion of Celsius Temperature And Fahrenheit temperature,Announcing on schedule temperature、real time with voice automatically and the Manual Announcing temperature、real time.一、方案选择与论证根据竞赛设计任务的总体要求,本系统可以划分为以下个基本模块,针对各个模块1的功能要求,分别有以下一些不同的设计方案:1、温度传感器模块方案一:采用热敏电阻,热敏电阻精度、重复性、可靠性较差,对于检测1摄氏度的信号是不适用的,也不能满足测量范围。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

基于单片机的时钟温度显示器制作报告班级:电子信息工程1003班姓名:刘洋一:方案1:采用STC89C52单片机便于硬件扩展。

2:采用LCD1602液晶显示。

3:采用DS12C887时钟芯片。

4:采用DS18B20温度传感器。

5:采用直流电源供电。

因知识水平有限,所以直接采用5.5V直流电源供电。

6:安装有电池仓,可用两节CR2302电池供电。

二:主要元件简介1:1602LCD:标准字符型液晶显示模块(LCM),采用点阵型液晶显示器(LCD),可显示16个字符X2行西文字符,字符尺寸为,内置HD44780及兼容芯片接口型液晶显示控制器,可与单片机直接连接,广泛应用于各类仪器仪表及电子设备。

2:DS12C887实时时钟芯片功能丰富,可以用来直接代替IBM PC上的时钟日历芯片DS12887,同时,它的管脚也和MC146818B、DS12887相兼容。

由于DS12C887能够自动产生世纪、年、月、日、时、分、秒等时间信息,其内部又增加了世纪寄存器,从而利用硬件电路解决子“千年”问题;DS12C887中自带有锂电池,外部掉电时,其内部时间信息还能够保持10年之久;对于一天内的时间记录,有12小时制和24小时制两种模式。

在12小时制模式中,用AM和PM区分上午和下午;时间的表示方法也有两种,一种用二进制数表示,一种是用BCD码表示;DS12C887中带有128字节RAM,其中有11字节RAM用来存储时间信息,4字节RAM用来存储DS12C887的控制信息,称为控制寄存器,113字节通用RAM使用户使用;此外用户还可对DS12C887进行编程以实现多种方波输出,并对其内部的三路中断通过软件进行屏蔽。

3:TS-18B20数字温度传感器,采用DALLAS公司生产的DS18B20可组网数字温度传感器芯片封装而成,具有耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。

3.1 独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。

3.2 测温范围-55℃~+125℃,固有测温分辨率0.5℃。

3.3 支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定,实现多点测温3.4 工作电源: 3~5V/DC3.5 在使用中不需要任何外围元件3.6 测量结果以9~12位数字量方式串行传送3.7 适用于DN15~25, DN40~DN250各种介质工业管道和狭小空间设备测温3.8 PVC电缆直接出线或德式球型接线盒出线,便于与其它电器设备连接。

三:设计1:电子线路:用导线与锡条手工焊制,略显粗陋。

2:程序设计:#include <reg52.h>#include <stdio.h>#define uchar unsigned char#define uint unsigned intsbit lcdrs=P2^4;//液晶控制sbit lcden=P2^6;sbit lcdrr=P2^5;sbit wen=P3^6;//温度按键sbit led=P3^7;sbit s1=P1^0;//按键sbit s2=P1^1;sbit s3=P1^2;sbit s4=P1^3;sbit dscs=P1^4;//时钟控制sbit dsas=P1^5;sbit dsrw=P1^6;sbit dsds=P1^7;sbit dsirq=P3^3;sbit ds=P3^1;//温度数据传输口bit flag1,flag_ri,flag2;uchar year,month,week,day,shi,fen,miao,amiao,ashi,afen,str[6],flag_get,strt[]="Temperature"; uchar count,s1num,flag,t0_num;uint temp;int num,j;void delay(int z)//延时1ms函数{int x,y;for(x=z;x>0;x--)for(y=0;y<110;y++);}void shan(){led=1;delay(50);led=0;}void write_com(char com)//液晶写指令{lcdrs=0;P0=com;delay(5);lcden=1;delay(5);lcden=0;}void write_date(char date)//液晶写数据{lcdrs=1;P0=date;delay(5);lcden=1;delay(5);lcden=0;}void write_ds(uchar add,uchar date)//写时钟芯片数据{dscs=0;dsas=1;dsds=1;dsrw=1;P0=add;dsas=0;P0=0xff;dsrw=0;P0=date;dsrw=1;dsas=1;dscs=1;}uchar read_ds(uchar add)//读取时钟芯片数据{uchar ds_date;dsas=1;dsds=1;dsrw=1;dscs=0;P0=add;dsas=0;dsds=0;P0=0xff;ds_date=P0;dsds=1;dscs=1;return ds_date;}void inittem(void)//温度芯片初始化{ds = 1;delay1(8);ds = 0;delay1(80);ds = 1;delay1(20);}void writeone(uchar dat)//温度写一个字节{uchar i=0;for(i=8;i>0;i--){ds = 0;ds = dat&0x01;delay1(5);ds = 1;dat>>=1;}delay1(5);}uchar readone()//温度读一个字节{uchar i=0;uchar dat = 0;for (i=8;i>0;i--){ds = 0;dat>>=1;ds = 1;if(ds)dat|=0x80;delay1(5);}return(dat);}uint readtem(void)//读取温度数据{uchar a=0;uint b=0;uint t=0;inittem();writeone(0xCC);writeone(0x44);delay1(200);inittem();writeone(0xCC);writeone(0xBE);a=readone();b=readone();b<<=8;t=a+b;return t;}void jisuan()//转换原始温度数据为十进制数{uchar TempH,TempL;temp=readtem();if(temp&0x8000){str[0]='-';temp=~temp;temp+=1;}elsestr[0]='+';TempH=temp>>4;TempL=temp&0x0F;TempL=TempL*6/10;flag_get=0;str[1]=(TempH%100)/10+0x30; //储存在数组中str[2]=TempH%10+0x30;str[3]='.';str[4]=TempL+0x30;str[5]='C';}void init()//中断、液晶、数据初始化{write_ds(1,0);EA=1;EX1=1;IT1=1;flag1=0;t0_num=0;s1num=0;week=1;lcden=0;lcdrs=0;lcdrr=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80+0x40+6);write_date(':');write_com(0x80+0x40+9);write_date(':');write_com(0x80);write_date('2');write_date('0');}void write_tem()//液晶显示温度函数{int i;jisuan();write_com(0x80+0x40+6);for(i=0;i<6;i++)write_date(str[i]);//直接使用存在数组中的温度数据}void write_sfm(char add,char date) //液晶显示时分秒函数{char shi,ge;shi=date/10;ge=date%10;write_com(0x80+0x40+add);write_date(0x30+shi);write_date(0x30+ge);}void write_nyr(char add,char date) //液晶显示年月日函数(与时分秒不在一行,所以分开方便控制){char shi,ge;shi=date/10;ge=date%10;write_com(0x80+add);write_date(0x30+shi);write_date(0x30+ge);}void write_week(char w) //液晶显示星期函数(与年月日等显示方式不同){int i;char week[7][3]={"MON","TUE","WEN","THU","FRI","SAT","SUN"};write_com(0x80+13);for(i=0;i<3;i++){write_date(week[w-1][i]);delay(5);}}void read_alarm()//从时钟芯片中读取闹钟数据{amiao=read_ds(1);afen=read_ds(3);ashi=read_ds(5);}void keyscan()//键盘扫描{if(flag_ri==1){if((s1==0)||(s2==0)||(s3==0)||(s4==0))//随意按键闹钟结束提示{delay(5);if((s1==0)||(s2==0)||(s3==0)||(s4==0)){while(!(s1&&s2&&s3&&s4));shan();}}}if(s1==0){delay(5);if(s1==0)//功能键按下后停止液晶刷新{s1num++;if(flag1==1&&s1num==4)s1num=1;//调整闹钟时只在时分秒处闪烁flag=1; //功能键按下后停止液晶刷新while(s1==0);shan();//指示灯提示按下if(s1num==1){write_com(0x0f);write_com(0x80+0x40+11);}else if(s1num==2){write_com(0x80+0x40+8);}else if(s1num==3){write_com(0x80+0x40+5);}else if(s1num==4){write_com(0x80+15);}else if(s1num==5){write_com(0x80+9);}else if(s1num==6){write_com(0x80+6);}else if(s1num==7){write_com(0x80+3);}else{s1num=0;flag=0;write_ds(0,miao);//调整完毕后储存在时钟芯片内write_ds(2,fen);write_ds(4,shi);write_ds(6,week);write_ds(7,day);write_ds(8,month);write_ds(9,year);write_com(0x0c);}}}if(s1num!=0)//只有功能键按下后还能调整时间{if(s2==0)//加一{delay(5);if(s2==0){shan();while(s2==0);if(s1num==1){miao++;if(miao>=60)miao=0;write_sfm(10,miao);write_com(0x80+0x40+11);}if(s1num==2){fen++;if(fen>=60)fen=0;write_sfm(7,fen);文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.write_com(0x80+0x40+8);}if(s1num==3){shi++;if(shi>=24)shi=0;write_sfm(4,shi);write_com(0x80+0x40+5);}if(s1num==4){week++;if(week>7)week=1;write_week(week);write_com(0x80+15);}if(s1num==5){day++;if(day>31)day=1;write_nyr(8,day);write_com(0x80+9);}if(s1num==6){month++;if(month>12)month=1;write_nyr(5,month);write_com(0x80+6);}if(s1num==7){year++;if(year>=100)year=0;write_nyr(2,year);write_com(0x80+3);}}}if(s3==0)//减一{delay(5);if(s3==0){shan();while(s3==0);if(s1num==1){miao--;if(miao==-1)miao=59;write_sfm(10,miao);write_com(0x80+0x40+11);}if(s1num==2){fen--;if(fen==-1)fen=59;write_sfm(7,fen);write_com(0x80+0x40+8);}if(s1num==3){shi--;if(shi==-1)shi=23;write_sfm(4,shi);write_com(0x80+0x40+5);}if(s1num==4){week--;if(week==0)week=7;write_week(week);write_com(0x80+15);}if(s1num==5){day--;if(day==0)day=31;write_nyr(8,day);write_com(0x80+9);}if(s1num==6){month--;if(month==0)month=12;write_nyr(5,month);write_com(0x80+6);}if(s1num==7){year--;if(year==-1)year=99;write_nyr(2,year);write_com(0x80+3);}}}}if(s4==0&&s1num==0)//调整闹钟按键,只有在功能键没按下时才能调整{delay(5);if(s4==0&&s1num==0){flag1=~flag1;shan();while(s4==0);if(flag1==0){flag=0;write_com(0x80+0x40);write_date(' ');write_date(' ');write_date(' ');write_date(' ');write_com(0x0c);write_ds(1,miao);write_ds(3,fen);write_ds(5,shi);}else{read_alarm();miao=amiao;fen=afen;shi=ashi;write_com(0x80+0x40);write_date('R');write_date('I');write_date('N');write_date('G');write_sfm(4,shi);write_sfm(7,fen);write_sfm(10,miao);}}}if(wen==0&&s1num==0)//显示温度按键,只有在功能键没按下时才能显示{delay(5);if(wen==0&&s1num==0){flag2=~flag2;shan();while(wen==0);if(flag2==1){write_com(0x01);delay(5);write_com(0x80+1);for(j=0;j<11;j++)write_date(strt[j]);write_tem();}if(flag2==0){write_com(0x01);delay(5);write_com(0x80+0x40+6);write_date(':');write_com(0x80+0x40+9);write_date(':');write_com(0x80);write_date('2');write_date('0');}}}}void main()//主函数{int i;init();while(1){keyscan();//不停进行键盘扫描if(flag2==1)//按下温度显示键后显示温度{for(i=10;i>0;i--){write_tem();}}文档来源为:从网络收集整理.word版本可编辑.欢迎下载支持.if(flag_ri==1)//闹铃中断后指示灯提示{shan();delay(100);shan();delay(500);}if(flag2==0&&flag==0&&flag1==0)//在没调整时间、闹铃,没显示温度的时候显示时间{ keyscan();year=read_ds(9);month=read_ds(8);keyscan();day=read_ds(7);week=read_ds(6);keyscan();//增加扫描次数减少卡顿感shi=read_ds(4);fen=read_ds(2);miao=read_ds(0);keyscan();write_sfm(10,miao);write_sfm(7,fen);write_sfm(4,shi);write_nyr(2,year);keyscan();write_nyr(5,month);write_nyr(8,day);write_week(week);} keyscan();} keyscan();}void exter() interrupt 2 //时钟芯片发起的闹铃外部中断{uchar c;flag_ri=1;c=read_ds(0x0c);}void tim(void) interrupt 1 //内部中断,定时读取温度数据{TH0=0xef;TL0=0xf0;num++;if(num==50){num=0;flag_get=1;}}四:电路图1:单片机电路2:LCD1602电路3:DS12C887电路4:DS18B20电路五:安装调试电路板上共有六个按键。

相关文档
最新文档