实验测试时成功的。
/***********************************************************************/
*项 目: 单总线多通道测量18b20温度
*时 间: 2019-09-25
*作 者: 零点工作室(RMLS)
/***********************************************************************/
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P3^7; //单总线io
sbit rs=P2^6; //1602 io口
sbit rw=P2^5;
sbit e = P2^7;
uchar temp1,temp2,temp3; //定义两个存放温度的变量
//uchar ID[8]; //存放DS18B20的64位序列号的数组
uchar code ID_1[]={0x28,0xEE,0x85,0x6C,0x25,0x16,0x02,0xE4}; //第一个DS18B20的序列号
uchar code ID_2[]={0x28,0x32,0x74,0x68,0x03,0x00,0x00,0x87}; //第二个DS18B20的序列号
uchar code ID_3[]={0x28,0xEE,0xC4,0xEF,0x21,0x16,0x02,0x0F}; //第三个DS18B20的序列号
uchar code table[]="0123456789";
uchar code table_temp[]="tempreture:";
uchar code table_0[]="'C";
/****************************************************/
void delay_50us(uint time); //50us的延时函数
void write_com(uchar com); //LCD1602写指令
void write_data(uchar dat); //LCD1602写数据
void init_LCD1602(void); //LCD1602初始化函数 id init_ds18b20(void); //ds18b20初始化
void delay(uint t); //while(t--)延时函数
void init_ds18b20(void); //DS18B20初始化函数
void write_byte(char dat); //ds18b20写一个字节函数
uchar read_byte(void); //ds18b20读一个字节函数
uchar readtemp1(void); //第一个ds18b20读取温度函数
uchar readtemp2(void); //第二个ds18b20读取温度函数
uchar readtemp3(void); //第二个ds18b20读取温度函数
void display(void); //LCD1602显示温度函数
void main(void)
{
init_LCD1602();
while(1)
{
temp1=readtemp1();
temp2=readtemp2();
temp3=readtemp3();
display();
}
}
/************************************************/
void delay_50us(uint time)
{
uchar j;
for(;time>0;time--);
for(j=19;j>0;j++);
}
/************************************************/
void write_com(uchar com) //LCD1602写指令
{
e=0;
rs=0;
rw=0;
P0=com;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
/***************************************************/
void write_data(uchar dat) //LCD1602写数据
{
e=0;
rs=1;
rw=0;
P0=dat;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
/***************************************************/
void init_LCD1602(void) //LCD1602初始化函数
{
delay_50us(300);
write_com(0x38);
delay_50us(100);
write_com(0x38);
delay_50us(100);
write_com(0x38);
write_com(0x38);//显示模式设置
write_com(0x08);//显示关闭
write_com(0x01);//显示清屏
write_com(0x06);//显示光标移动设置
write_com(0x0c);//显示开及光标设置
}
/*********************************************/
void delay(uint t)
{
while(t--);
}
/***************************************************/
void init_ds18b20(void)//初始化
{
uchar n;
DQ=1; //默认为高电平
delay(8);
DQ=0;
delay(80); //12MHz晶振下大约600微秒的延时
DQ=1; //释放总线
delay(8);
n=DQ;
delay(4);
}
/***************************************************/
void write_byte(char dat)//写一个字节
{
uchar i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=dat&0x01;//从最低位开始写,0x01
delay(4);
DQ=1;//拉高,传下一帧数据
dat>>=1;
}
delay(4);
}
/****************************************************/
uchar read_byte(void)//读一个字节
{
uchar i;
uchar value;
for(i=0;i<8;i++)
{
DQ=0;
value>>=1; //判断8次,移位七次(起延时作用)
DQ=1;
if(DQ) //采样,判断DQ
value|=0x80; //赋值,与0x80与一下
delay(4);
}
return value;
}
/*****************************************************/
uchar readtemp1(void)
{
uchar a,b,i; //读一个高八位,一个低八位
init_ds18b20();
write_byte(0x55);
for(i=0;i<8;i++)
{
write_byte(ID_1[i]);
}
write_byte(0x44); //启动温度测量
delay(300);
init_ds18b20();
write_byte(0x55);
for(i=0;i<8;i++)
{
write_byte(ID_1[i]);
}
write_byte(0xbe); //读这个温度
a=read_byte(); //低位
b=read_byte(); //高位
b<<=4;
b+=(a&0xf0)>>4; //屏蔽低四位
return b;
}
/******************************************************/
uchar readtemp2(void)
{
uchar a,b,i; //读一个高八位,一个低八位
init_ds18b20();
write_byte(0x55);
for(i=0;i<8;i++)
{
write_byte(ID_2[i]);
}
write_byte(0x44); //启动温度测量
delay(300);
init_ds18b20();
write_byte(0x55);
for(i=0;i<8;i++)
{
write_byte(ID_2[i]);
}
write_byte(0xbe); //读这个温度
a=read_byte(); //低位
b=read_byte(); //高位
b<<=4;
b+=(a&0xf0)>>4; //屏蔽低四位
return b;
}
uchar readtemp3(void)
{
uchar a,b,i; //读一个高八位,一个低八位
init_ds18b20();
write_byte(0x55);
for(i=0;i<8;i++)
{
write_byte(ID_3[i]);
}
write_byte(0x44); //启动温度测量
delay(300);
init_ds18b20();
write_byte(0x55);
for(i=0;i<8;i++)
{
write_byte(ID_3[i]);
}
write_byte(0xbe); //读这个温度
a=read_byte(); //低位
b=read_byte(); //高位
b<<=4;
b+=(a&0xf0)>>4; //屏蔽低四位
return b;
}
/******************************************************/
void display(void)
{
uchar i;
write_com(0x80);
for(i=0;i<11;i++)
{
write_data(table_temp[i]); //显示温度
delay_50us(1);
}
write_com(0x80+0x40); //第一个温度值
write_data(table[temp1/10]); //显示温度十位
write_data(table[temp1%10]); //显示温度个位
write_data(table_0[1]);
write_com(0x80+0x45); //第二个温度值
write_data(table[temp2/10]); //显示温度十位
write_data(table[temp2%10]); //显示温度个位
write_data(table_0[1]);
write_com(0x80+0x49); //第三个温度值
write_data(table[temp3/10]); //显示温度十位
write_data(table[temp3%10]); //显示温度个位
write_data(table_0[1]);
}