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

📄 temp2.c

📁 通过ds18b20的读写时序
💻 C
字号:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int

uchar c[4]={0x08,0x04,0X02,0x01};
uchar seg7[17]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0xff};
uchar dot_seg[10]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10};
uchar dis[5]={0x10,0x10,0x10,0x10, 0x00};

uchar tplsb,tpmsb;
uchar	tick0=30;

uchar flaga;
sbit DQ=P3^7;
/* ********************延时t毫秒 ***************************/

void delay(uint t)
{
	uchar m;
	while(t--)
	{
		for (m=0;m<125;m++)
			;
	}
} 

/********************* 产生复位脉冲初始化DS18B20 **************************/
void TxReset(void)
{
	uint i;
	DQ = 0;/* 拉低约900us */	
	for(i = 100; i > 0; i--)
		;

	DQ = 1;	// 产生上升沿
	for(i = 4; i > 0; i--)
		;
}

/* ***********************等待应答脉冲 *********************/
void RxWait(void)
{
	uint i;
	while(DQ)
		;
	while(~DQ)
		;			// 检测到应答脉冲 

	for(i = 4; i > 0; i--)
		;
}

/***************** 读取数据的一位,满足读时隙要求 *************************/ 
bit RdBit(void)
{
	uint i;
	bit b;
	DQ = 0;
	i++;
	DQ=1;

	i++; 
	i++;			// 延时15us以上,读时隙下降沿后15us,DS18B20输出数据才有效
	b = DQ;

	for(i = 8; i > 0; i--)
		;
	return b;
}

/* ****************读取数据的一个字节 *****************************/
uchar RdByte(void)
{
	uchar i,j,b;
	b = 0;
	for(i = 1; i <= 8; i++)
	{
		j=RdBit();
		b=(j<<7)|(b>>1);
	}
	return(b);
}

/* ****************写数据的一个字节,满足写1和写0的时隙要求 *************/
void WrByte(uchar b)
{
	uint i;
	uchar j;
	bit btmp;
	for(j = 1; j <= 8; j++)
	{
		btmp = b&0x01;
		b = b>>1;		// 取下一位(由低位向高位)
		if(btmp)
		{
			/* 写1 */
			DQ=0;
			i++;
			i++;	// 延时,使得15us以内拉高
			
			DQ=1;
 		    for(i = 8; i > 0; i--)// 整个写1时隙不低于60us
				;	
	   	}
		else
		{
			/* 写0 */
			DQ = 0;			
		
			for(i = 8; i > 0; i--)// 保持低在60us到120us之间
				;
			DQ = 1;
			i++;
			i++;
		}
	}
}

/* **************启动温度转换 *******************/
void convert(void)
{
	TxReset();			// 产生复位脉冲,初始化DS18B20
	RxWait();			// 等待DS18B20给出应答脉冲
	delay(1);			// 延时
	WrByte(0xcc);		// skip rom 命令
	WrByte(0x44);		// convert T 命令
}

/**************** 读取温度值 *********************/
void RdTemp(void)
{
	TxReset();			// 产生复位脉冲,初始化DS18B20 
	RxWait();			// 等待DS18B20给出应答脉冲
	delay(1);			// 延时
	WrByte(0xcc);		// skip rom 命令
	WrByte(0xbe);		// read scratchpad 命令
	tplsb = RdByte();	// 温度值低位字节(其中低4位为二进制的“小数”部分)
	tpmsb = RdByte();	// 高位值高位字节(其中高5位为符号位)		
}

//*************************8数据处理程序************************//
void datadeal(void)
{
     	uchar temp1,temp2;
		int tt;
		int	tm;

		tm = tpmsb << 8;
		tm = tm | tplsb;
		if(tm < 0) 
			tm = 0 - tm;

		temp2 = tm & 0x0f;
		temp1 = (tm >> 4) & 0xff;
		
		if(dis[0] == 0)	
			dis[0] = 16;
		dis[1] = temp1 / 10 % 10;
		dis[2] = temp1 % 10;
		flaga = tpmsb >> 3;
		flaga = flaga & 0x01;
		tt = tplsb & 0x0f;
		if(flaga == 0)
			tt = 625*tt;
		else 
		{
			tt = 0 - tt;
			tt = tt & 0x0f;
			tt = tt * 625;
		}
		dis[3] = tt / 1000;
		dis[4] = tt / 100 % 10;
		dis[5] = tt / 10 % 10;
		if(dis[1] >= 5)
			P1 = 0x08;
		else 
			P1 = 0x20;
		if(dis[1] == 0)
			dis[1] = 16;
		if(dis[4] > 4)
			dis[4] = dis[4]+1;
		if(dis[4] > 9)
			dis[2] += 1;
		if(dis[2] > 9)
			dis[1] += 1;
}
//**************显示程序****************//
void display(void) interrupt 1
{   
	static uchar	i;   
	
	TH0 = 0xD8;
	TL0 = 0xF0;	 
	P2 = c[i];  
	if(i == 0)
	{
		if(flaga)	
			P0 = 0xbf;
		else	
			P0 = seg7[dis[1]];
	}
	else if(i == 1)
		P0 = dot_seg[dis[i+1]];
	else  
		P0 = seg7[dis[i+1]];
	i = (i + 1) % 4;
}

void initINT(void)
{
	TMOD = 0x01;
	TH0 = 0xD8;
	TL0 = 0xF09;
	ET0 = 1;
	EX0 = 1;
    TR0=1;    
	EA = 1;
}

/* 主程序,读取的温度值最终存放在tplsb和tpmsb变量中。
   tplsb其中低4位为二进制的“小数”部分;tpmsb其中高
   5位为符号位。真正通过数码管输出时,需要进行到十进
   制有符号实数(包括小数部分)的转换。*/      
void main(void)
{	
	initINT();
	P0=0xff;
	P1 = 0;
  	while(1)
	{	
		convert();		// 启动温度转换,需要750ms
		RdTemp();		// 读取温度
		datadeal();
		delay(200);
	}
}

⌨️ 快捷键说明

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