一、DS18B02介绍数字温度传感器与模拟相比热敏电阻要通过ad芯片转化功能强硬件简单易扩展抗干扰性强测温范围-55C ~ 125C通信接口1-wire单总线其他特点总线结构内置温度报警功能可寄生供电引脚及应用电路STC89C52二、单总线介绍1-wire BUS一种通用数据总线异步半双工只需要一根通信线DQ省通信线硬件规范DQ开漏输出添加上拉电阻阻值4.7k左右线与若从机使用寄生供电主机需配备强上拉输出电路软件规范1. 初始化主机将总线拉低至少480微秒然后释放总线电阻上拉弱上拉等待15-60微秒后存在的从机会拉低总线60-240微秒以响应主机之后释放#include REGX52.H sbit OneWire_DQP3^7; unsigned char OneWire_Init(void) { unsigned char i; unsigned char AckBit; OneWire_DQ1; OneWire_DQ0; i 247;while (--i); //Delay 500us OneWire_DQ1; i 32;while (--i); //Delay 70us AckBitOneWire_DQ; i 247;while (--i); //Delay 500us return AckBit; }2.发送一位主机将总线拉低60-120微秒然后释放总线表示发送0主机将总线拉低1-15微秒然后释放总线表示发送1从机将会在30微秒后读取电频整个时间片应大于60微秒总线恢复时间1微秒对51单片机来说很短暂时不用管void OneWire_SendBit(unsigned char Bit) { unsigned char i; OneWire_DQ0; i 4;while (--i); //Delay 10us OneWire_DQBit; i 24;while (--i); //Delay 50us OneWire_DQ1; }3.接收一位主机将总线拉低1-15微秒然后释放总线并在拉低后15微秒内读取总线电平尽量贴近15微秒的末尾读取为低电平则为接收0为高电平为接收1整个时间片应大于60微秒unsigned char OneWire_ReceiveBit(void) { unsigned char i; unsigned char Bit; OneWire_DQ0; i 2;while (--i); //Delay 5us OneWire_DQ1; i 2;while (--i); //Delay 5us BitOneWire_DQ; i 24;while (--i); //Delay 50us return Bit; }4.发送/接收一个字节也就是连续发送/接收八次字节void OneWire_SendByte(unsigned char Byte) { unsigned char i; for(i0;i8;i) { OneWire_SendBit(Byte(0x01i)); } } unsigned char OneWire_ReceiveByte(void) { unsigned char i; unsigned char Byte0x00; for(i0;i8;i) { if(OneWire_ReceiveBit()){Byte|(0x01i);} } return Byte; }三、DS18B02操作流程和数据帧初始化从机复位主机判断从机是否响应ROM操作ROM指令本指令需要的读取操作功能操作RAM操作功能指令本指令需要的读取操作1.温度变化初始化跳过ROM开始温度变化void DS18B20_ConvertT(void) { OneWire_Init(); OneWire_SendByte(DS18B20_SKIP_ROM); OneWire_SendByte(DS18B20_CONVERT_T); }2.温度读取初始化跳过ROM读暂存器连续的读操作温度转换参考最后的温度表float DS18B20_ReadT(void) { unsigned char TLSB,TMSB; int Temp; float T; OneWire_Init(); OneWire_SendByte(DS18B20_SKIP_ROM); OneWire_SendByte(DS18B20_READ_SCRATCHPAD); TLSBOneWire_ReceiveByte(); TMSBOneWire_ReceiveByte(); Temp(TMSB8)|TLSB; //拼接温度 TTemp/16.0; //除四位二进制转为小数 return T; }3.主函数温度计算与显示void main() { LCD_Init(); LCD_ShowString(1,1,T:); LCD_ShowString(2,1,TH:); LCD_ShowString(2,9,TL:); LCD_ShowSignedNum(2,4,THigh,3); LCD_ShowSignedNum(2,12,TLow,3); while(1) { DS18B20_ConvertT(); //启动温度转换 T DS18B20_ReadT(); //读取温度 if(T 0) { LCD_ShowChar(1,3,-); T -T; } else { LCD_ShowChar(1,3,); //负数转为正数直接在前加上负号 } LCD_ShowNum(1,4,T,3); //分割为整数和小数显示 LCD_ShowChar(1,7,.); LCD_ShowNum(1,8,(unsigned long)(T*10000)%10000,4); //取出小数部分 } }4.读序问题1-WIRE总线使用中断时需要解决读序问题因为调用中断会影响通信的延时过程所以只能在协议通信时禁用中断但这样操作也会对定时器造成干扰而I2C有独立的时钟线被中断也没事附表温度存储格式