#include
#define uchar unsigned char
#define uint unsigned int
sbit lcdws=P2^1; //1602管脚定义
sbit lcden=P2^0;
sbit lcdrs=P2^2;
sbit key1=P2^3; //闹钟设置键
sbit key2=P2^4;
sbit key3=P1^5;//功能键定义
sbit key4=P1^6;//增大键定义
sbit key5=P1^7;//减小键定义
uchar shi,fen,miao,ashi,afen,amiao,year,month,day,week; uchar s1num=0,s1num2=0,temp;
bit flag;
float f_temp;
uint i,d;
uchar code table2[]={0x20,0x20,0x2e,0x20,0xdf,0x43};
uchar code table[]="20 - - ";
uchar code table1[]=" : : ";
sbit ds=P1^0;//ds18b20信号线
sbit beep=P1^4; //蜂鸣器管脚定义
sbit ACC_7 = ACC^7; //位寻址寄存器定义
sbit SCLK = P1^2; // DS1302时钟信号sbit DIO= P1^1; // DS1302数据信号sbit CE = P1^3;
//地址、数据发送子程序
//void delay2(uint ms)
// {
// uchar t;
// while(ms--); for(t=0;t<120;t++);
//}
// void playmusic()
// {
// uint i2=0,j2,k2;
// while(jiepai[i2]!=0||song[i2]!=0)
// {
// for(j2=0;j2 // { // beep=~beep; // for(k2=0;k2 // } // delay2(10); // i2++; // } // } void write_1302( uchar addr,uchar dat ) { uchar i,temp; CE=0; //CE 引脚为低,数据传送中止 SCLK=0; //清零时钟总线 CE = 1; //CE 引脚为高,逻辑控制有效 //发送地址 for ( i=8; i>0; i-- ) //循环8次移位 { SCLK = 0; temp = addr; DIO = (bit)(temp&0x01); //每次传输低字节 addr >>= 1; //右移一位 SCLK = 1; } //发送数据 for ( i=8; i>0; i-- ) { SCLK = 0; temp = dat; DIO = (bit)(temp&0x01); dat >>= 1; SCLK = 1; } CE = 0; } //数据读取子程序 uchar Read1302 ( uchar addr ) { unsigned char i,temp,dat1,dat2; CE=0; SCLK=0; CE = 1; //发送地址 for ( i=8; i>0; i-- ) //循环8次移位 { SCLK = 0; temp = addr; DIO = (bit)(temp&0x01); //每次传输低字节 addr >>= 1; //右移一位 SCLK = 1; //读取数据 for ( i=8; i>0; i-- ) { ACC_7=DIO; SCLK = 1; ACC>>=1; SCLK = 0; } CE=0; dat1=ACC; dat2=dat1/16; //数据进制转换 //十六进制转十进制 dat1=dat1%16; dat1=dat1+dat2*10; return (dat1); } //初始化DS1302 void Initial(void) //初始化1302 2010年09月30日23点58分56秒星期一{ write_1302 (0x8e,0x00); //允许写保护 write_1302 (0x80,0x56); //秒位初始化 write_1302 (0x82,0x58); //分钟初始化 write_1302 (0x84,0x23); //小时初始化 write_1302 (0x86,0x30); //日初始化 write_1302 (0x88,0x09); //月初始化 write_1302 (0x8c,0x10); //年初始化 write_1302 (0x8a,0x01); //日期始化 write_1302 (0x8e,0x80); //禁止写保护 } void delay(uint z)//延时1ms { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void write_com(uchar com)//1602写命令 { lcdrs=0; lcden=0; P0=com; delay(5); lcden=1; lcden=0; } void write_data(uchar date)//1602写数据 { lcdrs=1; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } void dsreset(void) //DS18B20,初始化函数{ uint i; ds=0; i=103; while(i>0)i--; ds=1; i=4; while(i>0)i--; } bit tempreadbit(void)//读1位数据函数 { uint i; bit dat; ds=0;i++; ds=1;i++;i++;//i++起到延时作用 dat=ds; i=8;while(i>0)i--; return(dat); } uchar tempread(void) //读一个字节数据函数{ uchar i,j,dat; dat=0; for(i=1;i<=8;i++) { j=tempreadbit(); dat=(j<<7)|(dat>>1); } return(dat); } void tempwritebyte(uchar dat) //向DS18B20写一个字节数据函数{ uint i; uchar j; bit testb; for(j=1;j<=8;j++) { testb=dat&0x01; dat=dat>>1; if(testb)//写1 { ds=0; i++;i++; ds=1; i=8;while(i>0)i--; } else { ds=0; //写0 i=8;while(i>0)i--; ds=1; i++;i++; } } } void tempchange(void) //DS18B20开始获取温度并转换 { dsreset(); delay(1); tempwritebyte(0xcc); tempwritebyte(0x44); } uint get_temp() //获取温度 { uchar a,b; dsreset(); delay(1); tempwritebyte(0xcc); tempwritebyte(0xbe); a=tempread(); //读高8位 b=tempread(); //读低8位 temp=b; temp<<=8; //两个字节组合成1个字节 temp=temp|a; f_temp=temp*0.0625; temp=f_temp*10+0.5; f_temp=f_temp+0.05; //温度在寄存器中为12位,分辨率为0.0625^ return temp; } void display(uchar addr,uchar dat) { write_com(0x80+0x40+addr); write_data(0x30+dat); delay(5); } void dis_temp(uint t) { uchar i; i=t/100; display(10,i); i=t%100/10; display(11,i); i=t%100%10; display(13,i); } void init()//初始化程序 { uchar num; flag=1; lcden=0; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); for(num=0;num<15;num++) { write_data(table[num]); delay(5); } write_com(0x80+0x40); for(num=0;num<8;num++) { write_data(table1[num]); delay(5); } write_com(0x80+0x40+10); for(num=0;num<6;num++) { write_data(table2[num]); delay(10); } } void di()//蜂鸣器响函数 { beep=0; delay(100); beep=1; } void write_sfm(uchar add,uchar date) { uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+0x40+add); write_data(0x30+shi); write_data(0x30+ge); } void write_nyrz(uchar add,uchar date)//显示年,月,日,周{ uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+add); write_data(0x30+shi); write_data(0x30+ge); } void display_week(uchar we) { write_com(0x80+12); switch(we) { case 1: write_data('M');delay(5); write_data('O');delay(5); write_data('N'); break; case 2: write_data('T');delay(5); write_data('U');delay(5); write_data('E'); break; case 3: write_data('W');delay(5); write_data('E');delay(5); write_data('D'); break; case 4: write_data('T');delay(5); write_data('H');delay(5); write_data('U'); break; case 5: write_data('F');delay(5); write_data('R');delay(5); write_data('T'); break; case 6: write_data('S');delay(5); write_data('A');delay(5); write_data('T'); break; case 7: write_data('S');delay(5); write_data('U');delay(5); write_data('N'); break; } } void keyscan()//按键设置 { if(key3==0)//功能键按下 { flag=0; delay(5); if(key3==0) { s1num++; while(!key3); di(); switch(s1num)//光标闪烁定位 { case 1:write_com(0x80+0x40+7);//定位到秒的位置 write_com(0x0f); break; case 2:write_com(0x80+0x40+4);//定位到分的位置 write_com(0x0f); break; case 3:write_com(0x80+0x40+1);//定位到小时的位置 write_com(0x0f); break; case 4:write_com(0x80+0x0e);//定位到星期的位置 write_com(0x0f); break; case 5:write_com(0x80+0x9);//定位到日的位置 write_com(0x0f); break; case 6:write_com(0x80+0x6);//定位到月的位置 write_com(0x0f); break; case 7:write_com(0x80+0x3);//定位到年的位置 write_com(0x0f); break; case 8: s1num=0;//复位,时钟走 write_com(0x0c); flag=1; write_1302 (0x8e,0x00); //允许写保护 write_1302 (0x80,miao); //秒位初始化 write_1302 (0x82,fen); //分钟初始化 write_1302 (0x84,shi); //小时初始化 write_1302 (0x86,day); //日初始化 write_1302 (0x88,month); //月初始化 write_1302 (0x8c,year); //年初始化 write_1302 (0x8a,week); //日期始化 write_1302 (0x8e,0x80); //禁止写¥ break; } } } if(s1num!=0)//只有功能键按下后,增大,增小建才有效 { if(key4==0)//增大建 { delay(5); if(key4==0) { while(!key4); di(); switch(s1num) { case 1: miao++; if(miao==60) miao=0; write_sfm(6,miao); //write_1302(write_second,miao); write_com(0x80+0x40+7); break; case 2: fen++; if(fen==60) fen=0; write_sfm(3,fen); //write_1302(write_minute,fen); write_com(0x80+0x40+4); break; case 3: shi++; if(shi==24) shi=0; write_sfm(0,shi); write_com(0x80+0x40+1); break; case 4: week++; if(week==8) week=1; display_week(week); write_com(0x80+14); break; case 5: day++; if(day==31) day=1; write_nyrz(8,day); write_com(0x80+9); break; case 6: month++; if(month==13) month=1; write_nyrz(5,month); write_com(0x80+6); break; case 7: year++; if(year==99) year=0; write_nyrz(2,year); write_com(0x80+3); break; } } } if(key5==0)//减小键 { delay(5); if(key5==0) { while(!key5); di(); switch(s1num) { case 1: miao--; if(miao==-1) miao=59; write_sfm(6,miao); write_com(0x80+0x40+7); break; case 2: fen--; if(fen==-1) fen=59; write_sfm(3,fen); write_com(0x80+0x40+4); break; case 3: shi--; if(shi==-1) shi=23; write_sfm(0,shi); write_com(0x80+0x40+1); break; case 4: week--; if(week==-1) week=7; display_week(week); write_com(0x80+14); break; case 5: day--; if(day==0) day=31; write_nyrz(8,day); write_com(0x80+9); break; case 6: month--; if(month==0) month=12; write_nyrz(5,month); write_com(0x80+6); break; case 7: year--; if(year==-1) year=99; write_nyrz(2,year); write_com(0x80+3); break; } } } } } void set_alarm() { if(key1==0)//功能键按下 { delay(5); if(key1==0) { while(!key1); flag=0; s1num2++; write_sfm(6,amiao); write_com(0x80+0x40+7); write_sfm(3,afen); write_com(0x80+0x40+4); write_sfm(0,ashi); write_com(0x80+0x40+1); di(); switch(s1num2)//光标闪烁定位 { case 1:write_com(0x80+0x40+7);//定位到秒的位置 write_com(0x0f); break; case 2:write_com(0x80+0x40+4);//定位到分的位置 write_com(0x0f); break; case 3:write_com(0x80+0x40+1);//定位到小时的位置 write_com(0x0f); break; case 4: s1num2=0;//复位,时钟走 write_com(0x0c); flag=1; // write_1302(0x8e,0x00);//允许写保护 write_1302 (0x8e,0x80); break; } } } if(s1num2!=0)//只有功能键按下后,增大,增小建才有效 { if(key2==0)//增大建 { delay(5); if(key2==0) { while(!key2); di(); switch(s1num2) { case 1: amiao++; if(amiao==60) amiao=0; write_sfm(6,amiao); write_com(0x80+0x40+7); break; case 2: afen++; if(afen==60) afen=0; write_sfm(3,afen); write_com(0x80+0x40+4); break; case 3: ashi++; if(ashi==24) ashi=0; write_sfm(0,ashi); write_com(0x80+0x40+1); break; } } } } } void main()//主函数 { Initial(); lcdws=0; init(); // IntConfiguration(); tempchange(); for(i=10;i>0;i--) { dis_temp(get_temp()); } while(1) { keyscan();//按键扫描 // while((key1&&key2&&key3&&key4&&key5)&&((fen==afen)&&(shi==ashi))) // { // beep=0; // delay(500); // beep=1; // } if(flag==1) { miao=Read1302(0x81);//显示秒 write_sfm(6,miao); fen=Read1302(0x83);//显示分 write_sfm(3,fen); shi=Read1302(0x85);//显示小时 write_sfm(0,shi); day=Read1302(0x87);//显示日 write_nyrz(8,day); month=Read1302(0x89);//显示月 write_nyrz(5,month); year=Read1302(0x8d);//显示年 write_nyrz(2,year); week=Read1302(0x8b);//显示日期 display_week(week); } else { write_1302(0x80,0x80);//时钟振荡器停止} set_alarm(); } }