DS18B20数字温度传感器
1.DS18B20功能指令
ROM指令
ROM Commands | 命令名称 | 描述 |
---|---|---|
F0H | Search ROM | 搜索ROM;用于确定挂接在同一总线上DS18B20的个数,识别64位ROM地址 |
33H | Read ROM | 读ROM;读DS18B20芯片中的编码值,即64位ROM值 |
55H | Match ROM | 匹配ROM发出此命令后,接着发出64位ROM编码,用于选中某个设备 |
CCH | Skip ROM | 忽略ROM表示后续发出的命令将会发给所有设备如果总线上只有一个DS18B20,则特别适用此命令 |
ECH | Alarm ROM | 警报搜索执行此命令后,只有温度超过设定值上限或下限的芯片才会做出响应 |
功能指令
Function Commands | 命令名称 | 描述 |
---|---|---|
44H | Convert Teamperature | 启动温度转换,注意不同精度需要不同转换时间,结果存入内部RAM |
4EH | Write Scratchpad | 写内部RAM,可以写入3字节:TH,TL,配置值(用于选择精度)TH,TL可用于设置报警上下限,或给用户自己使用 |
BEH | Read Scratchpad | 读整个内部RAM,9字节 |
48H | Copy Scratchpad | 把内部RAM中的TH、TL、配置值,复制给EEPROM |
B8H | Recall EEPROM | 从EEPROM中把TH、TL、配置值,读到内部RAM |
B4H | Read Power Supply | 分辨DS18B20的供电方式:用电源引脚供电,或从数据线偷电 |
DS18B20 Memory Map
Byte 4 配置DS18B20精度选择见目录3.5.1使用寄生供电方式 延时时间表
2.读取温度操作顺序(总线上只挂载了一个ds18b20)
3.代码实现
3.1初始化函数
/******************************************************************************/
// 函数名称:ds18b20_init
// 输入参数:无
// 输出参数:bit 检测是否在工作(0正常 1异常)
// 函数功能:初始化
// 晶振频率:11.0592M
/******************************************************************************/
bit ds18b20_init()
{
bit flag;
DQ=0; // 总线拉低
Delay500us(); // 延时最少480us
DQ=1; // 释放总线
Delay68us(); // 延时读取温度
flag=DQ;
Delay500us();
return flag;
}
3.1.1初始化时序图
3.1.2读初始化延时时间取值
3.2写一位操作
/******************************************************************************/
// 函数名称:ds18b20_write_low
// 输入参数:无
// 输出参数:无
// 函数功能:写一位0操作
// 晶振频率:11.0592M
/******************************************************************************/
void ds18b20_write_low()
{
DQ=0;
Delay68us();
DQ=1;
_nop_();
_nop_();
}
/******************************************************************************/
// 函数名称:ds18b20_write_high
// 输入参数:无
// 输出参数:无
// 函数功能:写一位1操作
// 晶振频率:11.0592M
/******************************************************************************/
void ds18b20_write_high()
{
DQ=0;
_nop_();
_nop_();
DQ=1;
Delay68us();
}
3.2.1写一位时序图
写0操作 开始将DQ拉低保持60us~120us,在将DQ引脚释放后延时大于1us要器件做好下一次写操作准备。
写1操作 开始将DQ引脚拉低保持1us,之后在1us~ 14us之间释放DQ引脚延时60us~120us。
3.3写操作函数
/******************************************************************************/
// 函数名称:ds18b20_write_cmd
// 输入参数:uint8
// 输出参数:无
// 函数功能:写字节操作(ds18b20发送是从最低位开始)
// 晶振频率:11.0592M
/******************************************************************************/
void ds18b20_write_cmd(uint8 cmd)
{
uint8 i;
for(i=0;i<8;i++)
{
if(cmd&0x01)
ds18b20_write_high();
else
ds18b20_write_low();
cmd>>=1;
}
}
3.4读操作函数
/******************************************************************************/
// 函数名称:ds18b20_read_data
// 输入参数:无
// 输出参数:无
// 函数功能:读一个字节(最低位开始)
// 晶振频率:11.0592M
/******************************************************************************/
uint8 ds18b20_read_data()
{
uint8 i,readflag =0x00;
for(i=0;i<8;i++)
{
readflag>>=1;
DQ=0;
_nop_();
_nop_();
DQ=1;
_nop_();
_nop_();
if(DQ)readflag|=0x80;
Delay68us();
}
return readflag;
}
3.4.1读操作时序图
读操作时将DQ引脚拉低保持1us,然后释放DQ引脚延时,此时读ds18b20数据位,这个过程要保存在15us之内完成,之后总延时要大于60us减去之前延时时间在加上1us缓冲,在此期间ds18b20会释放总线。
3.5忙信号检测(使用寄生供电方式无效)
/******************************************************************************/
// 函数名称:ds18b20_bus_check
// 输入参数:无
// 输出参数:无
// 函数功能:忙信号检测(0为忙 1为温度转换完成)
// 晶振频率:11.0592M
/******************************************************************************/
void ds18b20_bus_check()
{
bit flag;
do
{
DQ=0;
_nop_();
_nop_();
DQ=1;
_nop_();
_nop_();
flag=DQ;
Delay68us();
}while(!flag);
}
此函数就是读一位操作方式,见目录读取温度操作顺序
3.5.1使用寄生供电方式 延时时间表
3.6温度转换函数
/******************************************************************************/
// 函数名称:ds18b20_get_temp
// 输入参数:temp
// 输出参数:无
// 函数功能:接收转换并已字符形式存储温度
// 晶振频率:11.0592M
/*****************************************************************************/
void ds18b20_get_temp(uint8 *temp)
{
uint8 templow,temphigh,tempsol;
uint16 floatlow;
ds18b20_init();
ds18b20_write_cmd(0xcc);
ds18b20_write_cmd(0x44);
ds18b20_bus_check();
ds18b20_init();
ds18b20_write_cmd(0xcc);
ds18b20_write_cmd(0xbe);
templow=ds18b20_read_data();
temphigh=ds18b20_read_data();
floatlow=(templow & 0x0f)*625;
templow>>=4;
temphigh<<=4;
tempsol=templow+temphigh;
if(tempsol&0x80)
{
tempsol-=0x01;
tempsol=!tempsol;
}
*(temp+0)=tempsol/100+0x30; //百位
*(temp+1)=tempsol%100/10+0x30; //十位
*(temp+2)=tempsol%100%10+0x30; //个位
*(temp+4)=floatlow/1000+0x30; //小数点第1位
*(temp+5)=floatlow%1000/100+0x30; //小数点第2位
*(temp+6)=floatlow%1000%100/10+0x30; //小数点第3位
*(temp+7)=floatlow%1000%100%10+0x30; //小数点第4位
}
3.6.1温度计算图表
1.DS18B20未启动温度转换取值时出场默认是85°
2.温度为负时要对数据进行补码 反码操作
3.7主函数(模拟)串口向PC发送
/******************************************************************************/
// 温度存储
/******************************************************************************/
uint8 temperature[9]={ '0', '0', '0', '.', '0', '0', '0', '0', '\n'};
/******************************************************************************/
// main函数
/******************************************************************************/
void main(void){
led=1;
if (!ds18b20_init())
led=0;
while(1)
{
uint8 i,j,ak;
ds18b20_get_temp(temperature);
for(i=0;i<9;i++)
{
ak=temperature[i];
u_tx=1; //模拟串口开始位
u_tx=0;
Delay833us(); //波特率为1200 bit/s计算出的延时时间(大概值)
for(j=0;j<8;j++) //依次发送
{
if(ak&0x01)u_tx=1;
else u_tx=0;
Delay833us();
ak>>=1;
}
u_tx=1; //模拟串口停止位
Delay833us();
}
}
}