项目10—DS18B20温度计设计(正负)

DS18B20是一款常用的高精度的单总线数字温度测量芯片。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

参数:

测温范围为-55℃到+125℃,在-10℃到+85℃范围内误差为±0.4°。

返回16位二进制温度数值

主机和从机通信使用单总线,即使用单线进行数据的发送和接收

在使用中不需要任何外围元件,独立芯片即可完成工作。

掉电保护功能 DS18B20 内部含有 EEPROM ,通过配置寄存器可以设定数字转换精度和报警温度,在系统掉电以后,它仍可保存分辨率及报警温度的设定值。

每个DS18B20都有独立唯一的64位-ID,此特性决定了它可以将任意多的DS18b20挂载到一根总线上,通过ROM搜索读取相应DS18B20的温度值

宽电压供电,电压2.5V~5.5V

DS18B20返回的16位二进制数代表此刻探测的温度值,其高五位代表正负。如果高五位全部为1,则代表返回的温度值为负值。如果高五位全部为0,则代表返回的温度值为正值。后面的11位数据代表温度的绝对值,将其转换为十进制数值之后,再乘以0.0625即可获得此时的温度值。

DS18B20一共有三个引脚,分别是:

  • GND:电源地线
  • DQ:数字信号输入/输出端。
  • VDD:外接供电电源输入端。

DS18B20的工作步骤可以分为三步:

1.初始化DS18B20
2.执行ROM指令
3.执行DS18B20功能指令

其中第二步执行ROM指令,也就是访问每个DS18B20,搜索64位序列号,读取匹配的序列号值,然后匹配对应的DS18B20,如果我们仅仅使用单个DS18B20,可以直接跳过ROM指令。而跳过ROM指令的字节是0xCC。

我们这里用74HC573,排阻,51单片机,和DS18B20.

仿真如下: 

 

写程序时,我们把main.c和ds18b290.c分开写,即在main.c中包含ds18b20.c。

 

主程序如下:

#include<reg51.h>
#include<ds18b20.c>
unsigned char cp,cp1,temp,temp1;
unsigned char seven_seg[] = {0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
sbit LE  = P1^0;
void timer0_isr(void) interrupt 1
{
	TH0 = (65536 - 2500) / 256;
	TL0 = (65536 - 2500) % 256;
  P0 = 0xff;
	if(cp == 0){P0 = 0x01;LE = 0;LE = 1;LE = 0;P0 = seven_seg[c];}
	if(cp == 1){P0 = 0x02;LE = 0;LE = 1;LE = 0;P0 = seven_seg[temp1 % 10] & 0x7f;}
	if(cp == 2){P0 = 0x04;LE = 0;LE = 1;LE = 0;if(temp1 < 10)P0 = 0xff;else P0 = seven_seg[temp1 / 10];}
	if(cp == 3){P0 = 0x08;LE = 0;LE = 1;LE = 0;if((temp & 0x80) == 0x80)P0 = 0xbf;else P0 = 0xff;}
	cp++;if(cp >= 4)cp = 0;
	//产生时间
	cp1++;
	if(cp1 >= 200)
	{
		cp1 = 0;
		temp = Read_Temperature();
			if((temp & 0x80) == 0x80)
			{
			 	temp1 = 0xff - temp;
				c = (0x0f - c)*0.625 + 1;
				if(c == 10){temp1 = temp + 1;c = 0;}
			}
			else {temp1 = temp;c = c*0.625;}
	}
}
void timer0_init(void)
{
	TMOD = 0x01;
	TH0 = (65536 - 2500) / 256;
	TL0 = (65536 - 2500) % 256;
	EA = 1;
	ET0 = 1;
	TR0 = 1;
}
void main(void)
{
	timer0_init();
	while(1);
}

ds18b20的驱动程序如下:

/*********************************************************************/
//读取DS18B20温度,通过数码管显示,在温度超过35度时继电器吸合																						
#define uchar unsigned char 
#define uint unsigned int
uchar a,b,c;
sbit DQ = P1^2;
void delay(uint x)
{
	while(x--);  
}
void Init_DS18B20(void)
{
	unsigned char x=0;
	DQ = 1;         //DQ复位
	delay(8);       //稍做延时
	DQ = 0;    	    //单片机将DQ拉低
	delay(80);   	//精确延时 大于 480us
	DQ = 1;      	//拉高总线
	delay(14);
	x=DQ;      	    //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
	delay(20);
}
/******************************从18B20中读一个字节****************************/
uchar Read_OneChar(void)
{
	uchar i = 0;
	uchar dat = 0;
	for (i=8;i>0;i--)
	{
  		DQ = 0;          // 给脉冲信号
  		dat >>= 1;
  		DQ = 1;          // 给脉冲信号
  		if(DQ)
  		dat |= 0x80;
  		delay(8);
	}
	return(dat);
}
/******************************向18B20中写一个字节****************************/
void Write_OneChar(uchar dat)
{
	uchar i=0;
	for (i=8; i>0; i--)
	{
		DQ = 0;
		DQ = dat&0x01;
		delay(10);
		DQ = 1;
		dat >>= 1;
	}
	delay(8);
}
/***********************************读取温度**********************************/
uchar Read_Temperature(void)
{
	uchar i = 0,t = 0;
	Init_DS18B20();
	Write_OneChar(0xcc); 	// 跳过读序号列号的操作
	Write_OneChar(0x44); 	// 启动温度转换
	Init_DS18B20();
	Write_OneChar(0xcc); 	//跳过读序号列号的操作
	Write_OneChar(0xbe); 	//读取温度寄存器等(共可读9个寄存器) 前两个就是温度
	a = Read_OneChar();   	//读取温度值低位
	b = Read_OneChar();   	//读取温度值高位
	c = 0x0f & a;			//得到小数部分
	a = a >> 4;				//低位右移4位
	b = b << 4;             //高位左移4位
    t = a | b;				//得到8位温度的整数部分,最高为符号位
	return(t);
}
/*

运行结果:

 

 

 

 

  • 5
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

单旦羊

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值