DS20B18温度传感器+数码管显示

 

代码:

#include<reg52.h>

#define uint unsigned int 
#define uchar unsigned char
	
typedef unsigned int u16;

sbit LSA = P2^2;
sbit LSB = P2^3;
sbit LSC = P2^4;

sbit DS = P3^7;

char code smgduan[13]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
											0x7f,0x6f,0x00,0x80,0x40}; //0~9数码
char display_T[8];											
											
//毫秒延迟函数
void delayms(uint ms)
{
	uchar i;
	while(ms--)
		for(i=0;i<123;i++);
}	


//数码管显示函数
void Digdisplay()
{
	char i;
	for(i=0;i<8;i++)
	{
		switch(i)
		{
			case 0: LSC=1;LSB=1;LSA=1; break;   //显示第1位数码管
			case 1: LSC=1;LSB=1;LSA=0; break;		//显示第2位数码管
			case 2: LSC=1;LSB=0;LSA=1; break;   //显示第3位数码管
			case 3: LSC=1;LSB=0;LSA=0; break;   //显示第4位数码管
			case 4: LSC=0;LSB=1;LSA=1; break;   //显示第5位数码管
			case 5: LSC=0;LSB=1;LSA=0; break;   //显示第6位数码管
			case 6: LSC=0;LSB=0;LSA=1; break;   //显示第7位数码管
			case 7: LSC=0;LSB=0;LSA=0; break;   //显示第8位数码管
		}
		P0=smgduan[display_T[i]];  //发送数据
		delayms(1);      //延时1ms,让数码管不断显示
		P0=0x00;         //数码管消遣		
	}
}

//DS18B20初始化函数
uchar Ds18b20_init()
{
	unsigned char i;
	DS = 0;  //将总线拉低480US~960us
	i = 70;
	while(i--); //延时642us
	DS = 1;     //拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低
	i = 0;
	while(DS)   //等待DS18B20拉低总线
	{
		delayms(1);
		i++;
		if(i>5)   //等待大于5MS,说明总线没有被拉低,初始化失败
		{
			return 0; //初始化失败
		}
	}
	return 1;   //若为低电平,直接跳过while循环初始化成功
}

//写时序函数
void Ds18b20WriteByte(uchar dat)
{
	int i,j;
	for(j=0;j<8;j++)  //8位数据
	{
		DS = 0;             //每写入一位数据之前先把总线拉低1us
		i++;                
		DS = dat & 0x01;    //然后写入一个数据,从最低位开始。位运算的与运算,只要数据中有0,则相与后为0,只有为1相与为1
		i=6;                //延时初值
		while(i--);         //延时68us,因为持续时间最少为60us
		DS = 1;             //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值
		dat >>= 1;          //移位,从低位向高位写入数据,所以,最低为写入后,向右移,原来的次低位代替原来的低位。
	}
}

//读时序函数
uchar Ds18b20ReadByte()
{
	uchar byte,bi;
	uint i,j;
	for(j=8;j>0;j--)
	{
		DS = 0;  //先将总线拉低1us
		i++;
		DS = 1;  //然后释放总线
		i++;
		i++;     //延迟6us等待数据稳定
		bi = DS;  //读取数据,从最低位开始读取
		/*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0 */
		byte = (byte >> 1) | (bi << 7);  //现将byte右移一位,然后bi左移七位,相或得到数据
		i=4;        //读取完之后等待48us再接着读取下一个数
		while(i--);
	}
	return byte;
}

//转换温度启动指令
void Ds18b20ChangTemp()
{
	Ds18b20_init(); //初始化
	delayms(1);   
	Ds18b20WriteByte(0xcc); //写入跳过ROM操作命令(cc)
	Ds18b20WriteByte(0x44); //温度转换命令(44)
}

//读取温度命令
void Ds18b20ReadTempCom()
{
	Ds18b20_init();
	delayms(1);
	Ds18b20WriteByte(0xcc);   //跳过ROM操作命令
	Ds18b20WriteByte(0xbe);   //发送读取温度命令
}

//读取温度
int Ds18b20ReadTemp()
{
	int temp = 0;  
	uchar tmh,tm1;
	Ds18b20ChangTemp();      //先写入转换命令   
	Ds18b20ReadTempCom();    //然后等待转换完后发送读取温度命令
	tm1 = Ds18b20ReadByte(); //读取温度值共16位,先读低字节
	tmh = Ds18b20ReadByte(); //再读高字节
	temp = tmh;    
	temp <<= 8;              //移位运算,高字节左移8位,变为16位
	temp |= tm1;             //位运算中的或运算,组合
	return temp;             //高8位和低8位的组合
}

//数码管显示温度
void ds20b18display(int temp)
{
	float tp;
	if(temp < 0)
	{
		display_T[0] = 12;   //显示“-”
		temp=temp-1; //因为读取的温度是实际温度的补码,所以减1,再取反求出原码        
		temp=~temp;
		tp=temp;
		temp=tp*0.0625*100+0.5; //0.0625是精度
		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
		//算加上0.5,还是在小数点后面。
	}
	else
	{
		display_T[0] = 10;   //无显示
		tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量
		//如果温度是正的那么,那么正数的原码就是补码它本身
		temp=tp*0.0625*100+0.5;
		//留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点
		//后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就
		//算加上0.5,还是在小数点后面。
	}
	display_T[2] = temp/10000;          //显示百位
	display_T[3] = temp%10000/1000;     //显示十位
	display_T[4] = temp%1000/100;       //显示个位
	display_T[6] = temp%10/10;          //显示小数点后一位
	display_T[7] = temp%10;             //显示小数点后两位
	
	display_T[1] = 10;                 //无显示
	display_T[5] = 11;                 //显示“.”
}



void main()
{
	Ds18b20_init();
	while(1)
	{
		ds20b18display(Ds18b20ReadTemp());		
		Digdisplay();
	}
}



 结果图:

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值