#include #define uint unsigned int sbit SCLK = P1^4; //DS1302时钟口P1.4 sbit IO = P1^5; //DS1302数据口P1.5 sbit RST = P1^6; //DS1302片选口P1.6 sbit temp1=P1^7; sbit H0=P2^4; sbit H1=P2^5; sbit L0=P2^6; sbit L1=P2^7; sbit DQ=P3^5; uchar second,minute,hour,e; uchar time[10],shu[3]; /******************************************* *函数:delay(int z) *功能:延时 ********************************************/ void delay3(int z) { int i,j; for(i=z;i>0;i--) for(j=110;j>0;j--); } /******************************* 延时x微秒 ********************************/ void delayxus(unsigned int n) { while(n--) { _nop_(); _nop_(); } } /******************************* 延时x微秒 ********************************/ void Delay1() { _nop_(); _nop_(); } /****************************** 复位DS18B20 初始化 ******************************/ ds18b20_Reset(void) { unsigned char x=0; DQ=1; delayxus(60); DQ=0; delayxus(240); delayxus(240); DQ=1; delayxus(80); x=DQ; delayxus(120); } /******************************** 从DS18B20读一个字节数据 ********************************/ ds18b20_ReadByte(void) { unsigned char i=0; unsigned char dat=0; for(i=0;i<8;i++) { DQ=0; dat>>=1; delayxus(1); DQ=1; delayxus(1); if(DQ) dat|=0x80; delayxus(60); } return (dat); } /*************************** 向DS18B20写1字节数据 ****************************/ ds18b20_WriteByte(unsigned char dat) { unsigned char i=0; for(i=0;i<8;i++) { DQ=0; DQ=dat&0x01; delayxus(1); delayxus(60); DQ=1; dat>>=1; delayxus(1); } } /**************************** 读取温度 返回温度值 *****************************/ ReadTemperature(void) { unsigned int a=0; unsigned int b=0; unsigned int t=0; float tt=0; ds18b20_Reset(); ds18b20_WriteByte(0xCC); ds18b20_WriteByte(0x44); ds18b20_Reset(); ds18b20_WriteByte(0xCC); ds18b20_WriteByte(0xBE); a=ds18b20_ReadByte(); b=ds18b20_ReadByte(); t=b; t<<=8; t=t|a; tt=t*0.0625; t=tt*10; return (t); } void num() { unsigned int p; p=ReadTemperature(); shu[0]=p%10; shu[1]=(p/10)%10; shu[2]=(p/100)%10; } /************************************** 读DS1302某地址的的数据 **************************************/ uchar DS1302_ReadData(uchar addr) { uchar i,j,k; RST = 0; Delay1(); SCLK = 0; Delay1(); RST = 1; Delay1(); for (i=0x01,j=0; j<8; j++) //写地址 8位计数器 { if(addr&i) IO=1; else IO=0; SCLK = 1; //时钟线 Delay1(); //延时等待 i<<= 1; //移出数据 SCLK = 0; //时钟线 Delay1(); //延时等待 } k=0; for (i=0; i<8; i++) //读8位计数器 { k>>=1; SCLK = 0; //时钟线拉低 Delay1(); //延时等待 if (IO) k|= 0x80; //读取数据 SCLK = 1; //时钟线拉高 Delay1(); //延时等待 } SCLK = 1; RST = 0; return (k); } /************************************** 往DS1302的某个地址写入数据 **************************************/ void DS1302_WriteData(uchar addr, uchar dat) { uchar i,j; RST = 0; Delay1(); SCLK = 0; Delay1(); RST = 1; Delay1(); for (i=0x01,j=0; j<8; j++) //写数据 8位计数器 { if(addr&i) IO=1; else IO=0; SCLK = 1; //时钟线 Delay1(); //延时等待 i<<= 1; //移出数据 SCLK = 0; //时钟线 Delay1(); //延时等待 } for(i=0x01,j=0;j<8;j++) { if(dat&i) IO=1; else IO=0; SCLK=1; Delay1(); i<<= 1; SCLK=0; Delay1(); } RST = 0; SCLK = 1; } /******************************* 设置时间 *******************************/ void settime() { uchar temp; char Data,NowData; P2=0xf0; H0=0; temp=P2; temp=temp&0xc0; if(temp!=0xc0) { temp=P2; temp=temp&0xc0; delay3(10); if(temp!=0xc0) { switch(temp) { case 0x80: DS1302_WriteData(0x80,0x01); DS1302_WriteData(0x8e,0x00); Data=DS1302_ReadData(0x83); NowData=Data+1; if(NowData>0x59) NowData=0; DS1302_WriteData(0x82,NowData); DS1302_WriteData(0x8e,0x80); //key=1; break; case 0x40: DS1302_WriteData(0x80,0x01); DS1302_WriteData(0x8e,0x00); Data=DS1302_ReadData(0x83); NowData=Data-1; if(NowData==-1) NowData=0x59; DS1302_WriteData(0x82,NowData); DS1302_WriteData(0x8e,0x80); //key=2; break; } temp=P2; temp=temp&0xc0; while(temp!=0xc0) { temp=P2; temp=temp&0xc0; } } } P2=0xf0; H1=0; temp=P2; temp=temp&0xc0; if(temp!=0xc0) { temp=P2; temp=temp&0xc0; delay3(10); if(temp!=0xc0) { switch(temp) { case 0x80: DS1302_WriteData(0x80,0x01); DS1302_WriteData(0x8e,0x00); Data=DS1302_ReadData(0x85); NowData=Data+1; if(NowData>0x23) NowData=0; DS1302_WriteData(0x84,NowData); DS1302_WriteData(0x8e,0x80); //key=3; break; case 0x40: DS1302_WriteData(0x80,0x01); DS1302_WriteData(0x8e,0x00); Data=DS1302_ReadData(0x85); NowData=Data-1; if(NowData==-1) NowData=0x23; DS1302_WriteData(0x84,NowData); DS1302_WriteData(0x8e,0x80); //key=4; break; } temp=P2; temp=temp&0xc0; while(temp!=0xc0) { temp=P2; temp=temp&0xc0; } } } //return key; } /************************************** 初始化DS1302 **************************************/ void Init1302() { DS1302_WriteData(0x8e,0x00); //控制写入WP=0 DS1302_WriteData(0x80,0x00); //秒 DS1302_WriteData(0x82,0x23); //分 DS1302_WriteData(0x84,0x21); //时 DS1302_WriteData(0x8e,0x80); } /******************************************* *函数功能:ds1302时间处理 *入口参数:无 *说 明: BCD码转换成十进制数 *返 回: 无 ********************************************/ void donetime() { time[0]=DS1302_ReadData(0x81); time[1]=DS1302_ReadData(0x83); time[2]=DS1302_ReadData(0x85); second=(time[0]/16)*10+(time[0]%16);//((time[0]>>4)&0x0f)*10+(time[0]&0x0f);BCD转十进制有三种写法 minute=((time[1]&0x70)>>4)*10+(time[1]&0x0f); //(time[1]/16)*10+(time[1]%16); hour=((time[2]&0x30)>>4)*10+(time[2]&0x0f); } void main() { e=DS1302_ReadData(0x81);//判断时钟有没有运行 if(e&0x80) { Init1302(); //初始化DS1302 } while(1) { num(); settime(); donetime(); temp1=second&01;//时间点闪烁 display(shu[0],0); display1(shu[1],1); display(shu[2],2); display(minute%10,3); display(minute/10,4); display(hour%10,5); display(hour/10,6); display(1,7); } }