求助!DS18B20报警程序的问题

2020-01-27 11:46发布

#include<reg52.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char

uint get_tem(void);                //温度转换声明
uchar code table[]={0xc0,0xf9,0xa4,0xb0,
0x99,0x92,0x82,0xf8,
0x80,0x90};  //整数段码
uchar code table1[]={0x40,0x79,0x24,0x30,
0x19,0x12,0x02,0x78,
0x00,0x10};                 //加小数点段码
void keysan();                //按键程序
sbit dula=P2^6;                //段声明
sbit wela=P2^7;                //位声明
sbit DQ=P2^2;                //温度传感器
sbit key1=P3^7;                //功能键定义
sbit key2=P3^5;                //减定义
sbit key3=P3^6;                //加定义
uchar set_st=0;                   //状态标志位
sbit BEEP=P2^3;    //定义蜂鸣器
bit beep_st;     //蜂鸣器间隔标志
signed char shangxian=38;        //上限报警温度,默认值为38
signed char xiaxian=5;                //下限报警温度,默认值为5
disp_alarm(uchar baojing);
bit shanshuo_st;        //标志位
uchar x;
void check_wendu(void);        //温度显示和分离子程序
void Alarm();         //报警程序
void init();          //初始化
uchar a1,a2,a3,a4;      
uint m;        //温度值全局变量
void display(uchar bia,uchar shi,uchar ge,uchar xiao);
void delay(uint a)                 //延时1毫秒子程序
{
        uint z,x;
                for(z=a;z>0;z--)
                        for(x=110;x>0;x--);
}

void delayus(uint x,uchar y)        //微秒延时函数
{
        uint i;
        uchar j;
        for(i=x;i>0;i--);
        for(j=y;j>0;j--);
}

void keysan()                                //按键程序
{
        if(key1==0)
        {
                delay(5);
                if(key1==0)
                {
                        set_st++;
                        shanshuo_st=1;
                        x=0;
                        if(set_st>2)
                                set_st=0;
                        while(!key1);                       
                }
                }
       
        if(set_st==1)
        {
                BEEP=1;
                if(x>=10)
                {
                        shanshuo_st=~shanshuo_st;
                        x=0;
               
                }
                if(shanshuo_st)
                        {
                        disp_alarm(shangxian);
                        }
        }
        if(set_st==2)
        {
                BEEP=1;
                if(x>=10)
                {
                        shanshuo_st=~shanshuo_st;
                        x=0;
                       
                }
                if(shanshuo_st)
                        {
                        disp_alarm(xiaxian);
                        }
        }       
                        

        if(set_st!=0)
        {       
                if(key2==0)
                {
                        delay(5);
                        if(key2==0)
                        {
                               
                                if(set_st==1)
                                {
                                        shangxian--;
                                          if(shangxian<xiaxian)
                                        shangxian=xiaxian;
                                               
                                }
                                else if(set_st==2)
                                {
                                        xiaxian--;
                                        if(xiaxian<0)
                                        xiaxian=0;       
                                }
                                while(!key2);
                        }
                }
                if(key3==0)
                {
                        delay(5);
                        if(key3==0)
                        {
                               
                                if(set_st==1)
                                {
                                        shangxian++;
                                        if(shangxian>99)
                                                shangxian=99;
                                       
                                }
                                else if(set_st==2)
                                {
                                        xiaxian++;
                                        if(xiaxian>shangxian)
                                                xiaxian=shangxian;               
                                }
                                while(!key3);
                        }
                }
        }       
       
               
}

//disp_alarm3(uchar baojing3)
//{       
       
       
//}
disp_alarm(uchar baojing)                //报警显示程序
{       
        dula=1;
        P0=table[baojing/10];
        dula=0;
        P0=0x00;
        wela=1;
        P0=0x02;
        wela=0;
        delay(5);

        dula=1;
        P0=table[baojing%10];
        dula=0;
        P0=0x00;
        wela=1;
        P0=0x04;
        wela=0;
        delay(5);
        if(set_st==1)
        {
                dula=1;
                P0=0x89;
                dula=0;
                P0=0x00;
                wela=1;
                P0=0x01;
                wela=0;
                delay(5);
        }
        if(set_st==2)
        {
                dula=1;
                P0=0xc7;
                dula=0;
                P0=0x00;
                wela=1;
                P0=0x01;
                wela=0;
                delay(5);
        }

        dula=1;
        P0=0xff;
        dula=0;
        P0=0x00;
        wela=1;
        P0=0x00;
        wela=0;
        delay(5);       
}


void display(uchar bai,uchar shi,uchar ge,uchar xiao)
{       
        dula=1;
        P0=table[bai];
        dula=0;
        P0=0x00;
        wela=1;
        P0=0x01;
        wela=0;
        delay(5);
       
        dula=1;
        P0=table1[shi];
        dula=0;
        P0=0x00;
        wela=1;
        P0=0x02;
        wela=0;
        delay(5);

        dula=1;
        P0=table[ge];
        dula=0;
        P0=0x00;
        wela=1;
        P0=0x04;
        wela=0;
        delay(5);

        dula=1;
        P0=table[xiao];
        dula=0;
        P0=0x00;
        wela=1;
        P0=0x08;
        wela=0;
        delay(5);
}


void reset()
{
        uchar st=1;
        DQ=1;
        _nop_();_nop_();
        while(st)
        {
                DQ=0;
                delayus(70,30);
                DQ=1;
                delayus(4,4);
                if(DQ==1)
                        st=1;
                else
                        st=0;
                delayus(50,10);
        }
}



void write_byte(uchar date)
{
        uchar i,temp;
        DQ=1;
        _nop_();_nop_();       
        for(i=8;i>0;i--)
        {
               
                DQ=0;               
                delayus(0,0);
                temp=date&0x01;
                if(temp==1)
                        DQ=1;
                        else
                                DQ=0;
                delayus(2,2);
                DQ=1;
                date>>=1;
               
        }
       
}   

uchar read_byte()
{
        uchar i,date;
        static bit j;
        for(i=8;i>0;i--)
        {       
                date>>=1;
                DQ=1;
                _nop_();_nop_();
                DQ=0;
                _nop_();_nop_();_nop_();_nop_();_nop_();_nop_();
                DQ=1;
                _nop_();_nop_();_nop_();_nop_();
                j=DQ;
                if(j==1)
                date|=0x80;
                delayus(1,1);                                       
        }
                return(date);
}


uint get_tem(void)
{
        uchar tem1,tem2;      
        float aaa;
        uint temper;
        reset();
        write_byte(0xCC);//跳过ROM
        write_byte(0x44);//温度转换
        reset();  //复位
        write_byte(0xCC);//跳过ROM
        write_byte(0xBE);//读暂存器
        tem1=read_byte();
        tem2=read_byte();       
        aaa=(tem2*256+tem1)*6.25;
        temper=(int)aaa;
        return(temper);
       
}



/*****读取温度*****/
void check_wendu(void)
{
        uint c,num;
        for(num=50;num>0;num--)
                display(a1,a2,a3,a4);
        c=get_tem();  //获取温度值并减去DS18B20的温漂误差
        a1=c/1000;
        a2=c%1000/100;
        a3=c%100/10;
        a4=c%10;   
       
        m=a1*10+a2;      //计算得到整数位
        if(m<0)
                {
                        m=0;
                       
                }   //设置温度显示下限
                 if(m>99)
                {
                        m=99;
                       
                }   //设置温度显示上限               

}

/*****报警子程序*****/
void Alarm()
{
        if(x>=10)
        {
                beep_st=~beep_st;
                x=0;               
        }
        if((m>=shangxian&&beep_st==1)||(m<xiaxian&&beep_st==1))
        BEEP=0;
        else BEEP=1;                                
}

void init()
{
        wela=0;
        dula=0;
//        temper=0;
        TMOD=0x01;
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        EA=1;
        ET0=1;
        TR0=1;       
}


void main()
{
        init();       
        while(1)
        {       
                keysan();                       
                if(set_st==0)
                {
                        //get_tem();
                        check_wendu();
                           Alarm();   //报警检测
               
                }
               
        }
       
}

void timer0() interrupt 1  
{
        TH0=(65536-50000)/256;
        TL0=(65536-50000)%256;
        x++;       
}

这个程序能运行,但有时会出现以下问题,本人查了很久都不能解决问题出现的原因,在这里请教各位高手,希望各位多多指教。
第一个问题:在正常显示的时候偶尔会变成六三十度几,大概一秒钟有时会更短一点时间,蜂宁器报警一下。
第二个问题:在按进入功能调整键的时候会有按几次才能进入调整功能的情况,有时会一按就进有时会要按好几次才能进,很不稳定。
第三个问题:虽然解决了但不知道什么原因在这里也想问问各位高手是因为什么原因,我的硬件是用到74HC573芯片来锁存段和位,在写进入功能调整闪烁的程序时,要多写一个数码管不显示才能正常闪烁三个数码管,写少一个就少一个闪烁,我不知道这是为什么,我是不断修改闪烁程序中发现这个问题的,只有这个办法才能解决要闪三位,这令我十分的不解,在这里特向各位高手请教,希望大家多多给意见!谢谢!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。