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

2019-04-12 15:47发布

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; }

登录 后发表评论
0条评论
还没有人评论过~