前言
好久没有更新关于蓝桥杯单片机相关的模块了,今天更新一下数字温度传感器DS18B20的相关应用
单线数字温度计DS1820介绍
DS1820数字温度计提供9位(二进制)温度读数,指示器件的温度。信息经过单线接口送入DS1820 或从 DS1820 送出,因此从主机CPU到DSl820仅需一条线(和地线) 。DS1820的电源可以由数据线本身提供而不需要外部电源。因为每一个DS1820在出厂时已经给定了唯一的序号,因此任意多个DS1820可以存放在同一条单线总线上,这允许在许多不同的地方放置温度敏感器件。DS1820的测量范围从-55℃ 到+125℃ ,增量值为0.5℃ 。
DSl820中用于贮存测得的温度值的两个8位存贮器RAM,编号为0号和1号。1 号存贮器存放温度值的符号,如果温度为负(℃ )则1号存贮器8位全为1,否则全为0。0号存贮器用于存放温度值的补码 LSB(最低位)的 “1”表示 0.5 将存贮器中的二进制数求补再转换成十进制数并除以2就得到被测温度值(-55℃~125℃ ) 。
每只D51820都可以设置成两种供电方式,即数据总线供电方式和外部供电方式,采取数据总线供电方式可以节省一根导线,但完成温度测量的时间较长,采取外部供电方式则多用一根导线,但测量速度较快 。
温度计算
DS18B20用12位存贮温值度,最高位为符号位,下图为18b20的温度存储方式 负温度S=1,正温度S=0,如
0550H 为+85℃ ,0191H 为 25.0625℃ ,FC90H为-55℃
DSl820工作过程及时序
DSl820 工作过程中的协议如下
1、初始化
单总线上的所有处理均从初始化开始
2、ROM操作品令
总线主机检测到DS18B20的存在 便可以发出ROM操作命令之一
3、存储器操作命令
4、时序
主机使用时间隙来读写DS18B20的数据位和写命令字的位
(1)初始化
主机总线to时刻发送一复位脉冲(最短为480us的低电平信号), 接着在t1时刻释放总线并进入接收状态,DSl820在检测到总线的上升沿之后,等待15-60us,接DS18B20在t2时刻发出存在脉冲(低电平 持续60-240 us),如图中虚线所示
(2)写时间隙
当主机总线t o时刻从高拉至低电平时,就产生写时间隙,从to时刻开始15us之内应将所需写的位送到总线上,DS18B20在t。后15-60us间对总线采样,若低电平 写入的位是0,若高电平,写入的位是1,连续写2位间的间隙应大于1us
(3)读时间隙
主机总线to时刻从高拉至低电平时,总线只须保持低电平1 7ts。之后在t1时刻将总线拉高,产生读时间隙,读时间隙在t1时刻后t 2时刻前有效。t2距t0为15us 也就是说:t2时刻前主机必须完成读位,并在t0后的60us一120us内释放总线,读位子程序
代码
又臭又长的介绍,总不如代码来的实惠,直接上代码
onewire.c
#include "onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t)
{
while(t--);
}
//DS18B20芯片初始化
bit Init_DS18B20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(120);
DQ = 0;
Delay_OneWire(800);
DQ = 1;
Delay_OneWire(100);
initflag = DQ;
Delay_OneWire(50);
return initflag;
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(50);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(50);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(50);
}
return dat;
}
onewire.h
#ifndef _ONEWIRE_H
#define _ONEWIRE_H
#include <REGX52.H>
#define OW_SKIP_ROM 0xcc
#define DS18B20_CONVERT 0x44
#define DS18B20_READ 0xbe
//IC引脚定义
sbit DQ = P1^4;
//函数声明
void Delay_OneWire(unsigned int t);
void Write_DS18B20(unsigned char dat);
bit Init_DS18B20(void);
unsigned char Read_DS18B20(void);
#endif
实际使用部分代码
unsigned int ds18b20()
{
unsigned int LSB,MSB;
unsigned int temp = 0;
Init_DS18B20();
Write_DS18B20(0xcc);//跳过读序号列号的操作
Write_DS18B20(0x44);//启动温度转换
Init_DS18B20();
Write_DS18B20(0xcc);//跳过读序号列号的操作
Write_DS18B20(0xbe);//读取温度寄存器
LSB = Read_DS18B20();//读低8位
MSB = Read_DS18B20();//读高8位
temp = MSB;
temp = (temp<<8) |LSB;
temp *= 0.0625;
return temp;
}
本人水平有限,所有代码都是自己的风格书写,但是大致的应该是没有什么问题,希望对大家有帮助如果有哪里出错或者有更好的解法可以与我私信或在评论区里进行讨论
上一节:蓝桥杯单片机基础部分——4、DS1302时钟