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

📄 ds18b20.h

📁 1602+1802液晶温度显示
💻 H
字号:
/*==================================================================

[注]:STC5408AD的晶振频率为11.0592MHz

====================================================================*/

#ifndef __DS18B20_H__
#define __DS18B20_H__

#include <intrins.h>

sbit ds=P1^7;				//DS18B20 与STC5408AD 接口

#define uchar unsigned char
#define uint  unsigned int

extern uchar examp[40];		//显示屏的要显示的数据 	LCD 20*2
uchar temperature[2];		//测温读出数据 0为高位(三位有用),1为低位(高四位,四位小数)
uchar flag=0;				//1920存在标志位
uint temp=0;

/*延时函数*/
void TempDelay (uchar us)
{
   while(us--);
}

void delay(uint count) //延时子函数
{
	uint i;
	while(count){
	i=200;
	while(i>0)
		i--;
	count--;
	}
}

/*****************************************
时序:初始化时序、读时序、写时序。
所有时序都是将主机(单片机)作为主设备,单总
线器件作为从设备。而每一次命令和数据的传输
都是从主机主动启动写时序开始,如果要求单总
线器件回送数据,在进行写命令后,主机需启动
读时序完成数据接收。数据和命令的传输都是低
位在先。
初始化时序:复位脉冲 存在脉冲
        读;1 或 0时序
        写;1 或 0时序
只有存在脉冲信号是从18b20(从机)发出的,其
它信号都是由主机发出的。
存在脉冲:让主机(总线)知道从机(18b20)已
经做好了准备。
******************************************/


/*--------------------------------------------------------------------------------------------------------------------
初始化:检测总线控制器发出的复位脉冲
和ds18b20的任何通讯都要从初始化开始

初始化序列包括一个由总线控制器发出的复位脉冲
和跟在其后由从机发出的存在脉冲。

初始化:复位脉冲+存在脉冲

具体操作:
总线控制器发出(TX)一个复位脉冲 (一个最少保持480μs 的低电平信号),然后释放总线,
进入接收状态(RX)。单线总线由5K 上拉电阻拉到高电平。探测到I/O 引脚上的上升沿后
DS1820 等待15~60μs,然后发出存在脉冲(一个60~240μs 的低电平信号)。

具体看"倒塌 18b20"文档里的 " 单线复位脉冲时序和1-wire presence detect "的时序图
-------------------------------------------------------------------------------------------------------------------*/
void ds_reset(void)
{
   ds=1;
   _nop_(); _nop_(); _nop_(); _nop_(); _nop_();       //5us
   ds=0;					//	拉低总线
   TempDelay(250);			// 保持 480us
   TempDelay(250);
   ds=1;           		//(释放总线)产生复位脉冲后,微处理器释放总线,让总线处于空闲状态,原因查18b20中文资料
   TempDelay(30); 		//释放总线后,以便从机18b20通过拉低总线来指示其是否在线(等待回复)
   if(ds==0)
        flag=1;      	//初始化1820成功
   else
        flag=0;       	//初始化1820失败(或1820不存在)
	TempDelay(250);   	//存在检测低电平时间:60~240us,所以延时约140us(等待结束信号)
   ds=1;          		//再次拉高总线,让总线处于空闲状态
}

/*----------------------------------------
读/写时间隙:
DS1820 的数据读写是通过时间隙处理
位和命令字来确认信息交换。
------------------------------------------*/
uchar ds_read_byte(void ) //读一字节
{
	unsigned char i,TmepData;
	TmepData=0;

	for (i=8;i>0;i--){
		TmepData>>=1;
		ds = 0;   								//拉低总线,产生读信号
		_nop_(); _nop_(); _nop_(); _nop_(); 	//延时4us
		ds = 1; 								//释放总线,准备读数据
		_nop_(); _nop_(); _nop_(); _nop_(); _nop_();
		if (ds == 1)
   			TmepData |= 0x80;
		TempDelay(40);
		ds = 1;  								//拉高总线,准备下一位数据的读取.
 	}
 	return (TmepData);							//返回读到的数据
}


//向 1-WIRE 总线上写一个字节
void ds_write_byte(char val)
{
	uchar i;

	for (i=8; i>0; i--){  						// 一次写一位
    	ds=0;
		_nop_(); _nop_(); _nop_(); _nop_();
    	ds = val&0x01;
    	TempDelay(40); 
    	ds = 1;
    	val=val/2;
  	}
	TempDelay(70);
}

/*****************************************
主机(单片机)控制18B20完成温度转换要经过三个步骤:
每一次读写之前都要18B20进行复位操作,复位成功后发送
一条ROM指令,最后发送RAM指令,这样才能对DS18b20进行
预定的操作。
复位要求主CPU将数据线下拉500us,然后释放,当ds18B20
受到信号后等待16~60us,后发出60~240us的存在低脉冲,
主CPU收到此信号表示复位成功
******************************************/

/*----------------------------------------
进行温度转换:
先初始化
然后跳过ROM:跳过64位ROM地址,直接向ds18B20发温度转换命令,适合单片工作
发送温度转换命令
------------------------------------------*/

void tem_change()
{
	ds_reset();
	ds_write_byte(0xcc);
	ds_write_byte(0x44);
	delay(1);              //约2ms
}

/*----------------------------------------
获得温度:
------------------------------------------*/
void get_temperature()
{
	ds_reset();
	ds_write_byte(0xcc);
	ds_write_byte(0xbe);
	temperature[0]=ds_read_byte();
	temperature[1]=ds_read_byte();

	ds_reset();
	ds_write_byte(0xcc);
	ds_write_byte(0x44);
}

void display()
{
	uchar temp_data,temp_data_2;
	uint TempDec; 						//用来存放4位小数
	temp_data = temperature[1];
	temp_data &= 0xf0;  				//取高4位
	if (temp_data==0x00){
			temp_data = temperature[1]<<4;  		//取高字节低4位(温度读数高4位)
			temp_data_2 = temperature[0]>>4; 		//取低字节高4位(温度读数低4位)
			temp_data = temp_data | temp_data_2; 	//组合成完整数据
			examp[0]=0x2b;
			examp[1]=temp_data/100+0x30;   			//取百位转换为ASCII码
			examp[2]=((temp_data/10)%10)+0x30;  	//取十位转换为ASCII码
			examp[3]=(temp_data%10)+0x30;  			//取个位转换为ASCII码
			examp[4]=0x3a;
			temperature[0]&=0x0f;  					//取小数位转换为ASCII码
			TempDec = ((temperature[0]&0x0f)*0.0625)*10000;		//小数部分,扩大1万倍
			examp[5] = TempDec/1000+0x30;   					//取小数个位
			examp[6] = (TempDec%1000)/100+0x30;  				//取小数十位
			examp[7] = ((TempDec%1000)%100)/10+0x30;			//取小数百位
			examp[8] = ((TempDec%1000)%100)%10+0x30;			//取小数千位
			}
	else{								//求补取反加1,判断低8位是否有进位
		if (temperature[0]==0){ 		//有进位,高8位取反加1
    		temperature[0]=~temperature[0]+1;
   			temperature[1]=~temperature[1]+1;
			}
		else{ 				//没进位,高8位不加1
			temperature[0]=~temperature[0]+1;
			temperature[1]=~temperature[1];
			}
	temp_data = temperature[1]<<4;		//取高字节低4位(温度读数高4位)
	temp_data_2 = temperature[0]>>4; 	//取低字节高4位(温度读数低4位)
	temp_data=temp_data|temp_data_2; 	//组合成完整数据(整数部分)
	examp[0]= 0x2d;
	examp[1]=temp_data/100+0x30;   		//取百位转换为ASCII码
	examp[2]=(temp_data%100)/10+0x30;  	//取十位转换为ASCII码
	examp[3]=(temp_data%100)%10+0x30;  	//取个位转换为ASCII码
	examp[4]=0x3a;
	TempDec = ((temperature[0]&0x0f)*0.0625)*10000;		//小数部分,扩大1万倍
	examp[5] = TempDec/1000+0x30;   					//取小数个位转换为ASCII码
	examp[6] = (TempDec%1000)/100+0x30;  				//取小数十位转换为ASCII码
	examp[7] = ((TempDec%1000)%100)/10+0x30;			//取小数百位转换为ASCII码
	examp[8] = ((TempDec%1000)%100)%10+0x30;			//取小数千位转换为ASCII码
	}
}

/*----------------------------------------
读ROM  
------------------------------------------*/
/*
void ds_read_rom()                  //这里没有用到
{
   uchar a,b;
   ds_reset();
   delay(30);
   ds_write_byte(0x33);
   a=ds_read_byte();
   b=ds_read_byte();
}
*/

#endif

⌨️ 快捷键说明

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