参加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);
}测试结果:

结果很稳定。
我要赚赏金
