微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 单片机·DS18B20温度传感器

单片机·DS18B20温度传感器

时间:11-24 来源:互联网 点击:
一、DS18B20的特点

1.“一线总线”数字化温度传感器。(一线掌握好时序,比较简单)

2. 3~5V宽电压工作范围

3. 分辨9-12位可调

二、DS18B20的正确接线



面对着扁平的那一面,左负右正,一旦接反就有可能烧毁,也是温度显示85°C的原因。

且只有一根I/O线,注意读写时序 。

三、DS18B20时序介绍

1)复位


输入

t0-t1时刻:复位脉冲 480-960us ;

t1-t2时刻:释放总线 15-60us ;

检测

t2-t3时刻:虚线部分由DS18B20控制,60-240us低电平则表示复位成功,否则失败 ;

t3-t4时刻:释放总线

2)写操作


写0时序

输入

t0-15us:保持低电平,输入0;

检测

15-60us:检测i/o是否为低电平 ;

输入间隔>1us

写1时序

输入

t0-15us:拉高电平,输入1;

检测

15-60us:检测i/o是否为高电平

输入间隔>1us

3)读操作


t0-t1:保持4us低电平

t1-15us:DS18B20或者上拉电阻起作用,低电平或者高电平读出

15us-60us:释放总线

三、DS18B20的温度

1.DS18B20的温度格式表

一共是16位,我们用前5位表示符号位,后11位表示数值

2.DS18B20的温度数据表



125℃/2000 = 0.0625

当符号位为0时,表示正数,0.0625*hex得到温度的值 ;

当符号位为1时,表示负数,将所得到的(数值取反+1)*0.0625得到温度的值;

四、程序

1.启动温度转换

1)复位DS18B20;

2)发出Skip Rom命令(CCH) ;

3)发出convert命令(44H)

2.读取温度

1)复位DS18B20;

2)发出Skip Rom命令(CCH);

3)发出convert命令(BEH);

4)读2字节的温度 ;

5)温度格式转换 ;

程序

main.h

# ifndef _MAIN_H_

# define _MAIN_H_

# include

# include

sbit DQ = P3^2 ;

sbit RS = P1^0 ;

sbit RW = P1^1 ;

sbit EN = P1^5 ;

sbit BUSY = P0^7;

typedef unsigned char uint8 ;

typedef unsigned int uint16 ;

typedef int int16 ;

#define nops() {_nop_();_nop_();_nop_();_nop_();}

#endif

main.c

# include "main.h"

void delay(uint16 n)

{

while(n--) ;

}

void DB18B20_reset(void)

{

bit flag = 1 ; //程序有改动

while(flag)

{

DQ = 1 ;

nops() ;

DQ = 0 ;

delay(50) ;

DQ = 1 ;

delay(5) ;

flag = DQ ;

delay(20) ;

}

DQ = 1 ;

delay(20) ;

}

void write_byte(uint8 byte)

{

uint8 i ;

for(i=0; i<8; i++)

{

DQ = 1 ;

_nop_() ;

DQ = 0 ;

nops() ;

DQ = byte&0x01 ;

delay(6) ;

byte>>=1 ;

}

DQ = 1 ;

_nop_() ; //短暂延时应该即可。

}

uint8 read_byte(void)

{

uint8 i, dat =0 ;

for(i=0; i<8; i++)

{

DQ = 1 ;

_nop_() ;

DQ = 0 ;

nops() ;

DQ = 1 ;

nops() ;

dat>>=1 ;

if(DQ)

dat |= 0x80 ;

delay(6) ;

}

DQ = 1 ;

_nop_() ;

return dat ;

}

void start_temp_sensor(void)

{

DB18B20_reset() ;

write_byte(0xcc) ;

write_byte(0x44) ;

}

int16 read_temp(void)

{

uint8 tempdata[2] ;

int16 temp ; //数据的符号位看输出是否需要符号

DB18B20_reset() ;

write_byte(0xcc) ;

write_byte(0xBE) ;

tempdata[0] = read_byte() ;

tempdata[1] = read_byte() ;

temp = tempdata[1] ;

temp<=8 ;

temp |= tempdata[0] ; //转换为十进制的代码 不理解,求大神帮助

temp>>=4 ;

return temp ;

}

void wait(void)

{

P0 = 0xFF;

do

{

RS = 0;

RW = 1;

EN = 0;

EN = 1;

}while (BUSY == 1);

EN = 0;

}

void w_dat(uint8 dat)

{

wait();

EN = 0;

P0 = dat;

RS = 1;

RW = 0;

EN = 1;

EN = 0;

}

void w_cmd(uint8 cmd)

{

wait();

EN = 0;

P0 = cmd;

RS = 0;

RW = 0;

EN = 1;

EN = 0;

}

void w_hexnum(uint16 dat)

{

w_dat(dat/10 + 0) ;

w_dat(dat + 0) ;

w_dat(0xDF) ;

w_dat(C) ;

}

void Init_LCD1602(void)

{

w_cmd(0x38); // 16*2显示,5*7点阵,8位数据接口

w_cmd(0x0C); // 显示器开、光标开、光标允许闪烁

w_cmd(0x06); // 文字不动,光标自动右移

w_cmd(0x01); // 清屏

}

void main(void)

{

int16 ans ;

Init_LCD1602() ;

while(1)

{

start_temp_sensor() ; //这里为什么需要延时 ;

ans = read_temp() ;

w_cmd(0x80) ;

w_hexnum(ans) ;

}

}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top