DS18B20测温基于stc89c52单片机

在开头说明一下:本程序只用了温度测量这一个功能,其他功能并未在此涉及。
鄙人不才,如有错误还望各位大佬指点。
趁这段时间充裕把DS18B20温度传感器的一些东西写一写(主要是程序)。
Dallas半导体公司的数字化温度传感器DS18B20是世界上第一片支持“一线总线”接口的温度传感器,即只有一根数据线。它的适用电压为3V-5V,可程序设定9-12位的分辨率,精度为±0.5℃,测温范围-55℃~+125℃。
DS18B20的使用难点主要在延时时间上,只要把延时搞懂了那么除测温以外的功能也就不难了。相信你们手里都有芯片手册,手册上的时序画的明明白白,我也就不多说废话了,直接上程序

/**************************************
     平台STC89C52    晶振11.0592MHz
     6位共阴数码管    74HC573锁存器
**************************************/
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
uchar code table[]={0x3f,0x06,0x5b,0x4f,0x66,
					0x6d,0x7d,0x07,0x7f,0x6f,     ///不带小数点0~9
					0xbf,0x86,0xdb,0xcf,0xe6,
					0xed,0xfd,0x87,0xff,0xef,     ///带小数点0~9
					0x40,0x00};
uchar tem[2];               ///用来存放两字节的温度
uchar wendu[5];             ///用来存放(正负)十进制的温度
uchar fuhao;
bit flag;
sbit DQ=P2^2;               ///传感器的信号线
sbit dula=P2^6;             ///数码管段选端
sbit wela=P2^7;             ///数码管位选端
void delayus(uchar t)
{
	while(t--);
}
void delayms(uint z)  
{
	uint i,j;
	for(i=z;i>0;i--)
		for(j=110;j>0;j--);
}
void delaynop()
{
	_nop_();
}
/***************************************
        DS18B20复位函数
***************************************/
void res()
{
	DQ=1;
	_nop_(); 
	_nop_();
	_nop_();
	DQ=0;
	delayus(90);      ///约600us
	DQ=1;
	delayus(9);       ///约70us
	flag=DQ;          ///若flag为0则复位成功,否则失败
	delayus(80);      ///约530us
	DQ=1;
	_nop_();
}
/*************************************
           写一个字节函数
*************************************/
void ds18b20_write_byte(uchar dat)
{
	uchar i;
	bit j;
	for(i=8;i>0;i--)
	{
		j=dat&0x01;
		dat=dat>>1;
		DQ=1;
		_nop_();
		if(j==0)
		{
			DQ=0;
			delayus(9);      ///约70us
			DQ=1;
			_nop_();
		}
		else
		{
			DQ=0;
			_nop_();
			_nop_();
			_nop_();
			DQ=1;
			delayus(9);
		}
	}
}
/************************************
          读一个字节函数
************************************/
bit ds18b20_read_bit()
{
	bit j;
	DQ=1;
  	_nop_();
  	DQ=0;
  	delaynop();
 	DQ=1;
 	_nop_();
  	j=DQ;
  	delayus(8);
  	DQ=1;
  	_nop_();
 	return j;
 }
uchar ds18b20_read_byte()
{
	uchar i,j,dat;
	for(i=8;i>0;i--)
	{
		j=ds18b20_read_bit();
		dat=(dat>>1)|(j<<7);
	}
	return dat;	
}
/*************************************
			开始温度转换函数
*************************************/
void ds18b20_starttempreture()
{
	res();
	ds18b20_write_byte(0xcc);       ///写跳过序列号的命令
	ds18b20_write_byte(0x44);		///写开始温度转换的命令
}
/************************************
			计算读取温度函数
************************************/
void ds18b20_transtemperature()
{
	uint temp_i;
	uchar temp;
	res();
	ds18b20_write_byte(0xcc);       ///写跳过序列号的命令
	ds18b20_write_byte(0xbe);       ///写读取温度的命令
	tem[0]=ds18b20_read_byte();     ///温度低位
	tem[1]=ds18b20_read_byte();     ///温度高位
	_nop_();
	fuhao=tem[1]&0xf0;
	if(fuhao==0xf0)                 ///表达式为真则为负
	{
		if(tem[0]==0x00)            ///表达式为真则低位有进位
		{
			tem[0]=~tem[0]+1;
			tem[1]=~tem[1]+1;
		}
		else
		{
			tem[0]=~tem[0]+1;
			tem[1]=~tem[1];
		}
	}
	if(fuhao==0xf0)
	{wendu[0]=20;}
	else
	{wendu[0]=21;}                 ///符号位
	temp=(tem[1]<<4)|(tem[0]>>4);
	wendu[1]=temp%100/10;          ///十位
	wendu[2]=temp%10;              ///个位
	temp=tem[0]&0x0f;
	temp_i=temp*0.0625*10000;
	wendu[3]=temp_i/1000;          ///十分位
	wendu[4]=temp_i%1000/100; 	   ///百分位
}
/**************************************
			数码管显示函数
**************************************/
void display(uchar fu,uchar shi,uchar ge,uchar shifen,uchar baifen)
{
	wela=0;
	P0=table[fu];              ///显示符号位
	dula=1;
	dula=0; 
	P0=0x3e;
	wela=1;
	wela=0;
	delayms(1);
	P0=table[shi];              ///显示十位
	dula=1;
	dula=0; 
	P0=0x3d; 
	wela=1;
	wela=0;
	delayms(1);
	P0=table[ge+10];            ///显示个位,带小数点
	dula=1;
	dula=0;
	P0=0x3b;
	wela=1;
	wela=0;
	delayms(1);
	P0=table[shifen];           ///显示十分位
	dula=1;
	dula=0;
	P0=0x37;
	wela=1;
	wela=0;
	delayms(1);
	P0=table[baifen];           ///显示百分位
	dula=1;
	dula=0;
	P0=0x2f;
	wela=1;
	wela=0;
	delayms(1);
}
/***************************************
					主函数
***************************************/
void main()
{
	while(1)
	{
		res();
		ds18b20_write_byte(0xcc);
		ds18b20_write_byte(0x7f);
		if(flag==0)
		{
			ds18b20_starttempreture();
			ds18b20_transtemperature();
			display(wendu[0],wendu[1],wendu[2],wendu[3],wendu[4]);
		}
		else
		{
			display(20,20,20,20,20);
		}
	}
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值