×
单片机 > 单片机程序设计 > 详情

51单片机多路DS18B20测温显示并读取序列号

发布时间:2020-06-15 发布时间:
|

/*********************************************


功 能:读取序列号并匹配序列号,并读温度值

多功能试验板显示多路温度采集

正常显示2个DS18B20温度

正常读取DS18B20序列号


单片机:STC12C5A60S2

晶 振:11.0592M

作 者:苏义江改编自网络

时 间:2016-8-25

************************************************/

#include  

#include  

#define uchar unsigned char 

#define uint unsigned int 

sbit RS=P2^7; 

sbit RW=P2^6; 

sbit EN=P2^5; 

sbit DQ=P3^4; //传感器引脚 

sbit key=P3^7;

sbit d1=P1^3;//指示灯

sbit d2=P1^4;

bit st=1; 


uchar code table0[]={"DuoLuWenDuXS:U "}; 

uchar code table2[]={"SD: "}; //湿度

uchar code table1[]={"0123456789ABCDEF"}; 

//现有的2个DS18B20传感器的序列号ROM1,ROM2

uchar DSrom[4][8]={//4个器件每个64位序列号

{0x28,0xff,0x2a,0x0A,0x22,0x04,0x00,0xf6},//ROM1 

{0x28,0xFF,0x0b,0x0d,0x20,0x04,0x00,0x0a},//ROM2


{0x28,0x0C,0xBA,0xBA,0x02,0x00,0x00,0x54},//ROM3 

{0x28,0xff,0x91,0x14,0x22,0x04,0x00,0xe4}//ROM4 

};

int f[4]; //温度数组

int tvalue; //温度值变量

float ftvalue; //温度值变量

uchar fCode[8];//序列号数组

uint warnl=300; //设定温度值高

uint warnh=992;//设定温度值低

void ds1820wr(uchar dat);//写数据

void ds1820rst();//ds1820复位

uchar ds1820rd();//读数据 

void DispCode();//读取序列号


uchar tflag;//温度正负标志 


//////////lcd1602程序//////////// 

void delay1ms(uint ms)//延时1毫秒(不够精确的) 

uint i,j; 

for(i=0;i

for(j=0;j<620;j++); 

void wr_com(uchar com)//写指令// 

delay1ms(1); 

RS=0; 

RW=0; 

EN=0; 

P0=com; 

delay1ms(1); 

EN=1; 

delay1ms(1); 

EN=0; 

}

void wr_dat(uchar dat)//写数据// 

delay1ms(1);; 

RS=1; 

RW=0; 

EN=0; 

P0=dat; 

delay1ms(1); 

EN=1; 

delay1ms(1); 

EN=0; 

void lcd_init()//1602初始化设置// 

delay1ms(15); 

wr_com(0x38);

delay1ms(5); 

wr_com(0x08);delay1ms(5); 

wr_com(0x01);delay1ms(5); 

wr_com(0x06);delay1ms(5); 

wr_com(0x0c);delay1ms(5); 


}

void display(uchar *p)//显示字符串 

while(*p!='') 

wr_dat(*p); 

p++; 

delay1ms(1); 

}

void displayinit()//初始化显示 

lcd_init(); 

wr_com(0x80); 

display(table0); 


wr_com(0xC6);

wr_dat(0xdf);

wr_com(0xC7);

wr_dat('C');

wr_com(0xCf);

wr_dat(0x25);

wr_com(0XC9);

display(table2); 

}

void tmstart()//初始化ds18b20 

{

DQ=1; 

d1=1; 

d2=1; 

ds1820rst(); 

delay1ms(1); 

ds1820wr(0xcc); 

ds1820wr(0x44); 

void read_dealtemp()//读取并处理温度 

uchar i,j,t; 

uchar a,b; 

for(j=0;j<5;j++) //挂载4个设备

ds1820rst(); //复位

delay1ms(1); 

ds1820wr(0x55); //匹配EOM指令 

for(i=0;i<8;i++) 

ds1820wr(DSrom[j][i]);//发送64位序列号 

ds1820wr(0xbe);//温度转换 


a=ds1820rd(); //读高位

b=ds1820rd(); //读低位 

tvalue=b; 

tvalue<<=8; 

tvalue=tvalue|a; 

if(tvalue<0) //判断正负温度

d1=1; 

tvalue=~tvalue+1; 

wr_com(0xc0); //第二行第一列 

wr_dat(0x2d); //负温度符号"-"

if(tvalue

d2=0; //报警

DQ=0; 

else 

d2=1; 

DQ=1; 

}

else 

d2=1; 

wr_com(0xc0); 

wr_dat(' '); 

if(tvalue>warnh) //温度高于设定值warnh=992; 

d1=0; //报警

DQ=0; 

else

d1=1; 

DQ=1; 

if(j==0) 

{

wr_com(0x8f); 

wr_dat('1'); 

if(j==1) 

wr_com(0x8f); 

wr_dat('2'); 

if(j==2) 

wr_com(0x8f); 

wr_dat('3'); 

}

if(j==3) 

wr_com(0x8f); 

wr_dat('4'); 

if(j==4) 

wr_com(0x8f); 

wr_dat('5'); 

ftvalue=tvalue*0.0625; 

tvalue=ftvalue*10+0.5;

ftvalue=ftvalue+0.05; //温度补偿 

f[j]=tvalue;//温度扩大十倍,精确到一位小数 

tvalue=f[j]; 

t=tvalue/1000; 

wr_com(0x80+0x41); 

wr_dat(table1[t]);//显示百位 

t=tvalue%1000/100; 

wr_dat(table1[t]);//显示十位 

t=tvalue%100/10; 

wr_dat(table1[t]);//显示个位 

wr_dat(0x2e); //显示小数点儿 

t=tvalue%10/1; 

wr_dat(table1[t]);//显示小数位

delay1ms(5000); 

}

void keyscan()//按键

{

if(key==0)

{

delay1ms(30);

if(key==0)

{

st=~st;

}

while(!key);

}

}

void main() 

d1=1; 

d2=1; 

DQ=1; 

displayinit();//初始化显示 

while(1) 

keyscan();//按住按键等4个器件循环完毕显示序列号

if(st==1) 

wr_com(0x01);

displayinit();//初始化显示

tmstart();//初始化 

read_dealtemp();//读取温度 

else

{

wr_com(0x01);

keyscan();//按住按键等4个器件循环完毕显示序列号

DispCode();//读取序列号

delay1ms(1000); 

}

////////DS18B20函数///////////////

void delay_b20(uint n)//STC12C5A单片机定时1us

while(n--)

{

_nop_();


}


}


void ds1820rst()/*ds1820复位*/ 

uchar x=0; 

DQ = 1; //DQ复位 

delay_b20(1); //延时 

DQ = 0; //DQ拉低 

delay_b20(500); //精确延时大于480us 

DQ = 1; //拉高 

delay_b20(80); 


uchar ds1820rd()/*读数据*/ 

uchar i=0; 

uchar dat = 0;

for (i=0;i<8;i++) 

DQ = 1; //给脉冲信号

delay_b20(1);

DQ = 0; //给脉冲信号 

delay_b20(1); 

dat>>=1; 

DQ = 1; //给脉冲信号 

if(DQ) 

dat|=0x80; 

delay_b20(60); 

return(dat); 


void ds1820wr(uchar dat)/*写数据*/ 

uchar i=0; 

for (i=0; i<8; i++) 

DQ = 1; 

delay_b20(1);

DQ = 0; 

DQ = dat&0x01; 

delay_b20(60); 

DQ = 1; 

delay_b20(60); 

dat>>=1; 

delay_b20(1); 

///////////读取序列号//////////

void DispCode()//读取序列号 

uchar i,temp; 

ds1820rst(); 

ds1820wr(0x33); 

for (i=0;i<8;i++) 

{

fCode[i]=ds1820rd(); 

wr_com(0x80+0x40); 

for (i=0;i<8;i++) 

temp = fCode[i]>>4; //显示高四位 

if (temp<10) 

wr_dat(temp + 0x30); // 显示数字 

else 

wr_dat(temp + 0x37); //否则大于数字9显示字母

temp = fCode[i]&0x0f;//显示低四位 

if (temp<10) 

wr_dat(temp+ 0x30); 

else 

wr_dat(temp + 0x37); 

}


关键字:51单片机  DS18B20  测温显示  读取序列号 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
单片机中高阻态的实质及意义