以下是出問題那段程序,我的溫度報警值都設在38,常溫下是不會報警的,但程序在運行三四分鐘后就滿足了報警條件,把led1和led2都點亮,請高手指點,這程序到底問題出在那里。 **********************出問題那段程序 *************************
for(m=0;m<2;m++)
{
for(l=0;l<2;l++)
{
for(n=0;n<8;n++)
{
if(ID0[m][n]==ID[l][n]) //那個溫度器報警,就會搜到相應的序列號,
{
if(m==0) DS_led1=0;
if(l==1) DS_led2=0;
}
}
}
}
******************************************************************************
******************這是主程序 “DS18B20多點測溫 自動搜索報警程序 用四位數(shù)碼管顯示”***********************
#include <STC89C5xRC.H>
#include <intrins.h>
#define uchar unsigned char //定義無符號單字節(jié)
#define uint unsigned int //定義無符號整形
#define MAXNUM 2 //定義最多DS18B20個數(shù) 超過的無法顯示
sbit DQ=P1^2; //定義數(shù)據(jù)線
//sbit LED1=P1^0;
sbit DS_led1=P1^0;
sbit DS_led2=P1^1;
//sbit DS_led3=P1^3;
//sbit DS_led4=P1^4;
uchar Temp_Value_L[4];
uchar Temp_Value_H[4];
uchar Display_Digit[]={0,0,0,0};
uchar code df_Table[]={ 0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9}; //如3*0.0625=1.875,四舍五入得2
//共陽極數(shù)碼管及空白顯示
uchar code DSY_CODE[]=
{ 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff};
uchar code Alarm_Temp[4][2]={32,-40,32,-40,32,-40,32,-40};
uchar CurrentT=0;
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}
//uchar Ti_1[30];
void Delay(uint x)
{
while(--x);
}
/************************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)//寫一個字節(jié)
{
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()//讀一個字節(jié) 子程序
{
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 write_Alarm_Temp(uchar i) //寫報警溫度
{
uchar f;
reset();
write_byte(0x55); //匹配ROM
for(f=0;f<8;f++)
{
write_byte(ID[f]);
}
delay_nus(100);
write_byte(0x4e); //寫存儲器
delay_nus(100);
for(f=0;f<2;f++)
{
write_byte(Alarm_Temp[f]);
}
//拷貝暫存器到EEPROM
delay_nus(100);
reset();
write_byte(0x55); //匹配ROM
for(f=0;f<8;f++)
{
write_byte(ID[f]);
}
delay_nus(100);
write_byte(0x48); //拷貝暫存器到EEPROM
delay_nus(100);
}
void read_temp(uchar i)//讀取溫度 子程序
{
uchar f;
reset();
write_byte(0xcc); //忽略ROM
write_byte(0x44); //溫度轉(zhuǎn)換指令
while(DQ==0); //溫度轉(zhuǎn)換時DQ=0,結束后DQ=1
//delay_nms(50000); //600ms
reset();
write_byte(0x55); //匹配ROM
for(f=0;f<8;f++)
{
write_byte(ID[f]);//發(fā)匹配ROM
}
delay_nus(100);
write_byte(0xbe); //讀存儲器
delay_nus(100);
Temp_Value_L=read_byte();
Temp_Value_H=read_byte();
}
/***********************自動搜索ROM*****************************/
void search_rom(void)//搜索ROM
{
uchar xdata k,l,chongtuwei,m,n;
uchar xdata zhan[(MAXNUM-1)];
uchar xdata ss[64];
l=0;
do
{
reset();
write_byte(0xf0); //搜索ROM
for(m=0;m<8;m++)
{
uchar s=0;
for(n=0;n<8;n++)
{
k=read_2bit();//讀兩位數(shù)據(jù)
k=k&0x03;
s>>=1;
if(k==0x01)//01讀到的數(shù)據(jù)為0 寫0 此位為0的器件響應
{
write_bit (0);
ss[(m*8+n)]=0;
}
else if(k==0x02)//讀到的數(shù)據(jù)為1 寫1 此位為1的器件響應
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
}
else if(k==0x00)//讀到的數(shù)據(jù)為00 有沖突位 判斷沖突位
{ //如果沖突位大于棧頂寫0 小于棧頂寫以前數(shù)據(jù) 等于棧頂寫1
chongtuwei=m*8+n+1;
if(chongtuwei>zhan[l])
{
write_bit (0);
ss[(m*8+n)]=0;
zhan[++l]=chongtuwei;
}
else if(chongtuwei<zhan[l])
{
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;
}
}
}
ID[num][m]=s;
}
num=num+1;
}while(zhan[l]!=0&&(num<MAXNUM));
}
//在數(shù)碼管上顯示溫度
void Display_Temperature()
{
uint i;
uint t=750;
uchar ng=0,np=0;
char Signed_Current_Temp; //有符號通用標記
if( (Temp_Value_H[1] & 0xF8) ==0xF8 ) //處理有符號
{
Temp_Value_H[1]=~Temp_Value_H[1];
Temp_Value_L[1]=~Temp_Value_L[1]+1;
if(Temp_Value_L[1]==0x00) Temp_Value_H[1]++;
ng=1;np=0x7f;
}
Display_Digit[0]=df_Table[ Temp_Value_L[0] & 0x0F ];
CurrentT=( ( Temp_Value_L[0] & 0xF0 ) >>4 ) | ( ( Temp_Value_H[0] & 0x07 ) <<4 );
Signed_Current_Temp=ng?-CurrentT:CurrentT;
//HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?1:0;
//LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?1:0;
//Display_Digit[3]==CurrentT/100;
Display_Digit[2]=CurrentT/10;
Display_Digit[1]=CurrentT%10;
if(Display_Digit[2]==0)
{
Display_Digit[2]=10;
np=0xbf;
}
//刷新顯示若干時間
for(i=0;i<150;i++)
{
P0=DSY_CODE[Display_Digit[0]]; //小數(shù)位
P2=0xef;Delay(t);
P0=( DSY_CODE[ Display_Digit[1] ] ) & 0x7f; //個位及小數(shù)點
P2=0xdf;Delay(t);
P0=DSY_CODE[Display_Digit[2]]; // 十位
P2=0xbf;Delay(t);
if(ng) //如果為負則在調(diào)整后的位置顯示"-"
{
P0=0xbf;P2=0x7f;Delay(t);
}
}
}
void alarm_search(void)
{
uchar xdata k,l,chongtuwei,m,n,numb;
uchar xdata zhan[(MAXNUM-1)];
uchar xdata 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();//讀兩位數(shù)據(jù)
k=k&0x03;
s>>=1;
if(k==0x01)//01讀到的數(shù)據(jù)為0 寫0 此位為0的器件響應
{
write_bit (0);
ss[(m*8+n)]=0;
}
else if(k==0x02)//讀到的數(shù)據(jù)為1 寫1 此位為1的器件響應
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
}
else if(k==0x00)//讀到的數(shù)據(jù)為00 有沖突位 判斷沖突位
{ //如果沖突位大于棧頂寫0 小于棧頂寫以前數(shù)據(jù) 等于棧頂寫1
chongtuwei=m*8+n+1;
if(chongtuwei>zhan[l])
{
write_bit (0);
ss[(m*8+n)]=0;
zhan[++l]=chongtuwei;
}
else if(chongtuwei<zhan[l])
{
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&&(numb<MAXNUM));
for(m=0;m<2;m++)
{
for(l=0;l<2;l++)
{
for(n=0;n<8;n++)
{
if(ID0[m][n]==ID[l][n]) //那個溫度器報警,就會搜到相應的序列號,
{
if(m==0) DS_led1=0;
if(l==1) DS_led2=0;
}
}
}
}
}
void main (void)
{
uchar i;
search_rom();//搜索ROM并且存儲
//DS_led1=1;
while(1)
{
//DS_led1=1;DS_led2=1;
for(i=0;i<num;i++) //編號0到num-1 個ds18b20 循環(huán)
{
write_Alarm_Temp(i); //寫報警溫度
read_temp(i); //讀編號 i (0--(num-1)) ds18b20 的溫度
Display_Temperature();
}
alarm_search();
}
}
|