找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5178|回复: 1
打印 上一主题 下一主题
收起左侧

求助,DS18B20多点测温 搜索报警程序出问题

[复制链接]
跳转到指定楼层
楼主
ID:62689 发表于 2014-6-11 23:48 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下是出问题那段程序,我的温度报警值都设在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();      
        }  
}






分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:2318 发表于 2014-7-27 13:34 来自手机 | 只看该作者
最好是把工程文件也上传上来这样方便调试
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表