当前位置:文档之家› DS18B20自动搜索ROM51C程序多点测温经验证

DS18B20自动搜索ROM51C程序多点测温经验证

#include
#include

#define uchar unsigned char //定义无符号单字节
#define uint unsigned int //定义无符号整形
#define MAXNUM 2 //定义最多DS18B20个数 超过的无法显示

sbit DQ=P1^3; //定义数据线
sbit RS=P2^4;
sbit RW=P2^5;
sbit E=P2^6;

uchar code lcd0[]={"SEARCH ROMING..."};
uchar code lcd1[]={"SEARCH ROM OK!"};
uchar code lcd2[]={"The total is:"};
uchar code lcd3[]={"No.( ):"};
uchar code lcd4[]={'0','1','2','3','4','5','6','7','8','9','.',0xdf,0x43};
uchar dat[6];

uchar temp_l,temp_h,is_fuwen,temp_x,temp_over,t;
uchar num=0;
uint i;
uchar al[MAXNUM];

idata uchar ID[MAXNUM][8]; // ={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
void alarm_search(void);
/***********************液晶模块**********************************/
void delay()//延时程序
{
uchar y;
for(y=0;y<250;y++);
}
void LCD_write_com(uchar com)//写
{
delay();
RS=0;
RW=0;
E=0;
E=1;
P0=com;
E=0;
delay();
}
void LCD_write_data(uchar dat)
{
delay();
RS=1;
RW=0;
E=0;
E=1;
P0=dat;
E=0;
delay();
}
void init()//初始化
{
LCD_write_com(0x01);
LCD_write_com(0x38);
LCD_write_com(0x0c);
LCD_write_com(0x06);
}

/************************ds18b20****************************/
void delay_nus(uint n)//延时 程序 一次8+6(进出)=14us
{
while(n--);
}
void reset(void) //ds18b20初始化复位操作
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_nus(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_nus(80); //精确延时 大于 480us
DQ = 1; //拉高总线
delay_nus(10);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败
delay_nus(5);
}
void write_bit(uchar dat) //DS18B20 写一位 操作
{
DQ = 0;
_nop_();
_nop_();
DQ = dat&0x01;
delay_nus(5);
DQ = 1;
}
void write_byte(uchar dat)//写一个字节
{
unsigned char i,j;
for (i=8; i>0; i--)
{
j=dat&0x01;
write_bit(j);
dat>>=1;
}
}
uchar read_2bit()//读二位 子程序
{
uchar i;
uchar dat = 0;

for (i=2;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat<<=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x01;
delay_nus(4);
}
return(dat);
}
uchar read_byte()//读一个字节 子程序
{
uchar i=0;
uchar dat = 0;

for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_nus(4);
}
return(dat);
}



void delay_nms(uint n)
{
uint j;
for(j=0;j}
void read_temp(uchar i)//读取温度 子程序
{
uchar f;
reset();
write_byte(0xcc);
write_byte(0x44);

delay_nms(50000);

reset();
write_byte(0x55);
for(f=0;f<8;f++)
{
write_byte(ID[i][f]);//发匹配ROM
}
delay_nus(100);
write_byte(0xbe);
delay_nus(100);
temp_l=read_byte();
temp_h=read_byte();
}
void temp_convert()//

温度转换
{
temp_x=(temp_l&0x0f)*0.625+0.5;
is_fuwen=temp_h&0xf8;
if(is_fuwen)
{
is_fuwen=1;
temp_h=~temp_h;
if(temp_l==0)temp_h++; //若低8位全为0且温度为负,取补时就要向高位进1
temp_l=~temp_l+1;
}

temp_h<<=4;
temp_l>>=4;
temp_over=temp_h|temp_l;
delay_nus(255);
}

/*******************显示***************************/
void _search_cartoon(void)//搜索ROM动画
{
init();
LCD_write_com(0x80);
for(i=0;i<16;i++)
{
LCD_write_data(lcd0[i]);
}
LCD_write_com(0xc0);
for(i=0;i<16;i++)
{
LCD_write_data(0xff);
delay_nms(num*2000);
}
}
void _display_total() //显示总数
{
init();
LCD_write_com(0x80);
for(i=0;i<14;i++)
{
LCD_write_data(lcd1[i]);
}
LCD_write_com(0xc0);
for(i=0;i<13;i++)
{
LCD_write_data(lcd2[i]);
}
LCD_write_data(lcd4[num]);
delay_nms(50000);
delay_nms(50000);
}
void _display_ds18b20(i)//显示编号为i的DS18B20的温度//
{
uint data_b,data_temp,l;
data_b=temp_over/100;//百位//
data_temp=temp_over%100;
dat[0]=data_temp/10;//十位//
dat[1]=data_temp%10;//个位//
dat[2]=10;
dat[3]=temp_x;
dat[4]=11;
dat[5]=12;
init();
LCD_write_com(0x80);
for(l=0;l<14;l++)
{
LCD_write_data(lcd1[l]);
}
LCD_write_com(0xc0);
for(l=0;l<7;l++)
{
LCD_write_data(lcd3[l]);
}
LCD_write_com(0xc4);
LCD_write_data(lcd4[++i]);
LCD_write_com(0xc8);
if(is_fuwen==1)
{
LCD_write_data(0x2d);
}
else
{
LCD_write_data(lcd4[data_b]);
}
for(l=0;l<6;l++)
LCD_write_data(lcd4[dat[l]]);
delay_nms(50000);
delay_nms(50000);
}


/***********************自动搜索ROM*****************************/
void search_rom(void)//搜索ROM
{
uchar k,l,chongtuwei,m,n;
uchar zhan[(MAXNUM-1)];
uchar ss[64];
l=0;
do
{
reset();
write_byte(0xf0);
for(m=0;m<8;m++)
{
uchar s=0;
for(n=0;n<8;n++)
{
k=read_2bit();//读两位数据
k=k&0x03;
s>>=1;
if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
{
write_bit (0);
ss[(m*8+n)]=0;
}
else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
}
else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位
{ //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1
chongtuwei=m*8+n+1;
if(chongtuwei>zhan[l])
{
write_bit (0);
ss[(m*8+n)]=0;
zhan[++l]=chongtuwei;
}
else if(chongtuwei{
s=s|((ss[(m*8+n)]&0x01)<<7);
write_bit (ss[(m*8+n)]);
}
else if(chongtuwei==zhan[l])
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
l=l-1;
}
}
else
{
goto loop;
}
}
ID[num]

[m]=s;
}
num=num+1;
}while(zhan[l]!=0&&(num
loop: _search_cartoon();
_display_total();
}

void match_rom(uchar i)
{
uchar c;
reset();
write_byte(0x55);
for(c=0;c<8;c++)
write_byte(ID[--i][c]);
}

void write_schratchpad(char H,char L)
{
write_byte(0x4e);
write_byte(H);
write_byte(L);
}

void copy_schratchpad()
{
write_byte(0x48);
}

void recall_EE()
{
write_byte(0xb8);
}


void main (void)
{
uchar i;
search_rom();//搜索ROM并且存储
// reset();
// write_byte(0xcc);
// write_schratchpad(30,15);
// reset();
// write_byte(0xcc);
// copy_schratchpad();
reset();
match_rom(0);
recall_EE();
while(1)
{
for(i=0;i{
read_temp(i); //读编号 i (0--(num-1)) ds18b20 的温度
temp_convert(); //调用温度转换
_display_ds18b20(i);//显示 编号 i 的温度
}
alarm_search();
}
}
void alarm_search(void)
{
uchar k,l,chongtuwei,m,n,numb,a;
uchar zhan[(MAXNUM-1)];
uchar ss[64],ID0[MAXNUM][8];
l=0;
P1=0xe0;
do
{
reset();
write_byte(0xec);
for(m=0;m<8;m++)
{
uchar s=0;
for(n=0;n<8;n++)
{
k=read_2bit();//读两位数据
k=k&0x03;
s>>=1;
if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
{
write_bit (0);
ss[(m*8+n)]=0;
}
else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
}
else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位
{ //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写1
chongtuwei=m*8+n+1;
if(chongtuwei>zhan[l])
{
write_bit (0);
ss[(m*8+n)]=0;
zhan[++l]=chongtuwei;
}
else if(chongtuwei{
s=s|((ss[(m*8+n)]&0x01)<<7);
write_bit (ss[(m*8+n)]);
}
else if(chongtuwei==zhan[l])
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
l=l-1;
}
}
else
{
goto loop1;
}
}
ID0[numb][m]=s;
}
numb=numb+1;
}while(zhan[l]!=0&&(numbk=0;
for(m=0;m{
for(l=0;l{
for(n=0;n<8;n++)
{
if(ID0[m][n]==ID[l][n])
{
a++;
if(a==8)
{
al[k]=m;
k++;
}
}
}
a=0;
}
}
LCD_write_com(0x8f);
for(m=0;m{
LCD_write_data(lcd4[al[m]+1]);
}
P1=0x00;
loop1: if(P1!=0x00)
P1=0xfe;

}


















相关主题
文本预览
相关文档 最新文档