以下是出问题那段程序,我的温度报警值都设在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多点测温 自动搜索报警程序 用四位数码管显示”***********************
#include <STC89C5xRC.H>
#include <intrins.h>
#define uchar unsigned char //定义无符号单字节
#define uint unsigned int //定义无符号整形
#define MAXNUM 2 //定义最多DS18B20个数 超过的无法显示
sbit DQ=P1^2; //定义数据线
//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
//共阳极数码管及空白显示
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)//写一个字节
{
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()//读一个字节 子程序
{
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); //温度转换指令
while(DQ==0); //温度转换时DQ=0,结束后DQ=1
//delay_nms(50000); //600ms
reset();
write_byte(0x55); //匹配ROM
for(f=0;f<8;f++)
{
write_byte(ID[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();//读两位数据
k=k&0x03;
s>>=1;
if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
{
write_bit (0);
ss[(m*8+n)]=0;
}
else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
}
else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位
{ //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写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));
}
//在数码管上显示温度
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]]; //小数位
P2=0xef;Delay(t);
P0=( DSY_CODE[ Display_Digit[1] ] ) & 0x7f; //个位及小数点
P2=0xdf;Delay(t);
P0=DSY_CODE[Display_Digit[2]]; // 十位
P2=0xbf;Delay(t);
if(ng) //如果为负则在调整后的位置显示"-"
{
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();//读两位数据
k=k&0x03;
s>>=1;
if(k==0x01)//01读到的数据为0 写0 此位为0的器件响应
{
write_bit (0);
ss[(m*8+n)]=0;
}
else if(k==0x02)//读到的数据为1 写1 此位为1的器件响应
{
s=s|0x80;
write_bit (1);
ss[(m*8+n)]=1;
}
else if(k==0x00)//读到的数据为00 有冲突位 判断冲突位
{ //如果冲突位大于栈顶写0 小于栈顶写以前数据 等于栈顶写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 循环
{
write_Alarm_Temp(i); //写报警温度
read_temp(i); //读编号 i (0--(num-1)) ds18b20 的温度
Display_Temperature();
}
alarm_search();
}
}
|