本人在网上查18B20资料,均是多接口方式,即发跳过ROM指令。很少有人研究55匹配ROM指令,好容易查到还收费。
只好自己看18B20的PDF文档进行研究。
实验后才发现,其问询速度太慢,我的实验是3个18B20,则问询一圈需3秒左右,图中的箭头就是指示目前测试的哪个18B20。
最后上传我的程序(C51),内含2004和被屏蔽的设定18B20参数的程序。
原创者:wjzpp
#include <reg51.h>
#include <absacc.h>
#include <intrins.h>
#define LCDCOM XBYTE[0x0000] //LCD命令寄存器地址cs=1,rs=0,rw=0
#define LCDDAT XBYTE[0x0100] //LCD数据寄存器地址cs=1,rs=1,rw=0
#define LCDREAD XBYTE[0x0200] //读取数据cs=1,rs=0,rw=1
sbit busy_flag=ACC^7; //忙标志位
sbit p33=P3^3;
unsigned int count=0;
unsigned int count2=0;
sbit TMDAT=P1^0;
unsigned char m,m2;
unsigned char tmbuf[3][16]; //温度数据
unsigned char code tmrom[3][8]={
{0x28,0x36,0x53,0x51,0x00,0x00,0x00,0xcd}, //第一个18B20
{0x28,0xe1,0x68,0x5a,0x00,0x00,0x00,0xec}, //第二个18B20
{0x28,0xf3,0x91,0x20,0x02,0x00,0x00,0x70}}; //第三个18B20
//***************************** LCD Function *****************************
//延时1*d ms
void delay(unsigned char d)
{
unsigned char j;
while(d--)
{
for(j=0;j<125;j++){;}
}
}
//测试LCD忙
void wait_lcd(void)
{
do{ACC=LCDREAD;}
while(busy_flag==1);
}
//送命令字
void I_SEND(unsigned char y)
{
wait_lcd();
LCDCOM=y;
}
//送数据
void D_SEND(unsigned char x)
{
wait_lcd();
LCDDAT=x;
}
//LCD初始化
void start_lcd(void)
{
delay(5);
I_SEND(0x38); //显示模式设置
I_SEND(0x08); //关显示
I_SEND(0x01); //清除显示
I_SEND(0x38); //显示模式设置:单行、8字符、5*7点阵
I_SEND(0x06); //设置输入模式:光标增量移动、显示不移位
I_SEND(0x0c); //开显示、关闭光标、不闪烁
}
void display(void)
{
unsigned char t[3],d[3];
t[0]=(tmbuf[0][0]>>4)|(tmbuf[0][1]<<4);
t[1]=(tmbuf[1][0]>>4)|(tmbuf[1][1]<<4);
t[2]=(tmbuf[2][0]>>4)|(tmbuf[2][1]<<4);
d[0]=tmbuf[0][0]&0x0f;
d[1]=tmbuf[1][0]&0x0f;
d[2]=tmbuf[2][0]&0x0f;
I_SEND(0x80); //LCD第一行
D_SEND('D');
D_SEND('S');
D_SEND('1');
D_SEND('8');
D_SEND('B');
D_SEND('2');
D_SEND('0');
D_SEND(' ');
D_SEND('T');
D_SEND('e');
D_SEND('s');
D_SEND('t');
D_SEND('.');
D_SEND('.');
D_SEND('.');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
I_SEND(0xC0); //LCD第二行
D_SEND(((tmbuf[0][1]>>4)>9)?((tmbuf[0][1]>>4)+0x37):((tmbuf[0][1]>>4)+0x30));
D_SEND(((tmbuf[0][1]&0x0f)>9)?((tmbuf[0][1]&0x0f)+0x37):((tmbuf[0][1]&0x0f)+0x30));
D_SEND(((tmbuf[0][0]>>4)>9)?((tmbuf[0][0]>>4)+0x37):((tmbuf[0][0]>>4)+0x30));
D_SEND(((tmbuf[0][0]&0x0f)>9)?((tmbuf[0][0]&0x0f)+0x37):((tmbuf[0][0]&0x0f)+0x30));
D_SEND(' ');
D_SEND(' ');
D_SEND(t[0]>0x7f?'-':' ');
D_SEND(t[0]>0x7f?(0xff-t[0])/10+0x30:t[0]/10+0x30);
D_SEND(t[0]>0x7f?(0xff-t[0])%10+0x30:t[0]%10+0x30);
D_SEND('.');
D_SEND(t[0]>0x7f?(0x0f-d[0])*0.6+0x30:d[0]*0.6+0x30);
if(m2==0)D_SEND(0x7f);
else D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
I_SEND(0x94); //LCD第三行
D_SEND(((tmbuf[1][1]>>4)>9)?((tmbuf[1][1]>>4)+0x37):((tmbuf[1][1]>>4)+0x30));
D_SEND(((tmbuf[1][1]&0x0f)>9)?((tmbuf[1][1]&0x0f)+0x37):((tmbuf[1][1]&0x0f)+0x30));
D_SEND(((tmbuf[1][0]>>4)>9)?((tmbuf[1][0]>>4)+0x37):((tmbuf[1][0]>>4)+0x30));
D_SEND(((tmbuf[1][0]&0x0f)>9)?((tmbuf[1][0]&0x0f)+0x37):((tmbuf[1][0]&0x0f)+0x30));
D_SEND(' ');
D_SEND(' ');
D_SEND(t[1]>0x7f?'-':' ');
D_SEND(t[1]>0x7f?(0xff-t[1])/10+0x30:t[1]/10+0x30);
D_SEND(t[1]>0x7f?(0xff-t[1])%10+0x30:t[1]%10+0x30);
D_SEND('.');
D_SEND(t[1]>0x7f?(0x0f-d[1])*0.6+0x30:d[1]*0.6+0x30);
if(m2==1)D_SEND(0x7f);
else D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND((((count%10000)%1000)%100)/10+0x30);
D_SEND((((count%10000)%1000)%100)%10+0x30);
I_SEND(0xD4); //LCD第四行
D_SEND(((tmbuf[2][1]>>4)>9)?((tmbuf[2][1]>>4)+0x37):((tmbuf[2][1]>>4)+0x30));
D_SEND(((tmbuf[2][1]&0x0f)>9)?((tmbuf[2][1]&0x0f)+0x37):((tmbuf[2][1]&0x0f)+0x30));
D_SEND(((tmbuf[2][0]>>4)>9)?((tmbuf[2][0]>>4)+0x37):((tmbuf[2][0]>>4)+0x30));
D_SEND(((tmbuf[2][0]&0x0f)>9)?((tmbuf[2][0]&0x0f)+0x37):((tmbuf[2][0]&0x0f)+0x30));
D_SEND(' ');
D_SEND(' ');
D_SEND(t[2]>0x7f?'-':' ');
D_SEND(t[2]>0x7f?(0xff-t[2])/10+0x30:t[2]/10+0x30);
D_SEND(t[2]>0x7f?(0xff-t[2])%10+0x30:t[2]%10+0x30);
D_SEND('.');
D_SEND(t[2]>0x7f?(0x0f-d[2])*0.6+0x30:d[2]*0.6+0x30);
if(m2==2)D_SEND(0x7f);
else D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(' ');
D_SEND(count2/10000+0x30);
D_SEND((count2%10000)/1000+0x30);
D_SEND(((count2%10000)%1000)/100+0x30);
D_SEND((((count2%10000)%1000)%100)/10+0x30);
D_SEND((((count2%10000)%1000)%100)%10+0x30);
}
//******************** Temp Function *************************
void tmreset(void) //复位18B20
{
unsigned int i;
TMDAT=0;
i=103; while(i>0)i--;
TMDAT=1;
i=4; while(i>0)i--;
}
void tmpre(void) //18B20应答
{
unsigned int i;
while(TMDAT);
while(~TMDAT);
i=4; while(i>0)i--;
}
bit tmrbit(void)
{
unsigned int i;
bit dat;
TMDAT=0; i++;
TMDAT=1; i++; i++;
dat=TMDAT;
i=8; while(i>0)i--;
return(dat);
}
unsigned char tmrbyte(void) //读一个字节
{
unsigned char i,j,dat;
dat=0;
for(i=1;i<=8;i++)
{
j=tmrbit();
dat=(j<<7)|(dat>>1);
}
return(dat);
}
void tmwbyte(unsigned char dat) //写一个字节
{
unsigned int i;
unsigned char j;
bit testb;
for(j=1;j<=8;j++)
{
testb=dat & 0x01;
dat=dat>>1;
if(testb)
{
TMDAT=0;
i++; i++;
TMDAT=1;
i=8; while(i>0)i--;
}
else
{
TMDAT=0;
i=8; while(i>0)i--;
TMDAT=1;
i++; i++;
}
}
}
/*
void tminit(unsigned char w) //初始化DS18B20
{
tmreset();
tmpre();
delay(1);
//tmwbyte(0xcc);
tmwbyte(0x55);
tmwbyte(tmrom[w][0]);
tmwbyte(tmrom[w][1]);
tmwbyte(tmrom[w][2]);
tmwbyte(tmrom[w][3]);
tmwbyte(tmrom[w][4]);
tmwbyte(tmrom[w][5]);
tmwbyte(tmrom[w][6]);
tmwbyte(tmrom[w][7]);
tmwbyte(0x4e);
tmwbyte(0x4b);
tmwbyte(0x46);
tmwbyte(0x7f);
}