DS18B20简介
DS18B20 是由 DALLAS 半导体公司推出的一种的“一线总线(单总线)”接口的温度传感器
这种一线总线就是 三线制 SPI
DS18B20的 配置寄存器:
TM 是测试位,出厂设置就被设置为0,不需要改动,
R1、R0 是精度位,为设置1
0 1 1 1 1 1 1 1
温度寄存器格式
读取时,低位在前,高位在后,
正温度 高位前5位为 0,负温度 高位前5位为 1
’负温度 取反后 + 1*0.0625 可得到实际温度
如何转换?
以+85度 为例:
数据输出85°,0550h 换算10进制为1360,将这个值*0.0625 = 85度
负温度:-0.5
1111 1111 1111 1000 取反 0000 0000 0000 0111
换算十六进制 0x0007, 加1 0x0008,8*0.0625= 0.5 ,加上符号 -0.5°
DS18B20 时序包括:
初始化时序
写0 、1 时序
读0、1时序
DS18B20发送所有的命令和数据都是字节的低位在前
(1)单总线初始化时序
定义初始化函数:
1、主机输出低电平
2、保持低电平480us~960us
3、释放总线,为高电平
4、拉高电平延时15~60us
// 初始化时序 定义一个函数 复位
void ds18b20_reset(void)
{
DS18B20_PORT =0; // 输出低电平
delay_10us(75); // 75*10 750us
DS18B20_PORT = 1;// 释放总线
delay_10us(2); // 2*10 延时
}
(2)写时序
写时序包括写1 或 0 ,写时序至少60us,2次独立的写时序需要1us 恢复,
两种写0 写1 都是总线拉低位
写0,主机拉低,延时15us,45us 采样
写1 ,主机输出低电平,延时2us,然后释放总线拉高
(3)读时序
单总线流程
复位→发 SKIP ROM 命令(0XCC)→发开始转换命令(0X44)→延时→复位→发送 SKIP ROM 命令(0XCC)→发读存储器命令 (0XBE)→连续读出两个字节数据(即温度)→结束
软件编程:
// 初始化函数
u8 ds18b20_init(void)
{
ds18b20_reset();
return ds18b20_check();
}
// 复位
void ds18b20_reset(void)
{
DS18B20_PORT=0; //拉低 DQ
delay_10us(75); //拉低 750us
DS18B20_PORT=1; //DQ=1
delay_10us(2); //20US
}
// 检测ds18b20 是否存在
u8 ds18b20_check(void)
{
u8 time_temp=0;
while(DS18B20_PORT&&time_temp<20) //等待 DQ 为低电平
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //如果超时则强制返回 1
else time_temp=0;
while((!DS18B20_PORT)&&time_temp<20) //等待 DQ 为高电平
{
time_temp++;
delay_10us(1);
}
if(time_temp>=20)return 1; //如果超时则强制返回 1
return 0;
}
// 温度读取函数
float ds18b20_read_temperture(void)
{
float temp;
u8 dath=0;
u8 datl=0;
u16 value=0;
ds18b20_start();//开始转换
ds18b20_reset();//复位
ds18b20_check();
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0xbe);//读存储器
datl=ds18b20_read_byte();//低字节
dath=ds18b20_read_byte();//高字节
value=(dath<<8)+datl;//合并为 16 位数据
if((value&0xf800)==0xf800)//判断符号位,负温度
{
value=(~value)+1; //数据取反再加 1
temp=value*(-0.0625);//乘以精度
}
else //正温度
{
temp=value*0.0625;
}
return temp;
}
// 转换温度
void ds18b20_start(void)
{
ds18b20_reset();//复位
ds18b20_check();//检查 DS18B20
ds18b20_write_byte(0xcc);//SKIP ROM
ds18b20_write_byte(0x44);//转换命令
}