1、温度数据的存放:比如显示:+25.7℃,这个数据有十位、个位、小数点后一位、为正数这几个成员的信息,因此我们需要建立一个结构体来包含这些成员,那么,定义的任意一个结构体变量都拥有这些成员的属性。
//数据存储结构typedef struct tagTempData{unsigned char btThird;//百位数据unsigned char btSecond;//十位数据unsigned char btFirst;//个位数据unsigned char btDecimal;//小数点后一位数据unsigned charbtNegative;//是否为负数}TEMPDATA;TEMPDATA m_TempData;
DS18B20驱动函数的应用步骤:
1、DS18B20的初始化:
//芯片初始化void Initialization(){while(1){DQ = 0; //P2.7引脚将单总线拉低Delay480us(); //延时480usDQ = 1;//P2.7发复位脉冲Delay60us();//延时(DS18B20等待)60usif(!DQ) //P2.7引脚收到ds18b20的应答信号{DQ = 1;//数据线端口P2.7为高电平Delay240us();//延时240usbreak;//跳出循环}}}
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=0x2Aif (btBuffer & 1)//如果btBuffer(btData右移i位后(共8位))不为0{DQ = 0;_nop_();_nop_(); //延时2usDQ = 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_(); //延时2usDQ = 1;//P2.7发复位脉冲Delay16us(); //延时16usif (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匹配,=0xCCWriteByte(TEMP_SWITCH);//启动转换 = 0x44 Delay500ms(); //调用一次就行Delay500ms(); Initialization();//多个芯片的时候用MatchROM(ROMData)换掉WriteByte(SKIP_ROM)switch (i){case 1 : MatchROM(ROMData1); break;//匹配1case 2 : MatchROM(ROMData2); break;//匹配2case 3 : MatchROM(ROMData3); break;//匹配3case 4 : MatchROM(ROMData4); break;//匹配4case 5 : MatchROM(ROMData5); break;//匹配5case 6 : MatchROM(ROMData6); break;//匹配6case 7 : MatchROM(ROMData7); break;//匹配7case 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;}