一、功能引脚

其中,DQ脚为数据输入端/输出端(I/O),与单片机P1^4相连,采用单总线协议,该引脚为漏极开路输出,常态下呈高电平。
二、工作原理
DS18B20内部包含一个64位的ROM、9字节的RAM、温度传感器以及相关控制电路。
9字节RAM是一个高速暂存器,其中第0、1字节是温度转换有效位,第0字节的低3位存放了温度的高位,高5位存放温度的正负值;第1字节的高4位存放温度的低位,后4位存放温度的小数部分,因此精确度位2^(-4)=0.0625。如果检测温度大于零度,第0字节高5位全为0,温度有效值为原码表示;如果检测温度小于零度,第0字节的高5位全为1,温度的有效值用补码表示,在应用中需要进行数据转换。

三、工作时序
单总线协议规定一条数据线传输串行数据,时序有严格的控制,对于DS18B20的程序设计,必须遵守单总线协议。DS18B20操作主要分初始化、写数据、读数据。

1、初始化

bit init_ds18b20(void) { bit initflag = 0; DQ = 1; //总线复位 Delay_OneWire(12); DQ = 0; //拉低480us - 960us Delay_OneWire(80); DQ = 1; //拉高15 ~ 60us Delay_OneWire(10); initflag = DQ; //发出应答 Delay_OneWire(5); return initflag; }
如果初始化成功则在15~60us总线上产生一个由DS18B20返回的低电平0,据该状态可以确定它的存在。但是应注意,不能无限地等待,不然会使程序进入死循环,所以要进行超时判断。若单片机读到数据线上的低电平0后,说明DS18B20存在并相应,还要进行延时,其延时的时间从发出高电平算起(第5步的时间算起)最少要480µs。
延时函数
void Delay_OneWire(unsigned int t) { unsigned char i; while(t--){ for(i=0;i<12;i++); } }
2、写数据

void Write_DS18B20(unsigned char dat) { unsigned char i; for(i=0;i<8;i++) //从低到高依次发送数据 { DQ = 0; //置低电平发送起始信号 DQ = dat&0x01; //接收 Delay_OneWire(5); //等待 DQ = 1; //拉高释放总线 dat >>= 1; //右移获取后一位 } Delay_OneWire(5); }
3、读数据

unsigned char Read_DS18B20(void) { unsigned char i; unsigned char dat; for(i=0;i<8;i++) //依次获取数据 { DQ = 0; //拉低开始 dat >>= 1; DQ = 1; Delay_OneWire(1); //此处需等待,否则数据错误 if(DQ) { dat |= 0x80; //获得状态位 } Delay_OneWire(5); } return dat; }
四、代码
在实际应用中,单片机需要总线上的多个DS18B20中的某一个进行操作时,事前应将每DS18B20分别与总线连接,先读出读出其序列号;然后再将所有的DS18B20连接到总线上,当单片机发出匹配ROM命令(55H),紧接着主机提供的64位序列,找到对应的DS18B20后,之后的操作才是针对该器件得。如果总线上只存在一个DS18B20,就不需要读取ROM编码以及匹配ROM编码了,只要跳过ROM(CCH)命令,就可进行如下温度转换和读取操作。

unsigned int GetTemp() { unsigned int dat; unsigned char LSB,MSB; float temp; init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0x44); Delay_OneWire(500); init_ds18b20(); Write_DS18B20(0xcc); Write_DS18B20(0xbe); LSB = Read_DS18B20(); MSB = Read_DS18B20(); dat = MSB; dat = (dat << 8) | LSB; if((dat & 0xf800) == 0x0000){ temp = dat * 0.0625; dat = temp * 10; } return dat; }
tips:此处位保留一位小数,如想要两位乘100即可。
519

被折叠的 条评论
为什么被折叠?



