您的位置:首页 > 其它

3-多点温度采集模块设计--DS18B20驱动函数模块设计

2018-04-23 22:38 106 查看
版权声明: https://blog.csdn.net/qq_33869371/article/details/80055325

1、温度数据的存放:比如显示:+25.7℃,这个数据有十位、个位、小数点后一位、为正数这几个成员的信息,因此我们需要建立一个结构体来包含这些成员,那么,定义的任意一个结构体变量都拥有这些成员的属性。

//数据存储结构
typedef struct tagTempData
{
unsigned char 					btThird;		//百位数据
unsigned char 					btSecond;		//十位数据
unsigned char 					btFirst;		//个位数据
unsigned char 					btDecimal;		//小数点后一位数据
unsigned char					btNegative;		//是否为负数
}TEMPDATA;
TEMPDATA m_TempData;

DS18B20驱动函数的应用步骤:

1、DS18B20的初始化:


//芯片初始化
void Initialization()
{
while(1)
{
DQ = 0;				    //P2.7引脚将单总线拉低
Delay480us(); 			//延时480us
DQ = 1;					//P2.7发复位脉冲
Delay60us();			//延时(DS18B20等待)60us
if(!DQ)  				//P2.7引脚收到ds18b20的应答信号
{
DQ = 1;				//数据线端口P2.7为高电平
Delay240us();		//延时240us
break;				//跳出循环
}
}
}

2、向DS18B20写一个字节-8位


//向DS18B20写一个字节-8位-(从低位开始写)
void WriteByte(unsigned char btData)
{
unsigned char i, btBuffer;		//两个局部变量

for (i = 0; i < 8; i++)
{
btBuffer = btData >> i;	    //btData=0x55,右移i位
//右移一位为0010 1010=0x2A
if (btBuffer & 1)			//如果btBuffer(btData右移i位后(共8位))不为0
{
DQ = 0;
_nop_();
_nop_();	 		   //延时2us
DQ = 1;				//P2.7发复位脉冲
Delay60us();		   //延时60us
}
else						//(btData右移i位后)btBuffer为0则
{
DQ = 0;
Delay60us();
DQ = 1;
}
}
}
3、从DS18B20读一个字节


//从DS18B20读一个字节(从低位开始读)
unsigned char ReadByte()
{
unsigned char i, btDest;	   //为一个字符变量

for (i = 0; i < 8; i++)
{
btDest >>= 1;			  //右移1位
DQ = 0;					//P2.7发低电平脉冲
_nop_();
_nop_();				  //延时2us
DQ = 1;					//P2.7发复位脉冲
Delay16us();			  //延时16us
if (DQ) btDest |= 0x80;    // btDest按位或后变为负数
Delay60us();
}

return btDest;				//返回 btDest值
}
4、序列号匹配-因为采用的是单总线的检测方式,所以要对总线的每个DSl8820进行地址匹配,得到器件的响应后,方可对每个器件进行操作。
//序列号匹配
void MatchROM(const unsigned char *pMatchData)
{
unsigned char i;

Initialization();			  //DS18B20的初始化
WriteByte(MATCH_ROM);	    //=0x55,为匹配ROM,引用WriteByte()函数
for (i = 0; i < 8; i++)
WriteByte(*(pMatchData + i));	//指针指向下一个序列号
}
5、温度采集流程


//读取温度值
TEMPDATA ReadTemperature()						   //结构体类型的函数
{
TEMPDATA TempData;							    //TempData为结构体类型的变量
unsigned int iTempDataH;					 //为整型
unsigned char btDot, iTempDataL;			 //定义存储1个字符的变量// char 类型储存的实际上是整数-ASCII码值
static unsigned char i = 0;

TempData.btNegative = 0;						//为0温度为正
i++;
if (i == 9)
i = 1;										   //
Initialization();
WriteByte(SKIP_ROM);							//跳过ROM匹配,=0xCC
WriteByte(TEMP_SWITCH);							//启动转换  = 0x44
Delay500ms();  									//调用一次就行
Delay500ms();
Initialization();

//多个芯片的时候用MatchROM(ROMData)换掉WriteByte(SKIP_ROM)
switch (i)
{
case 1 : MatchROM(ROMData1); break;			//匹配1
case 2 : MatchROM(ROMData2); break;			//匹配2
case 3 : MatchROM(ROMData3); break;			//匹配3
case 4 : MatchROM(ROMData4); break;			//匹配4
case 5 : MatchROM(ROMData5); break;			//匹配5
case 6 : MatchROM(ROMData6); break;			//匹配6
case 7 : MatchROM(ROMData7); break;			//匹配7
case 8 : MatchROM(ROMData8); break;			//匹配8
}
//WriteByte(SKIP_ROM);							//跳过ROM匹配(单个芯片时用这句换掉上面的switch)
WriteByte(READ_MEMORY);							//读数据
iTempDataL = ReadByte();
iTempDataH = ReadByte();
iTempDataH <<= 8;
iTempDataH |= iTempDataL;

if (iTempDataH & 0x8000)
{
TempData.btNegative = 1;
iTempDataH = ~iTempDataH + 1;				//负数求补码
}

//为了省去浮点运算带来的开销,而采用整数和小数部分分开处理的方法(没有四舍五入)
btDot = (unsigned char)(iTempDataH & 0x000F);	//得到小数部分
iTempDataH >>= 4;								//得到整数部分
btDot *= 5; 									//btDot*10/16得到转换后的小数数据
btDot >>= 3;

//数据处理
TempData.btThird   = (unsigned char)iTempDataH / 100;
TempData.btSecond  = (unsigned char)iTempDataH % 100 / 10;
TempData.btFirst   = (unsigned char)iTempDataH % 10;
TempData.btDecimal = btDot;

return TempData;
}

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: