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

📄 ds18b20.c

📁 使用凌阳SPCE061A为主控核的测温程序
💻 C
字号:
/*********************************************************************************************/
//单总线数字温度传感器DS18B20驱动程序
//---------------------------------------------------------------------
//连接方式:
//			DQ:IOB15
//---------------------------------------------------------------------
//日期:	2008.08.30
//作者:	LiPeng
/*********************************************************************************************/

#include "SPCE061A.H"
#include "ds18b20.h"

/*外部函数声明*/
extern void Set_System_Clock();
extern void Renew_System_Clock();
extern void F_18B20_Delaynus(unsigned int n);
extern void Disp_Strs(int line,int row,char *strings);

/*********************************************************************/
//功能:	IO口初始化
//参数:	无
//返回值:	无
/*********************************************************************/
void F_18B20_IOInitial()
{
	*P_IOB_Dir&=(0xffff-0x8000);//定义IOB15为悬浮式输入端口,以后如若
	*P_IOB_Attrib|=0x8000;		//写数据,只需将*P_IOB_Dir数据更改即可
	*P_IOB_Data|=0x8000;
}

/*********************************************************************/
//功能:	将IOB15更改为输出口
//参数:	输入输出标志,'1'代表输出,反之为输入
//返回值:	无
/*********************************************************************/
void F_18B20_ChgIODir(unsigned int DirFlag)
{
	if(DirFlag)//'1',更改为输出
		*P_IOB_Dir|=0x8000;
	else
		*P_IOB_Dir&=(0xffff-0x8000);//否则,更改为输入
}

/*********************************************************************/
//功能:	写时序-写1
//参数:	无
//返回值:	无
/*********************************************************************/
void F_18B20_Write1()
{
	F_18B20_ChgIODir(1);//将IOB15更改为输出
	DQ_L;
	F_18B20_Delaynus(5);//主机拉低单总线15us内释放总线,则向单总线器件写1
	F_18B20_ChgIODir(0);//恢复IOB15为悬浮式输入
	F_18B20_Delaynus(50);//读写时序至少60us,实现延时控制读写时间	
}

/*********************************************************************/
//功能:	写时序-写0
//参数:	无
//返回值:	无
/*********************************************************************/
void F_18B20_Write0()
{
	F_18B20_ChgIODir(1); //将IOB15更改为输出
	DQ_L;
	F_18B20_Delaynus(70);//主机拉低单总线至少保持60us低电平,则向单总线器件写0
	F_18B20_ChgIODir(0); //恢复IOB15为悬浮式输入
}

/*********************************************************************/
//功能:	读时序-读一位数据
//参数:	无
//返回值:	读出的一位数据值
/*********************************************************************/
unsigned int F_18B20_ReadDQ()
{
	unsigned int ReadTemp=0;
	F_18B20_ChgIODir(1); //将IOB15更改为输出
	DQ_L;
	F_18B20_Delaynus(2); //注意此处时序,更改有可能造成读取错误
	F_18B20_ChgIODir(0); //恢复IOB15为悬浮式输入
	F_18B20_Delaynus(2);
	ReadTemp=*P_IOB_Data;//读入DQ线值
	F_18B20_Delaynus(40);
	ReadTemp&=0x8000;
	ReadTemp>>=8;
	return ReadTemp;
}

/*********************************************************************/
//功能:	向单总线器件写1字节
//参数:	要写入的字节数据
//返回值:	无
/*********************************************************************/
void F_18B20_WriteByte(unsigned int Data)
{
	unsigned int ByteCnt;
	for(ByteCnt=0;ByteCnt<8;ByteCnt++)
	{
		CL_Wdog;
		if(Data&0x01)
			F_18B20_Write1();
		else
			F_18B20_Write0();
		Data>>=1;//低位开始写起,依次右移8次
	}
}

/*********************************************************************/
//功能:	从单总线器件读1字节
//参数:	无
//返回值:	读出的字节数据
/*********************************************************************/
unsigned int F_18B20_ReadByte()
{
	unsigned int ByteCnt,ReadData=0x00;
	for(ByteCnt=0;ByteCnt<8;ByteCnt++)
	{
		CL_Wdog;
		ReadData>>=1;
		ReadData|=F_18B20_ReadDQ();//低位在前,每次右移一位
	}
	return ReadData;
}

/*********************************************************************/
//功能:	复位
//参数:	无
//返回值:	0表示复位失败,反之成功
/*********************************************************************/
unsigned int F_18B20_Reset()
{
	unsigned int InputTemp,OverTimeFlag;
	F_18B20_ChgIODir(1);  //将IOB15更改为输出
	DQ_L;
	F_18B20_Delaynus(600);//主机拉低总线至少480us产生复位脉冲
	F_18B20_ChgIODir(0);  //恢复IOB15为悬浮式输入,释放总线
	F_18B20_Delaynus(60); //注意该处延时,单总线器件等待时间,修改可能导致复位错误
	for(OverTimeFlag=5;OverTimeFlag>0;OverTimeFlag--)//单总线器件拉低总线60-240us作为应答脉冲
	{
		CL_Wdog;
		InputTemp=*P_IOB_Data;
		InputTemp&=0x8000;
		if(InputTemp)
			return 0;
	}
	return 1;
}

/*********************************************************************/
//功能:	初始化18B20
//参数:	无
//返回值:	0表示初始化失败,反之成功
/*********************************************************************/
unsigned int F_18B20_Initial()
{
	Set_System_Clock();//设置系统时钟
	F_18B20_IOInitial();
	if(F_18B20_Reset())
	{
		Renew_System_Clock();//恢复系统时钟
		return 1;
	}
	else
	{
		Disp_Strs(1,1,"Init Failed...");
		Renew_System_Clock();//恢复系统时钟
		return 0;
	}
}

/*********************************************************************/
//功能:	启动18B20测温
//参数:	无
//返回值:	float型温度值
/*********************************************************************/
float F_18B20_Start()
{
	int uintTemp=0;
	float fTemp=0.0;
	unsigned int Data[9];
	Set_System_Clock();
	if(F_18B20_Reset())
	{
		F_18B20_WriteByte(0xcc);       //Skip ROM,单点总线系统,不需读取分辨
		F_18B20_WriteByte(0x44);       //Start one convert
		while(F_18B20_ReadDQ()==0)	   //启动后发送读操作,若器件忙于温度转化则输出0,转化完毕输出1
		{
			CL_Wdog;
		}
		F_18B20_Reset();			   //一次完整操作包括初始化,ROM操作,存储器和控制操作,处理数据四步,每次都要遵循该流程
		F_18B20_WriteByte(0xcc);       //Skip ROM
		F_18B20_WriteByte(0xbe);       //Read Scratchpad,读缓冲寄存器
		for(uintTemp=0;uintTemp<9;uintTemp++)
		{
			CL_Wdog;
			Data[uintTemp]=F_18B20_ReadByte();
		}
		uintTemp=(Data[1]<<8)|Data[0];   //缓冲存储器中的Byte0、1数据为测得的温度信息,以16位补码形式存放
		
		if(uintTemp&0x8000)
			uintTemp=(~uintTemp)+1;
		
		fTemp=(float)uintTemp;
		fTemp=fTemp*0.0625;				 //获得最终温度输出
	}
	Renew_System_Clock();
	return fTemp;
}

⌨️ 快捷键说明

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