⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ds18b20温度处理.txt

📁 完美的可以时时和四号实现18b20温度测试
💻 TXT
字号:
#include<reg52.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int

sbit ds18b20=P2^2;		//DS18B20端口设置

sbit en_573=P2^1;     //74H573

sbit _595dat=P2^5;
sbit _595loc=P2^4;
sbit _595clk=P2^3;     //74H595

uchar num,dat,flag,tt,count;
uint temper;
bit presence;
uchar code table[]={
0x3f,0x06,0x5b,0x4f,
0x66,0x6d,0x7d,0x07,
0x7f,0x6f,};

/****************不同级别的延时函数,对于延时函数来说(--n)是在毫秒级较准确的运算大约为3us,且有(2n+1)us运算。
其它大都不太准确,当然这又要考虑到单片机晶振的问题。频率不同延时也有差别**********************************/

void delus(uint num)		//us级延时函数  
{
  while( --num ) ;
}

void delay(uchar t)			//ms级别延时			
{
	uchar i,j;
	for(j=t;j>0;j--)
		for(i=110;i>0;i--);
}

/*******************数码管(ssled)显示部分 
包括74HC573数据锁存部分和74HC595地址为锁存部分
SSLED地址位为595高三位**********************/

/**********调用函数,指定SSLED显示数据********************/
void hc_573(uchar dat)		//573数据锁存
{
	en_573=0;				//使能端开			
	P0=dat;					//录入数据
	delay(5);				//延时,时数据写入完整
	en_573=1;				//锁存
}

/**********调用函数,指定SSLED显示地址,595中高三位控制了数码管位选择,
故需要移位处理,同时又要兼顾其它位上数字不变之后才能录入锁存器********************/
void led_595(uchar add)
{
	uchar i=0,temp;
	temp=dat;			//SSLED地址为变换位595高三位
	add=add<<5;
	temp=temp&0x1f;
	temp=temp|add;
	
	_595loc=0;				//595移位锁存使能开,八位移位锁存
	for(i=0;i<8;i++)
	{	
		_595clk=0;				//一个上升脉冲录入一位
		if((temp<<i)&0x80)
			_595dat=1;
		else
			_595dat=0;	
	
		_595clk=1;
	 }
	_595loc=1;					//锁存数据
	delay(5);
	
}
/**********调用函数,指定SSLED地址并显示为了后面显示没有将table表格写入更多情况是
hc_573(table【dat】);代替hc_573(dat);当然前面要加上十六位数表格********************/
void dis_led(uchar add,uchar dat)		//指定SSLED地址并显示
{
	led_595(add);			//录入数据
	hc_573(dat);			//录入地址
	delay(5);				//延时,保证录入完整
	P0=0x00;					//消隐
}


/**********
		DS18B20温度测量并显示在八位数码管上
DS18B20是单总线控制数字温度传感器,控制过程完全是对时序的控制和掌握
因此它对时间(毫秒级:us)要求时非常严格的,少一点误差就无法准确测量出温度示数
这就又要考虑到单片机晶振的问题。(--n:适毫秒级大约3u时间,且有(2n+1)us运算。
其它大都不太准确)
********************/

/*************DS18B20的复位初始化及返回存在***************/
tem_reset(void)
{  
     ds18b20 = 1 ;      //ds18b20复位
     delus(8) ;    //稍做延时

     ds18b20 = 0 ;      //单片机将ds18b20拉低
     delus(90) ;   //精确延时 大于 480us

     ds18b20 = 1 ;       //拉高总线
     delus(8) ;

     presence = ds18b20 ;    //如果=0则初始化成功 =1则初始化失败
     delus(100) ;
     ds18b20 = 1 ; 
     
     return(presence) ; //返回信号,0=presence,1= no presence
}



/*******************读取一个字*******************/
tem_read(void)
{
	uchar i = 0, dat = 0 ;
	for (i = 8 ; i > 0 ; i--)
   {
	    ds18b20 = 0 ; // 给脉冲信号
	    dat >>= 1 ;		//数据右移一位
	    ds18b20 = 1 ; // 给脉冲信号
	
	    if(ds18b20)			//判断为=1保存1到高位,=0忽略(保存为0)
	     dat |= 0x80 ;
	    delus(4) ;		//稍作延时
   }

    return (dat) ;
}  


/*************************写入一个字节 *********************/
void tem_write(uchar com)
{
  unsigned char i = 0 ;
  for (i = 8 ; i > 0 ; i--)
  {
    ds18b20 = 0 ;				//给脉冲信号
    ds18b20 = com&0x01 ;		//判断并发送字节
    delus(5) ;

    ds18b20 = 1 ;
    com>>=1 ;		//数据右移,并保存
  }
}


/********************读取十六位字节温度表示*******************************/
uint read_tem()
{
	uchar temh,teml;
	uint temp;
	while(tem_reset());			//总线复位,响应存在
	tem_write(0xcc);            //发跳跃ROM命令
	tem_write(0x44);            //发温度转换命令

	while(tem_reset());			//总线复位,响应存在
	tem_write(0xcc);            //发跳跃ROM命令
	tem_write(0xbe);		//读取暂存储器温度

	teml=tem_read();    //读温度值的第字节
	temh=tem_read();    //读温度值的高字节
	temp=temh;
	temp<<=8;                                               
	temp=temp|teml;	// 两字节合成一个整型变量。
	return temp; 					//返回温度值

	
}

/*******************
*读取八位字节温度表示,在处理数据时要先读低八位,再读高八位。型如{dsl=read_tem;dsh=read_tem;}
由于处理八位数显示较麻烦所以大都作者会选择合并再处理如{uint temper;temper=dsh;tesmper=(dsh<<8)|dsl;}
之后的处理是十六位数读取
**********************************/
/*
uchar read_tem(void)
{
	uchar tem;
	uint temp;
	tem_reset();	//总线复位

	tem_write(0xcc);            //发跳跃ROM命令
	tem_write(0x44);         //发温度转换命令
	
	tem_reset(); 
	em_write(0xcc);            //发跳跃命令
	tem_write(0xbe);			//读取暂存储器温度
	
	tem=tem_read();    //读温度值的八位字节                                             
	return temp; 					//返回温度值

}

*/

/********************处理十六位读数并在数码管上显示,
数据关系:低四位乘以625(12位分频)是小数部分,中间八位是整数部分,高四位是符号位。
负数时取补码[取反加一(tem=~tem+1)处理与正数相同。十六位数据处理优点在于处理负数部分:
取反加一时会有遇到进位问题。这一进位将直接加到整数位,不再而外处理。********************************/
void dis_tem(uint ds_tem)
{

	char i,tem;
	int dsh,dsl,ds;
	ds=(uchar)(ds_tem>>8);
	ds=ds&0xf0;
	if(ds==0xf0)			//负数的处理
	{
		ds_tem=~ds_tem+1;		//取负数补码
		dis_led(7,0x40);
	}
	dsl=ds_tem&0x0f;			//整理得到可显示小数部分
	dsh=(ds_tem>>4)&0x0ff;		//得到可显示整数部分
	dsl=dsl*625;
	
	for(i=0;i<4;i++)			//小数部分
	{
		dis_led(i,table[dsl%10]);
		dsl=dsl/10;
	 }

	dis_led(i++,table[dsh%10]|0x80);		//个位数显示,带小数点
	dsh=dsh/10;

	tem=dsh/10;			//百位数显示,0不显示,否则显示
	if(tem==0)
		dis_led(6,0x00);
	else
		dis_led(6,table[tem]);

	tem=dsh%10;				//十位数显示,0不显示,否则显示
	if(tem==0)
		dis_led(5,0x00);
	else
		dis_led(5,table[tem]);

		

}

/********************主函数********************************/
main()
{	

  	while(tem_reset());	//总线复位
	tem_write(0xcc);            //发命令
	tem_write(0x44);            //发转换命令
	delay(1000);						//延时使温度转化完整

	while(1)
	{
		dis_tem(read_tem());		//显示温度读数,	
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -