求助!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芯片来锁存段和位,在写进入功能调整闪烁的程序时,要多写一个数码管不显示才能正常闪烁三个数码管,写少一个就少一个闪烁,我不知道这是为什么,我是不断修改闪烁程序中发现这个问题的,只有这个办法才能解决要闪三位,这令我十分的不解,在这里特向各位高手请教,希望大家多多给意见!谢谢!!
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
9条回答
07636678
2020-01-27 19:07
回复【1楼】lininglive
第一个问题:在正常显示的时候偶尔会变成六三十度几,大概一秒钟有时会更短一点时间,蜂宁器报警一下。
这个问题估计是程序里时序有问题 所以在一段时间后,由于延时错误 造成采集时间争取 ,我看你的采集温度程序好像没有禁止中断,建议加上禁止中断,还有你keyscan 函数里也加上禁止中断试试看,
显示程序中的dula 和 wela 没看明白是怎么会事,但是
dula=1;  
p0=table[baojing/10];  
dula=0;  
p0=0x00;  
p0口 送完数据 马上送0的话 间隔时间太少短了 就看不到闪烁效果了
-----------------------------------------------------------------------

你这里指我第三个问题里的闪烁问题吗?如果是像你说的那样时间太短闪烁效果就看不出,我也尝试过加延时,但还是没有闪动,试过很多办法,只有多写一个没用的显示位才能正常闪烁三个数码管,我真搞不懂是为什么??

一周热门 更多>