}
P8563_WaitACK(); //I2C器件或通讯出错,将会退出I2C通讯 }
/******************************************** 内部函数.输入数据 出口:B
********************************************/ uchar P8563_Readbyte() {
uchar i,bytedata; SDA=1;
for(i=0;i<8;i++) {
SCL=1;
bytedata<<=1; bytedata|=SDA; SCL=0; Delay(); }
return(bytedata); }
/******************************************** 输出数据->pcf8563
********************************************/ void P8563_writeData(uchar address,uchar mdata) {
P8563_Start();
P8563_writebyte(0xa2); /*写命令*/ P8563_writebyte(address); /*写地址*/ P8563_writebyte(mdata); /*写数据*/ P8563_Stop(); }
/******************************************** 输入数据<-pcf8563
********************************************/ uchar P8563_ReadData(uchar address) /*单字节*/ { uchar rdata; P8563_Start();
P8563_writebyte(0xa2); /*写命令*/ P8563_writebyte(address); /*写地址*/ P8563_Start();
P8563_writebyte(0xa3); /*读命令*/ rdata=P8563_Readbyte(); P8563_WriteACK(1);
P8563_Stop(); return(rdata); }
void P8563_ReadData1(uchar address,uchar count,uchar * buff) /*多字节*/ { uchar i;
P8563_Start();
P8563_writebyte(0xa2); /*写命令*/ P8563_writebyte(address); /*写地址*/ P8563_Start();
P8563_writebyte(0xa3); /*读命令*/ for(i=0;i buff[i]=P8563_Readbyte(); if(i P8563_WriteACK(1); P8563_Stop(); } /******************************************** 内部函数,读入时间到内部缓冲区 ********************************************/ void P8563_Read() { uchar time[7],century; P8563_ReadData1(0x02,0x07,time); century=time[5]; g8563_Store[0]=time[0]&0x7f; /*秒*/ g8563_Store[1]=time[1]&0x7f; /*分*/ g8563_Store[2]=time[2]&0x3f; /*小时*/ g8563_Store[3]=time[3]&0x3f; /*日*/ g8563_Store[4]=time[4]&0x07; /*星期*/ g8563_Store[5]=time[5]&0x1f; /*月*/ g8563_Store[6]=time[6]&0xff; /*年*/ g8563_Store[7]=century&0x80; /*取世纪,00为2000,80为1900*/ if(g8563_Store[7]==0x00)g8563_Store[7]=20; if(g8563_Store[7]==0x80)g8563_Store[7]=19; } /******************************************** 读入时间到内部缓冲区----外部调用 ********************************************/ void P8563_gettime() { P8563_Read(); if(g8563_Store[0]==0) P8563_Read(); /*如果为秒=0,为防止时间变化,再读一次*/ } /******************************************** 写时间修改值 ********************************************/ void P8563_settime() { P8563_writeData(2,g8563_Store[0]);//秒 P8563_writeData(3,g8563_Store[1]);//分 P8563_writeData(4,g8563_Store[2]);//时 P8563_writeData(5,g8563_Store[3]);//日 P8563_writeData(6,g8563_Store[4]);//星期 if(g8563_Store[7]==0x20)g8563_Store[5]=(g8563_Store[5]&0x3F);//判断世纪 if(g8563_Store[7]==0x19)g8563_Store[5]=(g8563_Store[5]|0x80);//判断世纪 P8563_writeData(7,g8563_Store[5]);//月 P8563_writeData(8,g8563_Store[6]);//年 } /******************************************** P8563的初始化 ********************************************/ void P8563_init() { uchar i; if((P8563_ReadData(0xa)&0x3f)!=0x8) /*检查是否第一次启动,是则初始化时间*/ { for(i=0;i<8;i++) g8563_Store[i]=c8563_Store[i]; /*初始化时间*/ P8563_settime(); P8563_writeData(0x0,0x00); P8563_writeData(0xa,0x8); /*8:00报警*/ P8563_writeData(0x1,0x12); /*报警有效*/ P8563_writeData(0xd,0xf0); } } //---BCD转换16函数---// void BCD_16( ) { uchar i,ucData1,ucData2; for(i=0;i<7;i++) { ucData1=g8563_Store[i]/16; //BCD码转十六进制 ucData2=g8563_Store[i]; g8563_Store[i]=ucData1*10+ucData2; } } //---DS18B20延时函数---// void delay_18B20(unsigned int i)//延时1微秒 { while(i--); } //---DS18B20复位函数---// //DS18B20要求数据线拉低500US即可复位。 void ds1820rst() { unsigned char x=0; } DQ = 1;//DQ复位 delay_18B20(4);//延时 DQ = 0;//DQ拉低 delay_18B20(100);//精确延时大于480us DQ = 1;//拉高 delay_18B20(40); //---DS18B20读数据函数---// unsigned char ds1820rd() { unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) { DQ = 0; //给脉冲信号 dat>>=1; DQ = 1; //给脉冲信号 if(DQ) dat|=0x80; delay_18B20(10); } return(dat); } //---DS18B20写数据函数---// void ds1820wr(unsigned char wdata) { unsigned char i=0; } for (i=8; i>0; i--) { DQ = 0; DQ = wdata&0x01; delay_18B20(10); DQ = 1; wdata>>=1; } //---读取温度值并转换---// read_temp() { unsigned char a,b; ds1820rst(); ds1820wr(0xCC);//跳过ROM _nop_(); //ds1820wr(0x4E);//写EEPROM,发出向内部RAM的3、4 字节写上、下限温度数据命令,紧跟该命令之后,是传送两字节的数据 // ds1820wr(0x00);//Th //ds1820wr(0x00);//Tl ds1820wr(0x7f);//12 bits温度分辨率0x1f, 0x3f, 0x5f ,0x7f温度读数分辨率分别对应0.5, 0.25, 0.125 ,0.0625 //ds1820wr(0xcc); //跳过读EPROM序列 //ds1820wr(0x48); 将RAM 中第3 、4 字节的内容复制到EEPROM 中. ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ _nop_(); ds1820wr(0x44);//*启动温度转换*/ ds1820rst(); ds1820wr(0xcc);//*跳过读序列号*/ ds1820wr(0xbe);//*读取温度*/ a=ds1820rd(); b=ds1820rd(); tvalue=b; tvalue<<=8; tvalue=tvalue|a; if(tvalue<0x0fff)tflag=0; else {tvalue=~tvalue+1; tflag=1; } f_temp=tvalue*(0.0625); // 温度在寄存器中为12位,分辨率为0.0625 tvalue=f_temp*10+0.5; //乘以10表示小数点后面只取1位,加0.5时四舍五入 return(tvalue);