一、前言
参考资料:
- DS18B20 Datasheet
- 正点原子DS18B20数字温度传感器实验源码
- 野火DS18B20数字温度传感器实验源码
硬件环境:
正点原子 STM32F407 探索者
开发环境:
KEIL5
代码下载链接:
https://download.csdn.net/download/Constantine1954/18836298
二、DS18B20相关简介
DS18B20的相关资料网上还是比较全的,这里只做简单介绍。
一、特点
1.DS18B20是单总线温度传感器,与微处理器连接时仅需要一条口线即可实现微处理器与 DS18B20 的双向通讯。单总线具有经济性好,抗干扰能力强,适合于恶劣环境的现场温度测量。
2.测温范围:-55℃-+125℃,在-10℃~+85℃范围内精度为±0.5℃。
3.工作电压为3~5.5V。
4.分辨率可通过程序设定 9~12 位(默认分辨率为12位),分辨率及报警温度设定保存在EEPROM中,掉电保存。
5.多个DS18B20可以并联在一条总线上,实现多点测温。
二、简介
-
内部结构图:
DS18B20内部主要包括,64位ROM、2字节温度输出寄存器、1字节上下警报寄存器(TH和TL)和1字节配置寄存器。
ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,即本文代码中提到的ID号。每个DS18B20的64位序列号均不相同,这样就可以实现一根总线挂接多个DS18B20的目的。
64位ROM的排列是:前8位是产品家族码,接着48位是DS18B20的序列号,最后8位是前面56位的循环冗余校验码。
DS18B20控制引脚需要一个上拉电阻,并通过开漏模式连接到总线。 -
内部构成
高速暂存存储器由9个字节组成,分为温度的低八位数据0、温度的高8位数据1、高温阈值2、低温阈值3、配置寄存器4、保留5、保留6、保留7和CRC校验8。
器件断电时,EEPROM寄存器中的数据保留,上电后,EEPROM数据被重新加载到相应的寄存器位置,也可以使用命令随时将数据从EEPROM重新加载到暂存器中。
-
温度寄存器
温度数据为两字节,传输顺序为先低字节,后高字节。
对应关系如下:
温度传感器的分辨率可由用户配置为9、10、11或12位,分别对应0.5℃、0.25 ℃、0.125℃和0.0625℃的增量。 -
高低温报警寄存器
BIT7为符号位,S=0为正数,S=1为负数。
由于TH和TL是8位寄存器,所以在TH和TL比较中只使用温度寄存器的第11位到第4位。
执行温度转换后,将温度值与用户定义的两个报警触发值进行比较,如果被测温度低于或等于TL值,或高于或等于TH值,则在DS18B20内部生成报警条件,并设置报警标志。主设备可以通过发出一个[0XEC]命令来检查总线上所有DS18B20的报警标志状态。
TH和TL寄存器是非易失性的(EEPROM),当设备断电时,它们将保留数据。可以通过内存部分暂存器的字节2和字节3访问TH和TL。 -
配置寄存器
8位配置寄存器,通过修改BIT5(R0)和BIT6(R1)来设置温度转换的分辨率,上电后默认分辨率为12位(R0=1,R1=1)。
对应关系如下:修改分辨率时需注意转换时间。
三、时序
所有的单总线器件都要求采用严格的信号时序。
DS18B20共有6种信号类型:
1)复位脉冲
2)应答脉冲
3)写0
4)写1
5)读0
6)读1
除应答脉冲外均由主机发出同步信号。
- 复位脉冲和应答脉冲(初始化序列)
单总线上的所有通信都是以初始化序列开始的,时序图如下:
1)主机输出低电平,保持低电平时间至少480us,以产生复位脉冲。
2)接着主机释放总线,4.7K的上拉电阻将总线拉高,延时15-60us,进入接受模式。
3)然后从机DS18B20拉低总线60-240us,以产生低电平的应答脉冲。
/*
模块功能:复位DS18B20
返回值:无
*/
void DS18B20_Rst(void)
{
DS18B20_IO_OUT(); //SET PG11 OUTPUT
DS18B20_DQ_OUT=0; //拉低DQ
delay_us(750); //拉低750us
DS18B20_DQ_OUT=1; //DQ=1
delay_us(15); //15US
}
/*
模块功能:等待DS18B20的回应
返回值:返回1:未检测到DS18B20的存在
返回0:存在
备注:这里没有对DS18B20响应复位信号失败和释放总线失败的返回值做区分
*/
u8 DS18B20_Check(void)
{
u8 retry=0;
DS18B20_IO_IN();//SET PG11 INPUT
while (DS18B20_DQ_IN&&retry<240)//检测DS18B20是否拉低总线 (60~240 us 响应复位信号)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
else retry=0;
while (!DS18B20_DQ_IN&&retry<240)//检测DS18B20是否释放总线 (60~240 us)
{
retry++;
delay_us(1);
};
if(retry>=240)return 1;
return 0;
}
- 写时序
所有写时序至少需要60us,且两次独立写时序之间至少需要1us的恢复时间。2种写时序均起始于主机拉低总线。
写1时序:主机输出低电平,延时2us,释放总线,延时60us。
写0时序:主机输出低电平,延时60us,释放总线,延时2us。
/*
模块功能:写1位到DS18B20
返回值:无
*/
void DS18B20_Write_Bit(u8 dat)
{
DS18B20_IO_OUT();
if (dat)
{
DS18B20_DQ_OUT=0;// Write 1
delay_us(2);
DS18B20_DQ_OUT=1;
delay_us(60);
}
else
{
DS18B20_DQ_OUT=0;// Write 0
delay_us(60);
DS18B20_DQ_OUT=1;
delay_us(2);
}
}
/*
模块功能:写1个字节到DS18B20
返回值:无
*/
void DS18B20_Write_Byte(u8 dat)
{
u8 j;
u8 testb;
DS18B20_IO_OUT();//SET PG11 OUTPUT;
for (j=1;j<=8;j++)
{
testb=dat&0x01;
dat=dat>>1;
if (testb)
{
DS18B20_DQ_OUT=0;// Write 1
delay_us(2)