DS18B20是一款DALLAS公司推出的单总线数字温度测量芯片。它具有体积小,硬件开销低,抗干扰能力强,精度高的特点
这次实现在ART-Pi开发板上挂载1个DS18B20测量温度功能
硬件如下:
VDD接到电源,DQ接MCU引脚,GND接地,由于DQ引脚为开漏输出,不具有输出高电平的能力,必须要接一个上拉电阻
①新建工程
在RT-Thread Studio中新建基于ART-Pi开发板的模板工程
②初始化DS18B20
初始化时序如下:
MCU拉低总线至少480us,产生复位脉冲,然后释放总线(拉高电平);这时DS8B20检测到请求之后,会拉低信号,大约60~240us表示应答;DS8B20拉低电平的60~240us之间,单片机读取总线的电平,如果是低电平,那么表示初始化成功;DS18B20拉低电平60~240us之后,会释放总线
代码实现:
//复位DS18B20void DS18B20_Rst(void) { rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); //输出模式 rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ rt_hw_us_delay(750); //拉低750us(480~960us) rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ } //等待DS18B20应答,有应答返回0,无应答返回1 uint8_t DS18B20_Check(void) { uint8_t retry=0; //进入接收模式,等待应答信号 //等待时间 rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //输入模式 rt_hw_us_delay(15); //等待15~60us while(rt_pin_read(DS18B20_DQ)&&retry<120) //最多再等待120us { retry++; rt_hw_us_delay(1); }; if(retry>=120) return 1; //120us未响应,则判断未检测到 else retry=0; //DS18B20开始拉低DQ while(!rt_pin_read(DS18B20_DQ)&&retry<240) //最长拉低240us { retry++; rt_hw_us_delay(1); }; if(retry>=240) return 1; return 0; }
复制代码③写DS18B20时序
写时序如下:
MCU给DS18B20写0时,MCU引脚拉低,延时60us,然后释放总线,延时2us
MCU给DS18B20写1时,MCU引脚拉低,延时2us,然后释放总线,延时60us
在写时序起始后15μs到60μs期间,DS18B20处于采样单总线电平状态。如果在此期间总线为高电平,则向DS18B20写入1;如果总线为低电平,则向DSl8B20写入0
代码实现:
//写字节到DS18B20void DS18B20_Write_Byte(uint8_t dat) { uint8_t j; uint8_t temp; rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); //输出模式 for(j=1;j<=8;j++) { temp=dat&0x01; dat=dat>>1; if (temp) //输出高 { rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ rt_hw_us_delay(2); //延时2us rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ rt_hw_us_delay(60); //延时60us } else //输出低 { rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ rt_hw_us_delay(60); //延时60us rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ rt_hw_us_delay(2); //延时2us } } rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //输入模式 }
复制代码读时序如下:
MCU拉低电平,延时2us;MCU转为输入模式,延时12us;然后读取单总线当前的电平,延时50us
代码实现:
//从DS18B20读位uint8_t DS18B20_Read_Bit(void) { uint8_t data; rt_pin_mode(DS18B20_DQ, PIN_MODE_OUTPUT); //输出模式 rt_pin_write(DS18B20_DQ, PIN_LOW); //拉低DQ rt_hw_us_delay(2); //延时2us rt_pin_write(DS18B20_DQ, PIN_HIGH); //拉高DQ rt_pin_mode(DS18B20_DQ, PIN_MODE_INPUT); //输入模式 rt_hw_us_delay(12); //延时12us if(rt_pin_read(DS18B20_DQ)) //读DQ数据 data=1; else data=0; rt_hw_us_delay(50); //延时50us return data; } //从DS18B20读字节 uint8_t DS18B20_Read_Byte(void) { uint8_t i, j, dat=0; for(i=1;i<=8;i++) { j=DS18B20_Read_Bit(); dat=(j<<7)|(dat>>1); } return dat; }
复制代码MCU发送复位信号,发送SKIP ROM命令(0XCC,匹配指令)
发开始转换命令(0X44)
延时等待转换完成(12bit分辨率时需要750ms)
MCU发送复位信号,发送SKIP ROM命令(0XCC)
发读存储器命令(0XBE),读取暂存器内容
连续读出两个字节数据
对读取的温度值进行转换
代码实现:
//开始温度转换void DS18B20_Start(void) { DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0x44); } //读取温度值 float DS18B20_Get_Temp(void) { uint8_t sign; //温度符号,0为-,1为+ uint8_t TL,TH; uint16_t temp; float temp1; DS18B20_Start (); rt_thread_mdelay(800); //等待转换完成 DS18B20_Rst(); DS18B20_Check(); DS18B20_Write_Byte(0xcc); DS18B20_Write_Byte(0xbe); TL=DS18B20_Read_Byte(); TH=DS18B20_Read_Byte(); if(TH>7) { TH=~TH; TL=~TL; sign=0; //温度为负 } else sign=1; //温度为正 temp=TH; //高八位 temp<<=8; temp+=TL; //低八位 temp1=(float)temp*0.0625; //转换实际温度 if(sign) return temp1; //返回温度值 else return -temp1; }
复制代码本次实现单总线上挂载1个DS18B20测量温度,后续再实现总线上挂载多个DS18B20测量温度。