当前位置:首页 > 芯闻号 > 充电吧
[导读]测试采用4个DS18B20挂在6m长得网线上面,使用的是5V供电,4.7K上拉,STM32驱动,程序实现ROM搜索并分别读取每一个DS18B20的温度./***********************

测试采用4个DS18B20挂在6m长得网线上面,使用的是5V供电,4.7K上拉,STM32驱动,

程序实现ROM搜索并分别读取每一个DS18B20的温度.


/*************************************************************************************************************
 * 文件名:		ds18b20.c
 * 功能:		STM32 DS18B20驱动
 * 作者:		cp1300@139.com
 * 创建时间:	2012年9月17日22:45
 * 最后修改时间:2012年9月17日
 * 详细:		需要延时函数支持
 * 			注意延时精度尽可能的高
 * 			读取的时候不要长时间的被中断,因为1wire对时间要求很严格
*************************************************************************************************************/
#include "system.h"
#include "delay.h"
#include "ds18b20.h"

//PC1
#define DS18B20_OUT		PBout(15)
#define DS18B20_IN		PBin(15)

//DS18B20使用的是GPIOE0
#define Set18b20IOout()		GPIOx_Init(GPIOB,BIT15,OUT_PP,SPEED_10M);	//设置DS18B20 IO为输出,
#define Set18b20IOin()		GPIOx_Init(GPIOB,BIT15,IN_IPU,0);			//设置DS18B20 IO为上拉输入,
#define Read18b20IO()		((DS18B20_IN) ? 1 : 0)						//读取DS18B20 IO
#define Write18b20IO(x)		(DS18B20_OUT = x)							//写DS18B20 IO








/*************************************************************************************************************************
*函数        :	bool DS18B20_Reset(void)
*功能        :	复位DS18B20
*参数        :	无
*返回        :	TRUE:成功;FALSE:失败
*依赖	: 	底层宏定义
*作者        :	cp1300@139.com
*时间     :	20120917
*最后修改时间:	20120917
*说明        :无
*************************************************************************************************************************/
bool DS18B20_Reset(void)
{
	u8 i = 0;
	
	Set18b20IOout();		//主机端口推挽输出模式
	Write18b20IO(1);
	Delay_US(1);
	Write18b20IO(0);		//拉低总线480us~240us
	Delay_US(500); 			//>480US延时
	Write18b20IO(1);
	Delay_US(2);			//复位完成
	Set18b20IOin();			//主机端口浮空输入模式
	while(Read18b20IO())	//等待低电平应答信号
	{
		i ++;
		Delay_US(1);
		if(i > 100)
		{
			uart_printf("DS18B20 error!rn");
			return FALSE;	//等待超时,初始化失败,返回FALSE;
		}
	}
	Delay_US(250);			//跳过回复信号
	return TRUE;			//检测到DS18B20,并且初始化成功
}



/*************************************************************************************************************************
*函数        :	__inline u8 DS18B20_ReadBit(void)
*功能        :	读取DS18B20 1bit数据
*参数        :	无
*返回        :	数据,最低位有效
*依赖	: 	底层宏定义
*作者        :	cp1300@139.com
*时间     :	20130402
*最后修改时间:	20130402
*说明        :无
*************************************************************************************************************************/
__inline u8 DS18B20_ReadBit(void)
{
	u8 data = 0;
	
	Set18b20IOout();	//主机端口推挽输出模式
	Write18b20IO(0);	//拉低总线10-15us
	Delay_US(12);
	Write18b20IO(1);	//释放总线
	Set18b20IOin();		//主机端口浮空输入模式
	Delay_US(10);
	if(Read18b20IO())	//读取数据,读取后大约延时40-45us
		data = 0x01;
	Delay_US(40);
	return data;
}


/*************************************************************************************************************************
*函数        :	u8 DS18B20_ReadData(void)
*功能        :	读取DS18B20数据
*参数        :	无
*返回        :	数据
*依赖	: 	底层宏定义
*作者        :	cp1300@139.com
*时间     :	20120917
*最后修改时间:	20120917
*说明        :无
*************************************************************************************************************************/
u8 DS18B20_ReadData(void)
{
	u8 i,data = 0;
	
	for(i = 0;i < 8;i ++)
	{

		data >>= 1;
		if(DS18B20_ReadBit())
			data |= 0x80;
	}
	return data;
}


/*************************************************************************************************************************
*函数        :	__inline void DS18B20_WriteBit(u8 bit)
*功能        :	向DS18B20写一位数据
*参数        :	数据,只发送最低位
*返回        :	无
*依赖	: 	底层宏定义
*作者        :	cp1300@139.com
*时间     :	20130402
*最后修改时间:	20130402
*说明        :无
*************************************************************************************************************************/
__inline void DS18B20_WriteBit(u8 bit)
{
	Set18b20IOout();	//主机端口推挽输出模式
   	Write18b20IO(0);		//拉低总线10-15us
	Delay_US(12);
	Write18b20IO(bit & 0x01);	//写入数据位,保持20-45us
	Delay_US(30);
	Write18b20IO(1);		//释放总线
	Delay_US(5);
}


/*************************************************************************************************************************
*函数        :	void DS18B20_WriteData(u8 data)
*功能        :	向DS18B20写数据
*参数        :	数据
*返回        :	无
*依赖	: 	底层宏定义
*作者        :	cp1300@139.com
*时间     :	20120917
*最后修改时间:	20120917
*说明        :无
*************************************************************************************************************************/
void DS18B20_WriteData(u8 data)
{
	u8 i;
	
	for(i = 0;i < 8;i ++)
	{
		DS18B20_WriteBit(data);
		data >>= 1;
	}
}





/*************************************************************************************************************************
*函数        :	s16 DS18B20_ReadTemper(void)
*功能        :	读取DS18B20温度
*参数        :	无
*返回        :	温度值
*依赖	: 	底层宏定义
*作者        :	cp1300@139.com
*时间     :	20120917
*最后修改时间:	20120917
*说明        :温度值扩大了100倍,温度值是个有符号数.
*************************************************************************************************************************/
s16 DS18B20_ReadTemper(void)
{
	u8 th, tl;
	s16 data;
	
	if(DS18B20_Reset() == FALSE)	
	{
		return 0xffff;	//返回错误
	}

	DS18B20_WriteData(0xcc);	//跳过读序列号
	DS18B20_WriteData(0x44);	//启动温度转换
	DS18B20_Reset();
	DS18B20_WriteData(0xcc);	//跳过读序列号
	DS18B20_WriteData(0xbe);	//读取温度
	tl = DS18B20_ReadData();	//读取低八位
	th = DS18B20_ReadData(); 	//读取高八位
	data = th;
	data <<= 8;
	data |= tl;
	data *= 6.25;				//温度值扩大100倍,精确到2位小数
	
	return data;
}


/*************************************************************************************************************************
*函数        :	__inline u8 DS18B20_Read2Bit(void)
*功能        :	读取DS18B20 2bit数据
*参数        :	无
*返回        :	数据
*依赖		: 	底层宏定义
*作者        :	cp1300@139.com
*时间     	:	20120917
*最后修改时间:	20120917
*说明        :无
*************************************************************************************************************************/
u8 DS18B20_Read2Bit(void)
{
	u8 i,data = 0;
	
	for(i = 0;i < 2;i ++)
	{

		data <<= 1;
		if(DS18B20_ReadBit())
			data |= 1;
	}
	return data;
}









//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//以下代码为多DS18B20相关



#define MAXNUM 4 //定义最多有4个 DS18B20
/*************************************************************************************************************************
*函数        	:	u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num)
*功能        	:	搜索DS18B20 ROM
*参数        	:	pID:DS18B20 ID缓冲区指针
					Num:DS18B20数目,必须事先知道
*返回        	:	搜索到的DS18B20数目
*依赖			: 	底层宏定义
*作者        	:	cp1300@139.com
*时间     		:	2013-04-17
*最后修改时间	:	2013-04-17
*说明        	:	程序必须事先知道DS18B20数目,搜索的数目只会小于这个数目
					代码移植于互联网
*************************************************************************************************************************/
u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num)
{ 
	unsigned char k,l,chongtuwei,m,n;
	unsigned char zhan[(MAXNUM)];
	unsigned char ss[64];
	u8 num = 0;
	l=0;
	
	do
	{
		DS18B20_Reset();
		DS18B20_WriteData(0xf0);	
		for(m=0;m<8;m++)
		{
			unsigned char s=0;
			for(n=0;n>=1;
				if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
				{   		
					DS18B20_WriteBit (0);
	    			ss[(m*8+n)]=0;
				}
				else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
				{
					s=s|0x80;
					DS18B20_WriteBit (1);
					ss[(m*8+n)]=1;
				}
				else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位 
				{				//如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1
					chongtuwei=m*8+n+1;					
					if(chongtuwei>zhan[l])
					{						
						DS18B20_WriteBit (0);
						ss[(m*8+n)]=0;												
						zhan[++l]=chongtuwei;						
					}
					else if(chongtuwei<zhan[l])
					{
						s=s|((ss[(m*8+n)]&0x01)<<7);
						DS18B20_WriteBit (ss[(m*8+n)]);
					}
					else if(chongtuwei==zhan[l])
					{
						s=s|0x80;
						DS18B20_WriteBit (1);
						ss[(m*8+n)]=1;
						l=l-1;
					}
				}
				else
				{
					return num;	//搜索完成,//返回搜索到的个数
				}
			}
			pID[num][m]=s;		
		}
		num=num+1;
	}
	while(zhan[l]!=0&&(num<MAXNUM));	
	
	return num;		//返回搜索到的个数
}






/*************************************************************************************************************************
*函数        	:	s16 DS18B20_ReadDesignateTemper(u8 pID[8])
*功能        	:	读取指定ID的DS18B20温度
*参数        	:	pID:DS18B20 ID,必须事先知道,如果不知道请启动ROM搜索
*返回        	:	温度值
*依赖			: 	底层宏定义
*作者       	:	cp1300@139.com
*时间     		:	2013-04-17
*最后修改时间	:	2013-04-17
*说明        	:	温度值扩大了100倍,温度值是个有符号数.
*************************************************************************************************************************/
s16 DS18B20_ReadDesignateTemper(u8 pID[8])
{
	u8 th, tl;
	s16 data;
	
	if(DS18B20_Reset() == FALSE)	
	{
		return 0xffff;				//返回错误
	}

	DS18B20_WriteData(0xcc);		//跳过读序列号
	DS18B20_WriteData(0x44);		//启动温度转换
	DS18B20_Reset();
	DS18B20_WriteData(0x55);		//发送序列号匹配命令
	for(data = 0;data < 8;data ++)	//发送8byte的序列号	
	{
	   DS18B20_WriteData(pID[data]);
	}
	Delay_US(10);
	DS18B20_WriteData(0xbe);	//读取温度
	tl = DS18B20_ReadData();	//读取低八位
	th = DS18B20_ReadData(); 	//读取高八位
	data = th;
	data <<= 8;
	data |= tl;
	data *= 6.25;				//温度值扩大100倍,精确到2位小数
	
	return data;
}





#ifndef DS18B20_H_
#define DS18B20_H_

//DS18B20指令
typedef enum 
{
	SEARCH_ROM			=	0xf0,	//搜索ROM指令
	READ_ROM			=	0x33,	//读取ROM指令
	MATH_ROM			=	0x55,	//匹配ROM指令
	SKIP_ROM			=	0xcc,	//忽略ROM指令
	ALARM_SEARCH		=	0xec,	//报警索索指令
	CONVERT_T			=	0x44,	//温度转换指令
	WRITE_SCRATCHPAD	=	0x4e,	//写暂存器指令
	READ_SCRATCHPAD		=	0xbe,	//读取暂存器指令
	COPY_SCRATCHPAD		=	0x48,	//拷贝暂存器指令
	RECALL_E2			=	0xb8,	//召回EEPROM指令
	READ_POWER_SUPPLY	=	0xb4,	//读取电源模式指令
} DS18B20_CMD;



//DS18B20 ROM编码
typedef struct
{
 	u8	DS18B20_CODE;	//DS18B20单总线编码:0x19
	u8	SN_1;			//序列号第1字节
	u8	SN_2;			//序列号第2字节
	u8	SN_3;			//序列号第3字节
	u8	SN_4;			//序列号第4字节
	u8	SN_5;			//序列号第5字节
	u8	SN_6;			//序列号第6字节
	u8	crc8;			//CRC8校验码	
} DS18B20_ROM_CODE;	



#define DS18B20_Init()		(DeviceClockEnable(DEV_GPIOB,ENABLE))		//使能GPIOB时钟

s16 DS18B20_ReadTemper(void);	//读取DS18B20温度
void DS18B20_WriteData(u8 data);

u8 DS18B20_SearchROM(u8 (*pID)[8],u8 Num);	//搜索ROM;
s16 DS18B20_ReadDesignateTemper(u8 pID[8]);	//读取指定ID的DS18B20温度



#endif /*DS18B20_H_*/






#define DS18B20_NUM		4
u8 ID_Buff[DS18B20_NUM][8];
int main(void)
{
	OS_CPU_SR  cpu_sr;
	s16 temp;
	u8 buff[16];
	u8 i,j,num;

	SYSTEM_ClockInit(9);			//初始化系统时钟72MHz
	JTAG_Set(SWD_ENABLE);			//只开启SWD调试模式
	DevInit();


	uart_printf("start system ...rnrn");

	num = DS18B20_SearchROM(ID_Buff,DS18B20_NUM);
	uart_printf("总线上实际挂载DS18B20数量: %drn",DS18B20_NUM);
	uart_printf("搜索到的DS18B20数量: %drn",num);

	
	for(i = 0;i < num;i ++)
	{
		uart_printf("rn DS18B20 No%d ID: ",i);
		for(j = 0;j < 8;j ++)
		{
			uart_printf("%02X ",ID_Buff[i][j]);
		}
	}

	i = 0;
	while(1)
	{

		LED1 = ~LED1;
		Delay_MS(1000);
		temp = DS18B20_ReadDesignateTemper(ID_Buff[i ++]);
		uart_printf("rn DS18B20 No%d Temp:%d ",i,temp);
		if(i == 4)
		{
		 	i = 0;
			uart_printf("rn");
		}

	}
}




结果


本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

DS18B20是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

关键字: ds18b20 温度传感器 数字信号

#51单片机#DS18B20硬件原理以及通信的工作时序

关键字: ds18b20 通信

DS18B20型智能温度传感器的工作原理

关键字: ds18b20 原理

DS18B20是一款常用的高精度的单总线数字温度测量芯片。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

关键字: ds18b20 手册

DS18B20是一款常用的高精度的单总线数字温度测量芯片。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。

关键字: ds18b20 引脚图

  1 引言   自动调温光疗系统是一种医用理疗仪器,其原理是采用单片机对可控硅的控制来控制高压下的激光输出器进行理疗,在激光输出器工作的同时对其进行实时温度检测,利用检测到的温度状况决

关键字: ds18b20 moc3021 自动调温

温度是表征环境的一个重要的参数。在工程领域,尤其像工程热力学等,温度检测非常普遍,对温度精确测量以便实时控制也显得尤为重要。

关键字: ds18b20 传感器 数据采集 matlab编程

单片机除了可以测量电信号外,还可以用与温度、湿度等非电信号的测量,能独立工作的单片机温度检测、温度控制系统已经广泛的应用于很多领域。单片机的接口信号是数字信号,要想用单片机作区温度这类非电信号,就要使用温度传感器将温度信...

关键字: ds18b20 数字温度计

DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。

关键字: ds18b20 数字温度计

温度的测量和控制在激光器、光纤光栅的使用及其他的工农业生产和科学研究中应用广泛。温度检测的传统方法是使用诸如热电偶、热电阻、半导体PN结之类的模拟温度传感器。信号经取样、放大后通过模数转换,再交自单片机处理。被测温度信号...

关键字: at89c51 ds18b20 温度测量
关闭
关闭