#include "includes.h"
#define US_1 4 #define US_80 200 #define US_400 1000 #define US_500 1250
extern void delay(unsigned int Time);
sbit DS18b20io =P4^3;//根据实际情况定义端口
void delay_5us(unsigned int y) //(0.62+(y-1)*0.12)us延时,24.5m晶振 { while(--y); } void DS18b20_w_byte(unsigned char x) //向18b20写一个字节.x是要写的内容 { unsigned char i; SFRPAGE=0x0f; for(i=0;i<8;i++) { DS18b20io=0; delay_5us(US_1); //要求>1us,但又不能超过15us if(0x01&x) DS18b20io=1; delay_5us(US_80); //要求总时间在60-120us ,80us DS18b20io=1; //释放总线 delay_5us(US_1); //要求>1us x=x>>1; } }
unsigned char DS18b20_r_byte(void) //从18b20读一个字节.返回读到的内容 { unsigned char i,j; SFRPAGE=0x0f; j=0; for(i=0;i<8;i++) { j=j>>1; DS18b20io=0; delay_5us(US_1); //要求>1us,但又不能超过15us 1.625us DS18b20io=1; //释放总线 delay_5us(2); if(DS18b20io) j|=0x80; delay_5us(US_80); //要求总时间在60-120us DS18b20io=1; //释放总线 delay_5us(US_1); //要求>1us } return j; }
void DS18b20_int(void) //每次上电都给18b20初始化,设置18b20的参数. { SFRPAGE=0x0f; DS18b20io=0; delay_5us(US_500); //要求480-960us DS18b20io=1; //释放总线 delay_5us(US_80); //要求60-120us if(DS18b20io==0) { delay_5us(US_400); //要求释放总线后480us内结束复位 DS18b20io=1; //释放总线 DS18b20_w_byte(0xcc); //发送Skip ROM命令 DS18b20_w_byte(0x4e); //发送"写"暂存RAM命令 DS18b20_w_byte(0x00); //温度报警上限设为0 DS18b20_w_byte(0x00); //温度报警下限设为0 DS18b20_w_byte(0x3f); //将18b20设为10位,精度就是0.25度 DS18b20io=0; delay_5us(US_500); //要求480-960us DS18b20io=1; //释放总线 delay_5us(US_400); //要求释放总线后480us内结束复位 DS18b20io=1; //释放总线 } } int DS18b20_readTemp(void) //读18b20温度值 { int temp_z;//整数部分 unsigned char temp=0; unsigned char data temp1=0; unsigned char *p; unsigned char DS18b20_temp[2]; float a=0; SFRPAGE=0X0F; DS18b20io=0; delay_5us(US_500); //要求480-960us DS18b20io=1; //释放总线 delay_5us(US_80); //要求60-120us if(DS18b20io==0) { delay_5us(US_400); //要求释放总线后480us内结束复位 DS18b20io=1; //释放总线 DS18b20_w_byte(0xcc); //发送Skip ROM命令 DS18b20_w_byte(0x44); //发送温度转换命令 DS18b20io=1; //释放总线 delay(10000); delay(10000); delay(10000); DS18b20io=0; delay_5us(US_500); //要求480-960us DS18b20io=1; //释放总线 delay_5us(US_80); //要求60-120us if(DS18b20io==0) { delay_5us(US_400); //要求释放总线后480us内结束复位 DS18b20io=1; //释放总线 DS18b20_w_byte(0xcc); //发送Skip ROM命令 DS18b20_w_byte(0xbe); //发送"读"暂存RAM命令 DS18b20_temp[0]=DS18b20_r_byte(); //读温度低字节 DS18b20_temp[1]=DS18b20_r_byte(); //读温度高字节 DS18b20io=0; delay_5us(US_500); //要求480-960us DS18b20io=1; //释放总线 delay_5us(US_400); //要求释放总线后480us内结束复位 DS18b20io=1; //释放总线 if(DS18b20_temp[1] & 0xf8) {//负温度 p=(unsigned char *)&temp_z; *p=~DS18b20_temp[1]; *(p+1)=~DS18b20_temp[0]; temp_z++; temp=*p; temp=temp | 0x80;//符号位,负号 *p=temp; } else { temp= (DS18b20_temp[1]<<4 & 0x70) +(DS18b20_temp[0]>>4 & 0x0f); temp1=DS18b20_temp[0]>>2 & 0x03; temp_z=temp *10 + (temp1*2.5); return temp_z; } } } } int Read_Temperature() { DS18b20_int(); return DS18b20_readTemp(); } |