打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
51单片机多路DS18B20测温显示并读取序列号
/*********************************************

功 能:读取序列号并匹配序列号,并读温度值
多功能试验板显示多路温度采集
正常显示2个DS18B20温度
正常读取DS18B20序列号

单片机:STC12C5A60S2
晶 振:11.0592M
作 者:苏义江改编自网络
时 间:2016-8-25
************************************************/
#include <reg52.h> 
#include <intrins.h> 
#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<ms;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!='\0') 
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<warnl) //温度高于设定值warnl=300;
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); 
}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
基于AT89C2051+ds18b20的温度计程序设计
DS18B20和串口通信的那点事儿 ? 笨笨剥壳
温控器上下限设置方法
DS18B20温度测量、报警系统的设计
单片机开发模块化编程实例详解
提醒人们喝热饮的记忆杯垫制作(原理图 源代码 制作过程)
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服