為什么使用單個ds18b20測溫用數碼管顯示很正常。
當多個ds18b20測溫時,數碼管顯示其中一個ds18b20的溫度時數碼管一個很亮,其他數碼管很暗還會一直閃??
源碼:
#include"delay.h"
void delay(uint z) //毫秒級延時函數
{
uint x,y;
for(x=z;x>0;x--)
for(y=240;y>0;y--);
}
void delay_18B20(uint t) //ds18b20延時函數
{
while(t--);
}
數碼管程序:
#include<stc12c5a60s2.h>
#include"smg.h"
#include"delay.h"
#define DataPort P1 //定義數據端口 程序中遇到DataPort 則用P0 替換
sbit LATCH2=P2^3; //位選
sbit LATCH1=P2^2; //段選
uchar code smg_du[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
uchar code smg_we[]={0xbf,0x7f};
void display(uchar i,uchar dat)
{
DataPort=0; //清空數據,防止有交替重影
LATCH1=1; //段鎖存
LATCH1=0;
DataPort=smg_we[i]; //取位碼
LATCH2=1; //位鎖存
LATCH2=0;
DataPort=smg_du[dat]; //取顯示數據,段碼
LATCH1=1; //段鎖存
LATCH1=0;
// delay_18B20(200); // 掃描間隙延時,時間太長會閃爍,太短會造成重影
// DataPort=0; //清空數據,防止有交替重影
}
ds18b20程序:
#include<stc12c5a60s2.h>
#include"ds18b20.h"
#include"smg.h"
#include"delay.h" //注:stc12c5a60s2單片機執(zhí)行一條語句的時間是普通51單片機的1/12,在寫時序時一定要注意到
sbit DQ=P2^0;
uchar code str1[]={0x28,0xC2,0x99,0x41,0x07,0x00,0x00,0xBE}; //ROM 1
uchar code str2[]={0x28,0xAE,0x79,0xFA,0x05,0x00,0x00,0x90}; //ROM 2
uchar data disdata[2];
uint tvalue; //溫度值
void init_ds18b20()//ds1820復位
{
DQ=1; //DQ復位
delay_18B20(40); //延時
DQ=0; //DQ拉低
delay_18B20(1000); //精確延時大于480us
DQ=1; //拉高
delay_18B20(400);
}
void write_byte(uchar dat) //寫一個字節(jié)
{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay_18B20(100);
DQ=1;
dat>>=1;
}
}
uchar read_byte() //讀一個字節(jié)
{
uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{
DQ=0; //給脈沖信號
dat>>=1;
DQ=1; //給脈沖信號
if(DQ)
dat|=0x80;
delay_18B20(100);
}
return(dat);
}
void ds18b20_Matchrom(uchar a) //匹配ROM
{
char j;
write_byte(0x55); //發(fā)送匹配ROM命令
if(a==1)
{
for(j=0;j<8;j++)
write_byte(str1[j]); //發(fā)送18B20的序列號,先發(fā)送低字節(jié)
}
if(a==2)
{
for(j=0;j<8;j++)
write_byte(str2[j]); //發(fā)送18B20的序列號,先發(fā)送低字節(jié)
}
}
uchar read_temp(uchar z) //讀取溫度值并轉換
{
uchar a,b;
init_ds18b20();
write_byte(0xcc); //跳過讀序列號
init_ds18b20();
if(z==1)
{
ds18b20_Matchrom(1); //匹配ROM 1
}
if(z==2)
{
ds18b20_Matchrom(2); //匹配ROM 2
}
write_byte(0x44);//*啟動溫度轉換*/
delay(5);
init_ds18b20();
write_byte(0xcc); //跳過讀序列號
init_ds18b20();
if(z==1)
{
ds18b20_Matchrom(1); //匹配ROM 1
}
if(z==2)
{
ds18b20_Matchrom(2); //匹配ROM 2
}
write_byte(0xbe);//*讀取溫度*/
a=read_byte();
b=read_byte();
tvalue=b<<4;
tvalue|=(a&0xf0)>>4;
return(tvalue);
}
void ds1820display()//溫度值顯示
{
if(z==1)
{
read_temp();
disdata[0]=tvalue%100/10;//十位數
display(0,disdata[0]);
delay_18B20(2000);
disdata[1]=tvalue%10;//個位數
display(1,disdata[1]);
// delay(5);
}
}
主程序;
#include"ds18b20.h"
void main()
{
init_ds18b20();
while(1)
{
ds1820display(); //溫度值顯示
}
}
|