参加TI的焕新大作战中,有一节课程是制作温度报警器,使用DS18B20,以我的习惯,是一定要上Arduino进行测试的。老习惯,还是使用ESP82666模块。
DS18B20是单总线通讯的,我就是用D0(GPIO16)来处理。
ESP8266(ESP12-E)模组的GPIO配置:
为了便于连接两个模组,我使用了ESP12E的扩展板。
DS18B20模组的接口设置:
整个装置连接好后,
测试程序:
#define DS18B20DQ 16 unsigned long total = 0; unsigned long tn = 0; void setup() { Serial.begin(115200); while (!Serial); } void Ds18b20Rst(void) { pinMode(DS18B20DQ,OUTPUT); digitalWrite(DS18B20DQ,LOW); delayMicroseconds(750);//主机发送复位脉冲480us-960us digitalWrite(DS18B20DQ,HIGH); delayMicroseconds(15);//18b20等待15-60us } /*等待18b20响应 * 返回1:未检测到18b20 * 返回0:存在 */ byte Ds18b20Check(void) { byte retry=0; pinMode(DS18B20DQ,INPUT); while(digitalRead(DS18B20DQ)&&retry<200) { retry++; delayMicroseconds(1); } if(retry>=200)return 1; else retry=0; while(!digitalRead(DS18B20DQ)&&retry<240) { retry++; delayMicroseconds(1); } if(retry>240)return 1; return 0; } /*从18b20读取一个位 * 返回值1/0 */ byte Ds18b20ReadBit(void) { byte data; pinMode(DS18B20DQ,OUTPUT); digitalWrite(DS18B20DQ,LOW); delayMicroseconds(2); digitalWrite(DS18B20DQ,HIGH); pinMode(DS18B20DQ,INPUT); delayMicroseconds(12); if(digitalRead(DS18B20DQ))data=1; else data=0; delayMicroseconds(50); return data; } /*从18b20读取一个字节 * 返回值:读到的数据 */ byte Ds18b20ReadByte(void) { byte i,j,dat; dat=0; for(i=1;i<=8;i++) { j=Ds18b20ReadBit(); dat=(j<<7)|(dat>>1);//低位在前 } return dat; } /*写一个字节到Ds18b20 * dat:要写入的字节 */ void Ds18b20WriteByte(byte dat) { byte i; byte temp; pinMode(DS18B20DQ,OUTPUT); for(i=1;i<=8;i++) { temp=dat&0x01; dat=dat>>1; if (temp) { // 输出1 digitalWrite(DS18B20DQ,LOW); delayMicroseconds(2); digitalWrite(DS18B20DQ,HIGH); delayMicroseconds(60); } else { // 输出0 digitalWrite(DS18B20DQ,LOW); delayMicroseconds(60); digitalWrite(DS18B20DQ,HIGH); delayMicroseconds(2); } } } /*从Ds18b20得到温度值 * 精度0.1c * 返回值:温度值(-550-1250) */ float Ds18b20GetTemp() { byte temp; byte TH=0,TL=0; short tem; float t; Ds18b20Rst(); Ds18b20Check(); // 跳过ROM操作 Ds18b20WriteByte(0XCC); // 发出转换指令 Ds18b20WriteByte(0X44); Ds18b20Rst(); Ds18b20Check(); // 跳过ROM操作 Ds18b20WriteByte(0XCC); // 读数据,低位在前 Ds18b20WriteByte(0XBE); TL=Ds18b20ReadByte();//LSB TH=Ds18b20ReadByte();//MSB Serial.print("TH="); Serial.println(TH); Serial.print("TL="); Serial.println(TL); if(TH>7) { // 如果数据是负的 TH=~TH; TL=~TL; // 负温度标志 temp=0; } else { // 正温度 temp=1; } tem=TH;//高八位 tem<<=8; tem+=TL;//低八位 // 计算温度值 t=((float)tem*0.0625); if(temp) return t; else return -t; } void loop(void) { float t; t= Ds18b20GetTemp(); Serial.print("The temperature is :"); Serial.println(t); delay(500); }
测试结果:
结果很稳定。