標(biāo)題:
52單片機(jī)接兩個(gè)DS18B20,測(cè)出的溫度顯示相差很大,大概10度左右,大神可以給些建議...
[打印本頁(yè)]
作者:
onana
時(shí)間:
2019-5-25 19:01
標(biāo)題:
52單片機(jī)接兩個(gè)DS18B20,測(cè)出的溫度顯示相差很大,大概10度左右,大神可以給些建議...
#include <REGX52.H>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
typedef unsigned int u16; //對(duì)數(shù)據(jù)類型進(jìn)行聲明定義
typedef unsigned char u8;
sbit IRIN=P3^2;
u8 IrValue[6];
u8 Time;
sbit wela = P0^7;
sbit dula = P0^6;
sbit EN=P2^7;//使能
sbit RS=P2^6;//數(shù)據(jù)/命令選擇端(H/L)
sbit RW=P2^5;//讀/寫端(H/L)
sbit DS1=P2^4; //DS18B20one接入口
sbit DS2=P2^3; //DS18B20two接入口
sbit Dcfcold=P2^2;
sbit Dcfhot=P2^1;
sbit Dcfmix=P2^0;
bit f1=1; //正負(fù)溫度標(biāo)志位
bit f2=1;
unsigned char m=1,y=0,o=0;//寄存器
unsigned int sdata1; //存放整數(shù)溫度
unsigned char xiaoshu11; //存放小數(shù)后第一位溫度數(shù)值
unsigned char xiaoshu12; //存放小數(shù)后第二位溫度數(shù)值
unsigned int sdata2; //存放整數(shù)溫度
unsigned char xiaoshu21; //存放小數(shù)后第一位溫度數(shù)值
unsigned char xiaoshu22; //存放小數(shù)后第二位溫度數(shù)值
unsigned char code huany[]=" Welcome to use "; //歡迎使用
unsigned char code tt[] =" ter thermometer"; //溫度計(jì)
unsigned char code duqu[]=" loading... "; //讀取
unsigned char code tab1[]=" C C "; //框架
unsigned char code tab2[]="U: C L: C ";
unsigned char code shuzu[]="0123456789+- .*"; //數(shù)字,,10加號(hào),,,11減號(hào),,,12空格,,,,13點(diǎn),,,,14*
uchar u,l,p,Key_value;
//uchar str[4];
uchar str[4];//uchartostr函數(shù)轉(zhuǎn)換的字符串 同時(shí)可以把16進(jìn)制轉(zhuǎn)成10進(jìn)制
/*******************************************************************************
* 函 數(shù) 名 : delay
* 函數(shù)功能 : 延時(shí)函數(shù),i=1時(shí),大約延時(shí)10us
*******************************************************************************/
void Irdelay(u16 i)
{
while(i--);
}
void Ir_work(void)//紅外鍵值散轉(zhuǎn)程序
{
switch(IrValue[2]) //判斷第三個(gè)數(shù)碼值
{
case 0x40:u++;break;
case 0x19:u--;break;
case 0x07:l++;break;
case 0x09:l--;break;
// case 0x0C:mix=1;break;
// case 0x16:imix=0;break;
default:break;
}
// irpro_ok=0;//處理完成標(biāo)志
}
/*******************************************************************************
* 函數(shù)名 : IrInit()
* 函數(shù)功能 : 初始化紅外線接收
* 輸入 : 無(wú)
* 輸出 : 無(wú)
*******************************************************************************/
void IrInit()
{
IT0=1;//下降沿觸發(fā)
EX0=1;//打開(kāi)中斷0允許
EA=1; //打開(kāi)總中斷
IRIN=1;//初始化端口
}
/*******************************************************************************
* 函 數(shù) 名 : main
* 函數(shù)功能 : 主函數(shù)
* 輸 入 : 無(wú)
* 輸 出 : 無(wú)
*******************************************************************************/
//void main()
//{
// IrInit();
// while(1)
// {
// DisplayData[0] = smgduan[IrValue[2]/16];
// DisplayData[1] = smgduan[IrValue[2]%16];
// DisplayData[2] = smgduan[16];
// DigDisplay();
// }
//}
/*******************************************************************************
* 函數(shù)名 : ReadIr()
* 函數(shù)功能 : 讀取紅外數(shù)值的中斷函數(shù)
* 輸入 : 無(wú)
* 輸出 : 無(wú)
*******************************************************************************/
void ReadIr() interrupt 0
{
u8 j,k;
u16 err;
Time=0;
Irdelay(700); //7ms
if(IRIN==0) //確認(rèn)是否真的接收到正確的信號(hào)
{
err=1000; //1000*10us=10ms,超過(guò)說(shuō)明接收到錯(cuò)誤的信號(hào)
/*當(dāng)兩個(gè)條件都為真是循環(huán),如果有一個(gè)條件為假的時(shí)候跳出循環(huán),免得程序出錯(cuò)的時(shí)
侯,程序死在這里*/
while((IRIN==0)&&(err>0)) //等待前面9ms的低電平過(guò)去
{
Irdelay(1);
err--;
}
if(IRIN==1) //如果正確等到9ms低電平
{
err=500;
while((IRIN==1)&&(err>0)) //等待4.5ms的起始高電平過(guò)去
{
Irdelay(1);
err--;
}
for(k=0;k<4;k++) //共有4組數(shù)據(jù)
{
for(j=0;j<8;j++) //接收一組數(shù)據(jù)
{
err=60;
while((IRIN==0)&&(err>0))//等待信號(hào)前面的560us低電平過(guò)去
{
Irdelay(1);
err--;
}
err=500;
while((IRIN==1)&&(err>0)) //計(jì)算高電平的時(shí)間長(zhǎng)度。
{
Irdelay(10); //0.1ms
Time++;
err--;
if(Time>30)
{
return;
}
}
IrValue[k]>>=1; //k表示第幾組數(shù)據(jù)
if(Time>=8) //如果高電平出現(xiàn)大于565us,那么是1
{
IrValue[k]|=0x80;
}
Time=0; //用完時(shí)間要重新賦值
}
}
}
if(IrValue[2]!=~IrValue[3])
{
return;
}
}
}
/**************************************/
/*************LCD1602*****************/
void delay(uint z) //延時(shí)函數(shù)
{
uint x,y;
for(x=z;x>0;x--)
for(y=120;y>0;y--);
}
void write_com(uchar com) //寫命令
{
P0=com;
RS=0;
EN=0;
delay(10);
EN=1;
delay(10);
EN=0;
}
void write_data(uchar date) //寫數(shù)據(jù)
{
P0=date;
RS=1;
EN=0;
delay(10);
EN=1;
delay(10);
EN=0;
}
void init()
{
RW=0;
dula=0;
wela=0;
write_com(0x38); //顯示模式設(shè)置:16×2顯示,5×7點(diǎn)陣,8位數(shù)據(jù)接口
delay(20);
write_com(0x0c); //顯示模式設(shè)置
delay(20);
write_com(0x06); //顯示模式設(shè)置:光標(biāo)右移,字符不移
delay(20);
write_com(0x01); //清屏幕指令,將以前的顯示內(nèi)容清除
delay(20);
}
uchar *uchartostr(uchar num) //將一個(gè)字節(jié)的數(shù)據(jù)轉(zhuǎn)換為字符串 或10進(jìn)制
{
uchar x2,x1,x0,i;
x2=num/100;
x1=num%100/10;
x0=num%100%10;
i=0;
if(x2!=0)
{
str[i]=x2+48;
i++;
}
if(x1!=0)
{
str[i]=x1+48;
i++;
}
str[i]=x0+48;
i++;
str[i]='\0';
return str;
}
void lcd_dis(uchar X,uchar Y,uchar *dis) //顯示數(shù)據(jù)數(shù)組
{
uchar pos;
switch(X)
{
case 0:X=0x00;break;
case 1:X=0x40;break;
break;
default:break;
}
pos =0x80+X+Y;
write_com(pos); //顯示地址
while(*dis!='\0')
{
write_data(*dis++);
}
}
void delay_50us(unsigned int t) //延時(shí)函數(shù)
{
unsigned int j,k;
for (;t>0;t--)
{
for(j=10;j>0;j--)
{
for(k=1;k>0;k--);
}
}
}
/////////////////////////////18B20one//////////////////////////////
void delay_18B201(unsigned int i) //18b20全局延時(shí)
{
while(i--);
}
Init_DS18B201(void)
{
unsigned char x=0;
DS1=1;//DQ復(fù)位
delay_18B201(10);//稍做延時(shí)
DS1=0;//單片機(jī)將DQ拉低
delay_18B201(80);//精確延時(shí)大于480us
DS1=1;//拉高總線
delay_18B201(20);
x=DS1;//稍做延時(shí)后如果x=0則初始化成功x=1則初始化失敗
delay_18B201(30);
return x;
}
//讀一個(gè)字節(jié)
ReadOneChar1(void)
{
unsigned char i=0;
unsigned char dat=0;
for(i=8;i>0;i--)
{
DS1=0;//給脈沖信號(hào)
dat>>=1;
DS1=1;//給脈沖信號(hào)
if(DS1)
dat|=0x80;
delay_18B201(4);
}
return(dat);
}
//寫一個(gè)字節(jié)
WriteOneChar1(unsigned char dat)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
DS1=0;
DS1=dat&0x01;
delay_18B201(5);
DS1=1;
dat>>=1;
}
return(dat);
}
void ReadTemperature1(void)
{
unsigned char L=0;
unsigned char H=0;
Init_DS18B201();
WriteOneChar1(0xCC);//跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar1(0x44);//啟動(dòng)溫度轉(zhuǎn)換
delay_18B201(100);
Init_DS18B201();
WriteOneChar1(0xCC);//跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar1(0xBE);//讀取溫度寄存器等(共可讀9個(gè)寄存器前兩個(gè)就是 溫度
L=ReadOneChar1(); //溫度低8位
H=ReadOneChar1(); //溫度高8位
f1=1;
sdata1 = L/16+H*16; //整數(shù)部分
xiaoshu11 = (L&0x0f)*10/16; //小數(shù)第一位
xiaoshu12 =(L&0x0f)*100/16%10; //小數(shù)第二位
}
///////////////////18B20two/////////////
void delay_18B202(unsigned int i) //18b20全局延時(shí)
{
while(i--);
}
Init_DS18B202(void)
{
unsigned char x=0;
DS2=1;//DQ復(fù)位
delay_18B202(10);//稍做延時(shí)
DS2=0;//單片機(jī)將DQ拉低
delay_18B202(80);//精確延時(shí)大于480us
DS2=1;//拉高總線
delay_18B202(20);
x=DS2;//稍做延時(shí)后如果x=0則初始化成功x=1則初始化失敗
delay_18B202(30);
return x;
}
//讀一個(gè)字節(jié)
ReadOneChar2(void)
{
unsigned char i=0;
unsigned char dat=0;
for(i=8;i>0;i--)
{
DS2=0;//給脈沖信號(hào)
dat>>=1;
DS2=1;//給脈沖信號(hào)
if(DS2)
dat|=0x80;
delay_18B202(4);
}
return(dat);
}
//寫一個(gè)字節(jié)
WriteOneChar2(unsigned char dat)
{
unsigned char i=0;
for(i=8;i>0;i--)
{
DS2=0;
DS2=dat&0x01;
delay_18B202(5);
DS2=1;
dat>>=1;
}
return(dat);
}
void ReadTemperature2(void)
{
unsigned char L=0;
unsigned char H=0;
Init_DS18B202();
WriteOneChar2(0xCC);//跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar2(0x44);//啟動(dòng)溫度轉(zhuǎn)換
delay_18B202(100);
Init_DS18B202();
WriteOneChar2(0xCC);//跳過(guò)讀序號(hào)列號(hào)的操作
WriteOneChar2(0xBE);//讀取溫度寄存器等(共可讀9個(gè)寄存器前兩個(gè)就是 溫度
L=ReadOneChar2(); //溫度低8位
H=ReadOneChar2(); //溫度高8位
f2=1;
sdata2 = L/16+H*16; //整數(shù)部分
xiaoshu21 = (L&0x0f)*10/16; //小數(shù)第一位
xiaoshu22 =(L&0x0f)*100/16%10; //小數(shù)第二位
}
void display0()//顯示welcome to use the
{
unsigned char i,w,h=0x8f,i1,w1,h1=0xcf,w2,i2,h2,g=2;
init();
for(w=0;w<16;w++) //顯示歡迎
{
write_com(h--);//第一行自減左移
for(i=0;i<16;i++)
{
write_data(huany[i]);
delay_50us(5);
}
}
for(w1=0;w1<16;w1++)//第二行自減左移
{
write_com(h1--);
for(i1=0;i1<16;i1++)
{
write_data(tt[i1]);
delay_50us(5);
}
}
delay_50us(5000);//顯示loading
init();
write_com(0x80);
for(w2=0;w2<16;w2++)//向右顯示
{
write_data(duqu[w2]);
delay_50us(200);
}
while(g--)//小數(shù)點(diǎn)循環(huán)亮滅
{
write_com(0x8a);
for(i2=0;i2<3;i2++)
{
write_data(duqu[i2]);
}
write_com(0x8a);
for(h2=10;h2<14;h2++)
{
delay_50us(300);
write_data(duqu[h2]);
delay_50us(300);
}
}
}
void display1() //顯示框架
{
unsigned char p,q;
init();//全局清零
write_com(0x80);
for(q=0;q<16;q++) //顯示TMHL
{
write_data(tab1[q]);
}
write_com(0xc0);
for(p=0;p<16;p++)
{
write_data(tab2[p]);
}
write_com(0xc4);
write_data(0Xdf);
write_com(0xcd);
write_data(0xdf);
}
void displayone(unsigned int date) //顯示溫度,
{
if(date/100==0) //100度內(nèi)
{
write_com(0x80);
write_data(shuzu[date/10]);//十位
write_com(0x81);
write_data(shuzu[date%10]);//個(gè)位
write_com(0x82);
write_data(shuzu[13]);//小數(shù)點(diǎn)
write_com(0x83);
write_data(shuzu[xiaoshu11]);//小數(shù)點(diǎn)后一位
write_com(0x84);
write_data(shuzu[xiaoshu12]); //小數(shù)點(diǎn)后二位
write_com(0x85);
write_data(0xdf);
}
}
void displaytwo(unsigned int date) //顯示溫度,
{
if(date/100==0) //100度內(nèi)
{
write_com(0x88);
write_data(shuzu[date/10]);//十位
write_com(0x89);
write_data(shuzu[date%10]);//個(gè)位
write_com(0x8a);
write_data(shuzu[13]);//小數(shù)點(diǎn)
write_com(0x8b);
write_data(shuzu[xiaoshu21]);//小數(shù)點(diǎn)后一位
write_com(0x8c);
write_data(shuzu[xiaoshu22]); //小數(shù)點(diǎn)后二位
write_com(0x8d);
write_data(0xdf);
}
}
//void fuhao() //溫度正負(fù)子程序
//{
// if(f==1) //溫度為正
// {
// write_com(0x84);
// write_data(shuzu[12]);
// }
// else if(f==0) //溫度為負(fù),顯示負(fù)號(hào)
// {
// write_com(0x84);
// write_data(shuzu[11]);
// }
//}
void key()
{
Key_value = P1;
Key_value = Key_value & 0x0f;
if ( Key_value != 0x0f )
{
switch(Key_value)
{
case 0x0e: u++; break;
case 0x0d: u--; break;
case 0x0b: l++; break;
case 0x07: l--; break;
}
}
}
void compare()//溫度數(shù)據(jù)比較
{
if(sdata1>=u) //溫度大于上限,開(kāi)冷關(guān)熱
{
displayone(sdata1);
displaytwo(sdata2);
Dcfcold =1; //1.5
Dcfhot =0; //1.3
}
else if(l>0&sdata1<=l) //溫度小于下限,開(kāi)熱關(guān)冷
{
displayone(sdata1);
displaytwo(sdata2);
Dcfcold =0; //1.5
Dcfhot =1; //1.4
}
else if(sdata1<u&sdata1>l)
{
displayone(sdata1);
displaytwo(sdata2);
Dcfcold =0; //1.5
Dcfhot =0; //1.4
Dcfmix =0;
}
else
displayone(sdata1);
displaytwo(sdata2);
}
void main()
{
//P1=0x00;
u=35;
l=20;
IrInit();
display0(); //歡迎,
display1();//框架
while(1)
{
lcd_dis(1,2,uchartostr( u ) );
lcd_dis(1,11,uchartostr( l ) );
ReadTemperature1(); //測(cè)溫程序
ReadTemperature2(); //測(cè)溫程序
// fuhao();//負(fù)號(hào)顯示程序
key(); //按鍵
compare();
Ir_work();
}
}
復(fù)制代碼
作者:
wc86110
時(shí)間:
2019-5-25 22:56
???是在同一個(gè)空間還是不同空間?
作者:
onana
時(shí)間:
2019-5-26 10:03
wc86110 發(fā)表于 2019-5-25 22:56
???是在同一個(gè)空間還是不同空間?
同一空間
作者:
wc86110
時(shí)間:
2019-5-26 13:36
同一空間存在溫差也很正常,得看兩個(gè)探頭所在周圍環(huán)境有沒(méi)有熱源(溫差)
作者:
滄浪
時(shí)間:
2019-5-26 14:16
你這個(gè)是用的是幾個(gè)DS18B20呢??jī)蓚(gè)18B20應(yīng)該得 有使用序列號(hào)相關(guān)的代碼吧,我沒(méi)有看見(jiàn)相關(guān)代碼
作者:
qoou1997
時(shí)間:
2019-5-26 15:53
如果這個(gè)溫差是恒定的話,可以考慮后期先對(duì)數(shù)據(jù)進(jìn)行處理(加減定值),然后再顯示
作者:
8往事隨風(fēng)001
時(shí)間:
2019-5-27 09:49
這是我曾用32寫的,可做參考。!
http://www.torrancerestoration.com/bbs/dpj-161142-1.html
作者:
zhanghyg
時(shí)間:
2019-5-27 11:22
兩個(gè)端口有沒(méi)有上拉電阻?
歡迎光臨 (http://www.torrancerestoration.com/bbs/)
Powered by Discuz! X3.1