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

📄 ds1820.c

📁 温度芯片DS1820读写程序实例(基于MSC-51)
💻 C
字号:
//**********************************************************************
//功能		: 实时时钟DS1820操作模块
//作者		: lihj
//创建日期	: 2004-07-10
//版本		: V1.0
//修改记录	: 
//***********************************************************************
#include <reg51.h>
#include <std.h>
#include <ds1820.h>

sbit TMDAT = P3^4;			//根据实实际情况设定

//函数功能:延时(12MHz晶振)
//输入参数:<count>延时时间长度,单位1ms
void Delay_ms (U16 count)	 					
{									
	U16 i;		       						
	while (count)							
	{								
		i = 123;						
		while (i>0) i--;					
		count--;						
    }									
}									

//函数功能:复位芯片(至少480us长的低电平信号)
void ResetChip (void)							
{		                  		 			
	U16 i;	
							
	TMDAT = 0;				//480us~960us长低电平:复位
	i = 150;							
	while (i--);         	//延时约900 uS(12Mhz时)	
	TMDAT = 1;							
	i = 5;								
	while (i--);		   	//DS1820检测到上升沿后,过15~60us后输出“存在”信号
}

//函数功能:	判断DS1820是否存在
//返回参数:	TRUE:芯片存在
//	    	FALSE:芯片不存在
U8 ChipPresenceCheck(void)				
{                     						
	U16 i;							
	
	ResetChip();
	
	//等待70us,应该检测到低电平
	i = 11;
	while(i--);
	if(TMDAT)
	{
		return FALSE;
	}
	
	//等待400us,应检测到高电平,低电平信号保持60~240us
	i = 65; 
	while (i--);
	if(TMDAT)
	{
		return TRUE;		
	}
	else
	{
		return FALSE;
	}	
}									

//函数功能:从总线上读取1位信号
bit RdBit (void)							
{                   							  
	U16 i;							
	bit b0;							
	TMDAT = 0; i++;				//下降沿之后,保持低电平至少1us						//
	TMDAT = 1; i++; i++;		//微量延时(既作输入又作输出的I/O脚,读数据时,先拉高电平)
	
	b0 = TMDAT;							
	i = 9; 
	while (i--);				//延时60us		
	return (b0);							
}									

//函数功能:从总线上读取1个字节信号
U8 RdByte (void) 			 			
{         								
	U8 i,j,byRdData=0;						
	
	for (i=0;i<8;i++)						
	{								
		j = RdBit ();
		byRdData >>= 1;						
		byRdData = (j << 7) | byRdData;				
	}								
	return (byRdData);							
}									

//函数功能:向总线上写一位数据	
void WrBit(bit b0)
{
	U8 i;
	
	if (b0)						
	{							
		TMDAT = 0;              		//产生一个下降沿,低电平至少保持1us	//
		i++; i++;               		             		
		TMDAT = 1;				//输出1				
		i = 9; while (i--); 			//高电平保持60us             		//
	}							
	else							
	{							
		TMDAT = 0;                           	// 写0 	
		i = 9; while (i--);  			//低电平保持60us           		//
		TMDAT = 1;					
		i++; i++;                            		
	}	
}

//向总线上写一个字节
void WrByte (U8 dat)					
{                						
	U8 i;						
	bit testb;							
	for (i=0;i<8;i++)						
	{								
		testb = dat & 0x01;					
		dat = dat >> 1;						
		WrBit(testb);						
	}								
}									

//函数功能	:写1-Wire协议头操作(复位芯片、选择芯片、写命令码)
//输入参数	:<pSN>芯片序号
//	  	: <byCommand>命令码
void SendHeaderData(U8 *pSN, U8 byCommand)
{
	U8 i;
	
	ResetChip();			//复位				
	Delay_ms(1);			//延时				

//***********************
//如果总线上只有一个设备,不需要选择芯片操作	
#if	(CHIP_NUM_IN_WIRE == 1)
	WrByte(0xcc);			//总线上只有一个设备,跳过芯片匹配步骤
#else	
	WrByte(0x55); 			//发送ROM匹配命令		
	for(i=0;i<8;i++)					
	{							
		WrByte(*pSN++);		//发送64位序列号	
	}
#endif							

	WrByte(byCommand);		//发送读取中间寄存器命令
}

//函数功能	: 读温度芯片中间寄存器(从偏移地址0开始)
//输入参数	: <pSN>温度芯片的序号(ROM码)
//		:  <pRdData> 存放读取出的数据
//		:  <byLen>需读取的数据的长度
void RdScratchpad(U8 *pSN, U8 *pRdData, U8 byLen)
{
	U8 i;
	
	//输入参数检查
	if(byLen > 9)
	{
		byLen = 9;
	}
	
	SendHeaderData(pSN, 0xbe);
	
	//读出数据
	for(i=0;i<byLen;i++)
	{
		*pRdData++ = RdByte();
	}
	
	ResetChip();			//复位芯片,结束读操作
	Delay_ms(1);			//延时	
}


//函数功能	: 写温度芯片中间寄存器(从偏移地址2开始)
//输入参数	: <pSN>温度芯片的序号(ROM码)
//		:  <pWrData> 写到中间寄存器的源数据
//		:  <byLen>写入数据的长度	
void WrScratchpad(U8 *pSN, U8 *pWrData, U8 byLen) 
{
	U8 i;
	
	//输入参数检查
	if(byLen > 2)
	{
		byLen = 2;
	}
	
	SendHeaderData(pSN, 0x4e);		//发送协议头			
	
	//写入数据
	for(i=0;i<byLen;i++)
	{
		WrByte(*pWrData++);
	}
	
	ResetChip();				//复位芯片,结束写操作
	Delay_ms(1);				//延时	
}

//函数功能:启动温度转换过程
//输入参数:<pSN>芯片序号
void StartConvertTmpt (U8 *pSN)							//
{       
	U8 byBusyFlag=0;
	 
	SendHeaderData(pSN, 0x44); 		//发送协议头           				
	
	while(1)				//某些情况下,这里可能出现死循环
	{
		byBusyFlag = RdByte();
		if(byBusyFlag == 0xff)
		{
			break;
		}
	}
	
	ResetChip ();				//复位,保持低电平480-960us					//
	Delay_ms(1);
}									

//函数功能	:读取温度
//输入参数	: <pSN>芯片序号
//输出参数	: 温度值,放大10倍的整数
S16 RdTemperture (U8 *pSN)								//
{                   							
	U8 byRdData[8];
	U8 byTEMP_READ;
	U8 byCOUNT_PER_C;
	U8 byCOUNT_REMAIN;
	S16 t;							
	float ft;
	
	
	RdScratchpad(pSN, byRdData, 8);		//读取数据,没有读CRC校验码

	//0.5摄氏度精度的计算方法
//	t = byRdData[0]+(byRdData[1]<<8);	//1表示0.5摄氏度
//	return t;
	
	t = byRdData[0]+(byRdData[1]<<8);
	byTEMP_READ = t>>1;
	byCOUNT_REMAIN = byRdData[6];
	byCOUNT_PER_C = byRdData[7];
					
	ft = (float)byTEMP_READ - 0.25 + (float)(byCOUNT_PER_C - byCOUNT_REMAIN)/(float)byCOUNT_PER_C;
	t = ft*10;
	
	return t;				//1表示0.1摄氏度							
}									

//函数功能	:读取芯片序号(只能在总线只有一个器件时调用)
//输入参数	: <pSN>返回的芯片序号存放地址
void ReadROM(U8 *pSN)									//
{									
	U8 i;
	
	ResetChip ();			//复位					
	Delay_ms (1);			//延时					
	WrByte(0x33);			//发送读序列号子程序			
	
	for(i=0;i<8;i++)
	{
		*pSN ++ = RdByte();	//读取第一个序列号,应为10H;		//
	}							
}									

//功能	:写温度报警上下限
//输入参数	: <pSN>温度芯片序号
//		:  <nHighAlarmLim> 温度报警上限
//		:  <nLowAlarmLim> 温度报警下限
U8 WrTmptAlarmLim(U8 *pSN, S16 nHighAlarmLim, S16 nLowAlarmLim)
{
	U8 byWrData[2];
	U8 byRdData[4];
	
	byWrData[0] = nHighAlarmLim;
	byWrData[1] = nLowAlarmLim;
	
	WrScratchpad(pSN, byWrData, 2);		//写入数据
	
	RdScratchpad(pSN, byRdData, 4);		//读出数据进行校验
	if((byRdData[2] != nHighAlarmLim) || (byRdData[3] != nLowAlarmLim))
	{
		return FALSE;
	}
	
	//将中间寄存器数据拷贝到E2RAM(存放报警限数据)
	SendHeaderData(pSN, 0x48);
	Delay_ms (6);				//延时6ms	
	ResetChip();				//复位芯片,结束本次操作
}
	
		
									

⌨️ 快捷键说明

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