1.导入LCD1602、Delay相关文件
2.根据原理编写单总线代码
图1 DS18B02原理表示的接口
图2 初始化
#include <REGX52.H>
sbit OneWire_DQ=P3^7;
unsigned char Onewire_Init()
{
unsigned char i,Answer;
OneWire_DQ=1; //OneWire_DQ在这之前有可能为0
OneWire_DQ=0; //拉低
i = 247; while (--i); //延时500us
OneWire_DQ=1; //主机OneWire_DQ释放总线
i = 32; while (--i); //延时70us
Answer=OneWire_DQ; //读电平,代表应答位
i = 247; while (--i); //延迟480us,用于完成初始化整个过程
return Answer;
}
图3 发送一位数据
void Onewire_WriteBit(unsigned char Bite)
{
unsigned char i;
OneWire_DQ=0; //拉低,这是直接进行判断的,假设第一次是发送1,看是否是假设的这样
i = 4; while (--i); //延时10us,发送一位数据
OneWire_DQ=Bite; //主机释放总线,0表示继续写,1此处释放,表示延时10us发送
i = 24; while (--i); //延时50us
OneWire_DQ=1; //从机OneWire_DQ释放总线,如果Bite==0表示到此处释放,延时60us
}
图4 接收一位数据
unsigned char Onewire_ReadBit()
{
unsigned char i,Bite;
OneWire_DQ=0; //拉低
i = 2; while (--i); //延时5us
OneWire_DQ=1; //释放总线
i = 2; while (--i); //延时5us
Bite=OneWire_DQ;
i = 24; while (--i); //延时50us,为了弥补到60us
return Bite;
}
图5 接收和发送时序
void Onewire_WriteByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
Onewire_WriteBit(Byte&(0x01<<i));
}
}
unsigned char Onewire_ReadByte()
{
unsigned char i,Byte=0x00;
for(i=0;i<8;i++)
{
if(Onewire_ReadBit())
{Byte|=(0x01<<i);} //读取就是在使用
}
return Byte;
}
Onewire.c代码汇总
#include <REGX52.H>
sbit OneWire_DQ=P3^7;
unsigned char Onewire_Init()
{
unsigned char i,Answer;
OneWire_DQ=1; //OneWire_DQ在这之前有可能为0
OneWire_DQ=0; //拉低
i = 247; while (--i); //延时500us
OneWire_DQ=1; //主机OneWire_DQ释放总线
i = 32; while (--i); //延时70us
Answer=OneWire_DQ; //读电平
i = 247; while (--i); //延迟480us,用于完成初始化整个过程
return Answer;
}
void Onewire_WriteBit(unsigned char Bite)
{
unsigned char i;
OneWire_DQ=0; //拉低
i = 4; while (--i); //延时10us,发送一位数据
OneWire_DQ=Bite; //主机释放总线,0表示继续写,1此处释放,表示延时10us发送
i = 24; while (--i); //延时50us
OneWire_DQ=1; //从机OneWire_DQ释放总线,如果Bite==0表示到此处释放,延时60us
}
unsigned char Onewire_ReadBit()
{
unsigned char i,Bite;
OneWire_DQ=0; //拉低
i = 2; while (--i); //延时5us
OneWire_DQ=1; //释放总线
i = 2; while (--i); //延时5us
Bite=OneWire_DQ;
i = 24; while (--i); //延时50us,为了弥补到60us
return Bite;
}
void Onewire_WriteByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
Onewire_WriteBit(Byte&(0x01<<i));
}
}
unsigned char Onewire_ReadByte()
{
unsigned char i,Byte=0x00;
for(i=0;i<8;i++)
{
if(Onewire_ReadBit())
{Byte|=(0x01<<i);} //读取就是在使用
}
return Byte;
}
图6 DS18B02操作流程
图7 DS18B02数据帧
DS18B02.c
#include <REGX52.H>
#include "Onewire.h"
#define SKIP_ROM 0xCC //跳过ROM
#define CONVERT_T 0x44 //转换
#define READ_SCRATCHPAD 0xBE //读暂存器
void t_Trans()
{
Onewire_Init();
Onewire_WriteByte(SKIP_ROM); //跳过ROM
Onewire_WriteByte(CONVERT_T); //转换
}
float t_Read()
{
unsigned char TLSB,TMSB;
float T;
int temp;
Onewire_Init();
Onewire_WriteByte(SKIP_ROM); //跳过ROM
Onewire_WriteByte(READ_SCRATCHPAD); //为了读暂存器
TLSB=Onewire_ReadByte(); //读低位置的8个
TMSB=Onewire_ReadByte(); //读高位置的8个
//温度存储格式为整数,所以需要换为整数,但无符号的char转换为int相当于向左移了4位
temp=(TMSB<<8)|TLSB; //转换为int相当于提高了16位
T=temp/16.0;
return T;
}
3.main.c代码
#include <REGX52.H>
#include "LCD1602.h"
#include "Delay.h"
#include "DS18B02.h"
float T;
void main()
{
t_Trans();
Delay(1000);//这两行代码保证第一次显示的温度不是默认值
LCD_Init();
LCD_ShowString(1,1,"Temperature:");
while(1)
{
t_Trans(); //转换温度
T=t_Read(); //读取温度
if(T<0)
{
LCD_ShowChar(2,1,'-');
T=-T;
}
else
{
LCD_ShowChar(2,1,'+');
}
LCD_ShowNum(2,2,T,3);
LCD_ShowChar(2,5,'.');
LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
}
}
4.结果展示
DS18B02在LCD上显示温度