稻香 发表于 2012-7-8 19:19:08

STC89C51 单总线多路DS18B20温度测量及监控系统【提供源代码】

本帖最后由 稻香 于 2012-7-8 19:45 编辑

以下是源代码:
有需要资料的留言联系我。
今天不知道怎么的资料发布上去。

/*-----------------------------------------------
名称:多点温度测量显示
论坛:http://user.qzone.qq.com/891405379/infocenter
编写:daoxiang
单位:CCIT.School of electronic and information tech.
日期:2012.07.07
修改:无
内容:单点温度测量+温度上下限报警处理+设置报警温度上下限
------------------------------------------------*/
#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^7;           //DS18B20连接端
sbit WELA1=P2^0;   //共阳数码管,从左到右的第一位
sbit WELA2=P2^1;   //共阳数码管,从左到右的第二位
sbit WELA3=P2^2;   //共阳数码管,从左到右的第三位
sbit WELA4=P2^3;   //共阳数码管,从左到右的第四位
sbit beep=P2^6;           //蜂鸣器选择端
sbit led_red=P2^4; //红色LED选择端
sbit led_yellow=P2^5;//黄色LED选择端
sbit key1=P3^2;               //key1功能号设置,0:显示温度;1:显示温度上限;2:显示温度下限
sbit key2=P3^3;               //key2加减设置
uint temp;                       //全局变量,保存转换后的温度值
float f_temp;               //全局变量
uint warn_low=33;                  //温度报警下限初始值
intwarn_low_limit=24;//-1;//温度报警下限最小值为(warn_low_limit+1)
uint warn_low_reset=32;          //温度下限复位值
uint warn_high=33;                  //温度报警上限初始值
uint warn_high_limit=36;//温度报警上限最大值为(warn_high_limit-1)
uint warn_high_reset=30;//温度上限复位值
uint mode=0;
uint t0_num=0;                          //timer0计数次数初始值
uint ds_num=0;                          //温度显示初始值
uint key1num=0;                          //功能号初始值为0:直接显示温度
                                                  //功能号初始值为1:显示上限温度
                                                  //功能号初始值为2:显示下限温度
                                                  //ROM1(第1个18B20的光刻ROM)       
uchar code str_red[]={0x28,0xBA,0x6A,0xEE,0x03,0x00,0x00,0xC2};
                                                  //ROM2(第2个18B20的光刻ROM)
uchar code str_yellow[]={0x28,0x89,0x0B,0xE8,0x03,0x00,0x00,0xA3};
/*共阳数码管的码表*/
unsigned char code table[]={
0xc0,0xcf,0xA4,0xb0,0x99,//共阳极数码管:0-9不带小数点的码表
0x92,0x82,0xf8,0x80,0x90,                        //数组元素下标:0-9
0x40,0x4f,0x24,0x30,0x19,//共阳极数码管:0-9带小数点的码表
0x12,0x02,0x78,0x00,0x10,                  //数组元素下标:10-19
0xbf,                                       //负号的码表数组元素下标:20
0x89,                                        //H 的码表           数组元素下标:21
0xC7,                                       //L 的码表           数组元素下标:22
0xC6,                                       //C 的码表    数组元素下标:23          表示温度为'正'摄氏度
0x86                                       //E 的码表           数组元素下标:24          表示温度为'负'摄氏度
                                                   };
/*延时函数:延时‘z’毫秒*/
void delayms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)          
                for(y=110;y>0;y--);
}

/*DS18B20的复位,初始化函数*/
void dsreset(void)
{
        uint i;
        ds=0;
        i=103;
        while(i>0)i--;
        ds=1;
        i=4;
        while(i>0)i--;
}

/*读1位数据函数*/
bit tempreadbit(void)
{
        uint i;
        bit dat;
        ds=0;i++;               
        ds=1;i++;i++;
        dat=ds;
        i=8;while(i>0)i--;
        return(dat);
}

/*读一个字节数据函数*/
uchar tempread(void)
{
        uchar i,j,dat;
        dat=0;
        for(i=1;i<=8;i++)
        {
                j=tempreadbit();
                dat=(j<<7)|(dat>>1);
        }
        return(dat);
}

/*向DS18B20写一个字节数据*/
void tempwritebyte(uchar dat)
{
        uint i;
        uchar j;
        bit testb;
        for(j=1;j<=8;j++)
        {
                testb=dat&0x01;
                dat=dat>>1;
                if(testb)//写1
                {
                        ds=0;
                        i++;i++;
                        ds=1;
                        i=8;while(i>0)i--;
                }
                else
                {
                        ds=0;//写0
                        i=8;while(i>0)i--;
                        ds=1;
                        i++;i++;
                }
        }
}

void match_rom(uchar a)                //18B20匹配ROM
{
        char i;
        //
//        Display();                      //数码管显示
        //
        tempwritebyte(0x55);                //发送匹配ROM命令
        if(a==0)                        //匹配ROM1
        {
                for(i=0;i<8;i++)
                tempwritebyte(str_red);//发送18B20的序列号,先发送低字节
        }
        if(a==1)                        //匹配ROM2
        {
                for(i=0;i<8;i++)
                tempwritebyte(str_yellow);//发送18B20的序列号,先发送低字节
        }
}

/*DS18B20开始获取温度并且转换*/
void tempchange(uint ds_num_trans)
{
        dsreset();
//        switch(ds_num)
        {
//                case 0:
                delayms(1);
//                tempwritebyte(0xcc); //写跳过读ROM指令
                match_rom(ds_num_trans);
                tempwritebyte(0x44); //写温度转换指令
        }
}

/*读寄存器中存储的温度数据*/
uint get_temp()
{
        uchar a,b,i;
        dsreset();
        delayms(1);
        i=ds_num;
//        tempwritebyte(0xcc);//写跳过读ROM指令
        match_rom(i);//ds_num);          //匹配ROM
        tempwritebyte(0xbe);//0XBEH:读暂存器,读内部RAM中9字节的内容
        a=tempread();
        b=tempread();                  //读低8位
        temp=b;                                  //读高8位
        temp<<=8;                          //两个字节组合为1个字
        temp=temp|a;                  
        f_temp=temp*0.0625;          //温度在寄存器中为12位,分辨率为0.0625度
        temp=f_temp*10+0.5;          //
        f_temp=f_temp+0.05;          //乘以10 表示小数点后面只取1位,加0.5是四舍五入
        return temp;                  //temp是整型
}

/*数据显示程序*/
void display(uchar num,uchar dat)
{       
           P2=(P2&(0xF0));//关闭显示等价于(WELA1=0;WELA2=0;WELA3=0;WELA4=0;)//关闭显示 P2=(P2&(0xF0))
          switch(num)                         //读取显示位
                {
                        case 1:        WELA1=1;break;//分别为数码管从左到右的1-4位
                        case 2:        WELA2=1;break;
                        case 3:        WELA3=1;break;
                        case 4:        WELA4=1;break;
                        default: break;       
                };
                P1=table;delayms(3);P2=(P2&(0xF0));
}

/*显示函数 t 传递的是整形温度值*/
void dis_temp(uint s,uint t)        //温度处理并且调用显示
{
        uchar i;
        uint dis;
        dis=s;
        switch(dis)
        {        case 0:        //显示温度值
                        {
                        i=t/100;               
                        display(1,i);                //数码管由左到右第一位:显示温度的十位       
                        i=t%100/10;       
                        display(2,i+10);         //数码管由左到右第二位:显示温度的个位
                        i=t%100%10;       
                        display(3,i);                //数码管由左到右第三位:显示温度的小数位
                        display(4,23);                //数码管由左到右第四位:显示显示单位'C'       
                        };break;
                case 1:        //显示高温上限
                        {
                        display(1,21);                //数码管由左到右第一位:显示‘H’
                        i=t/100;
                        display(2,i);               //数码管由左到右第二位:显示温度上限的十位
                        i=t%100/10;
                        display(3,i+10);        //数码管由左到右第三位:显示温度上限的个位
                        display(4,23);                //数码管由左到右第四位:显示显示温度单位‘C’
                        };break;
                case 2:        //显示低温下限
                        {
                        display(1,22);        //数码管由左到右第一位:显示'L'
                        i=t/100;               
                        display(2,i);        //数码管由左到右第二位:显示低温下限的十位       
                        i=t%100/10;       
                        display(3,i+10);//数码管由左到右第三位:显示低温下限的个位   
                        display(4,23);        //数码管由左到右第四位:显示‘.C’单位
                        };break;
        }
}       
/*蜂鸣器报警+LED闪烁*/
void warn(uint s,uint led_num)
{
        uchar i;
        uint led_num1;
        beep=0;
        led_num1=led_num;
        if(led_num1==0)
        {
        led_yellow=1;
        led_red=0;       
        }
        else if(led_num1==1)
        {
        led_red=1;
        led_yellow=0;       
        }
        i=s;
        while(i--)
                dis_temp(key1num,get_temp());
        beep=1;
        if(led_num==0)
        led_red=1;
        else if(led_num==1)
        led_yellow=1;
        i=s;
          while(i--)
                  dis_temp(key1num,get_temp());
}

/*温度报警处理函数*/
void deal(uint t,uint warn_high,uint warn_low)
{
        uchar i=40;
        if((t<((warn_low)*10)))
                        warn(8,ds_num);
        else if(t>((warn_high)*10))
                        warn(16,ds_num);
        else if(t>((warn_low)*10)&&(t<(warn_high)*10))
                        while(i--)
                        dis_temp(key1num,get_temp());
                       
}

void inter_init()
{
        TMOD|=0x01;   //使用模式1,16位定时器
        ET0=1;          //开T0中断
//        TR0=0;
        EA=1;                        //开总中断
        EX0=1;          //开外部中断0
        EX1=1;          //开外部中断1
        IT0=0;          //IT0=0电平触发,IT=1边沿触发
//        TR0=1;
}

/*主函数*/
void main()
{
        inter_init();        //中断初始化
        while(1)
        {
                if(key1num==0)
                {
                        if(ds_num==0)
                        {
                                led_yellow=1;
                                led_red=0;//红色的LED点亮
                                tempchange(ds_num);//匹配第一个ROM 读取第一个DS18B20的温度
//                                dis_temp(key1num,get_temp());//显示温度
                                deal(get_temp(),warn_high,warn_low);
                        }
                        else if(ds_num==1)
                        {
                                tempchange(ds_num);//匹配第二个ROM
                                led_yellow=0;//        黄色的LED点亮
                                led_red=1;
//                                dis_temp(key1num,get_temp());//读取第二个DS18B20的温度
                                deal(get_temp(),warn_high,warn_low);//显示温度
                        }
                }
                else if(key1num==1)
                        dis_temp(key1num,((warn_high)*10));        //显示温度上限值
                else if(key1num==2)
                        dis_temp(key1num,((warn_low)*10));        //显示温度下限值
        }
}
/*外部中断0:主按键P3^2:主按键功能号设置函数*/
void key1_num() interrupt 0          //外部中断0
{
        if(key1==0)                                  //判断按键       
        {
                delayms(10);
                if(key1==0)
                {
                        key1num++;                  //功能号加1
                        if(key1num==3)          //功能号复位
                        key1num=0;                  //
                        while(!key1);          //等待按键释放
                }
        }
}

/*外部中断2:副按键P3^3:高温低温报警设置功能函数*/
void key2_func() interrupt 2       //外部中断1
{
        switch(key1num)                               //导入判断功能号
        {
                case 0:{                                               //功能号0:显示温度
                                if(key2==0)
                                {
                                        delayms(10);
                                        if(ds_num==0)
                                        TR0=0;
                                        if(key2==0)
                                        {
                                                ds_num++;
                                                if(ds_num==1)
                                                {
                                                TR0=0;
                                                while(!key2);
                                                }
                                        else if(ds_num==2)
                                        {
                                        ds_num=0;
                                        while(!key2);
                                        TR0=1;
                                        }
                                        }
                                }
                       
                        };break;
                case 1:{                                       //功能为1:设置温度上限值
                                if(key2==0)                       //按键处理
                                {
                                        delayms(10);
                                        if(key2==0)               //
                                        {
                                                warn_high++; //温度上限值加1
                                                if(warn_high==warn_high_limit)//报警上限值到warn_high_limit时复位 为warn_high_reset
                                                        warn_high=warn_high_reset;          //
                                                while(!key2); //等待按键释放
                                        }
                                }
                     };break;
                case 2:                                  //功能号为2:设置温度下限值
                {
                        if(key2==0)
                        {
                                delayms(10);
                                if(key2==0)
                                {
                                        warn_low--;        //温度下限值减1,
                                        if(warn_low==warn_low_limit)//报警上限值到warn_low_limit时复位为 warn_low_reset
                                                warn_low=warn_low_reset; //
                                                while(!key2);//等待按键释放
                                };                               
                        }
                };break;
                default:break;
        }
}

/*定时器0中断处理函数*/
void Timer0_deal() interrupt 1
{
        TH0=0x70;//定时40毫秒                        //(65536-2000)/256;//重新赋值 2ms
        TL0=0x00;//                                                //(65536-2000)%256;
        t0_num++;
        if(t0_num==50)//2000)                  //4000ms 定时4秒之后
        {
                t0_num=0;
                ds_num++;
                if(ds_num==2)
                ds_num=0;
        }
}

稻香 发表于 2012-7-8 19:23:06

1:能够监测亮点温度[可以扩展为多路]
2:可以设置温度报警上限 下限值
3:可单点显示
4:可以循环显示

稻香 发表于 2012-7-8 19:33:20

多点温度监测系统的原理图

hzdiy 发表于 2012-7-9 16:35:43

谢谢楼主分享!

wtiechen1969 发表于 2012-7-10 10:17:29

不错,学习了

linguicheng 发表于 2012-7-18 23:08:41

原理图什么的怎么没有上传?

jetli 发表于 2012-7-19 08:56:08

希望这个⊙▂⊙

“多点温度监测系统”

而且是搜索算法的多点,单点的论坛大把大把{:titter:}

aidianzio 发表于 2012-7-19 11:27:10

原理图呢?
谢谢分享

aidianzio 发表于 2012-7-19 11:29:01

稻香 发表于 2012-7-8 19:33 static/image/common/back.gif
多点温度监测系统的原理图

能把原理图分享一下吗?谢谢

fangzhiping 发表于 2012-7-19 19:39:39

表示谢谢楼主的分享

sdf159372008 发表于 2012-7-19 20:09:49

单线多点测温的反应略微慢了点,其他倒是很不错~

稻香 发表于 2012-7-20 19:33:35

aidianzio 发表于 2012-7-19 11:29 static/image/common/back.gif
能把原理图分享一下吗?谢谢

你给我邮箱发信息吧 tangang723@qq.com。这个上面发图麻烦。我邮箱发给你

稻香 发表于 2012-7-20 19:49:18

稻香 发表于 2012-7-20 19:33 static/image/common/back.gif
你给我邮箱发信息吧 。这个上面发图麻烦。我邮箱发给你

原理图文件

稻香 发表于 2012-7-20 19:49:47

aidianzio 发表于 2012-7-19 11:29 static/image/common/back.gif
能把原理图分享一下吗?谢谢

我发到13楼了。

jetli 发表于 2012-7-21 09:22:57

稻香 发表于 2012-7-20 19:49 static/image/common/back.gif
我发到13楼了。



没看到
多点测温
源程序啊?

tonyone 发表于 2012-7-21 14:54:06

没玩过多个的,记号

稻香 发表于 2012-7-28 14:51:48

jetli 发表于 2012-7-21 09:22 static/image/common/back.gif
没看到
多点测温
源程序啊?

/*-----------------------------------------------
名称:多点温度测量显示
论坛:http://user.qzone.qq.com/891405379/infocenter
编写:daoxiang
单位:CCIT.School of electronic and information tech.
日期:2012.07.07
修改:无
内容:单点温度测量+温度上下限报警处理+设置报警温度上下限
------------------------------------------------*/
#include<reg52.h>
#include<stdio.h>
#define uchar unsigned char
#define uint unsigned int
sbit ds=P2^7;           //DS18B20连接端
sbit WELA1=P2^0;   //共阳数码管,从左到右的第一位
sbit WELA2=P2^1;   //共阳数码管,从左到右的第二位
sbit WELA3=P2^2;   //共阳数码管,从左到右的第三位
sbit WELA4=P2^3;   //共阳数码管,从左到右的第四位
sbit beep=P2^6;           //蜂鸣器选择端
sbit led_red=P2^4; //红色LED选择端
sbit led_yellow=P2^5;//黄色LED选择端
sbit key1=P3^2;               //key1功能号设置,0:显示温度;1:显示温度上限;2:显示温度下限
sbit key2=P3^3;               //key2加减设置
uint temp;                       //全局变量,保存转换后的温度值
float f_temp;               //全局变量
uint warn_low=33;                  //温度报警下限初始值
intwarn_low_limit=24;//-1;//温度报警下限最小值为(warn_low_limit+1)
uint warn_low_reset=32;          //温度下限复位值
uint warn_high=33;                  //温度报警上限初始值
uint warn_high_limit=36;//温度报警上限最大值为(warn_high_limit-1)
uint warn_high_reset=30;//温度上限复位值
uint mode=0;
uint t0_num=0;                          //timer0计数次数初始值
uint ds_num=1;                          //温度显示初始值
uint key1num=0;                          //功能号初始值为0:直接显示温度
                                                  //功能号初始值为1:显示上限温度
                                                  //功能号初始值为2:显示下限温度
                                                  //ROM1(第1个18B20的光刻ROM)
uint key2_num=3;                  //表示循环显示温度。       
uchar code str_red[]={0x28,0xBA,0x6A,0xEE,0x03,0x00,0x00,0xC2};
                                                  //ROM2(第2个18B20的光刻ROM)
uchar code str_yellow[]={0x28,0x89,0x0B,0xE8,0x03,0x00,0x00,0xA3};
/*共阳数码管的码表*/
unsigned char code table[]={
0xc0,0xcf,0xA4,0xb0,0x99,//共阳极数码管:0-9不带小数点的码表
0x92,0x82,0xf8,0x80,0x90,                        //数组元素下标:0-9
0x40,0x4f,0x24,0x30,0x19,//共阳极数码管:0-9带小数点的码表
0x12,0x02,0x78,0x00,0x10,                  //数组元素下标:10-19
0xbf,                                       //负号的码表数组元素下标:20
0x89,                                        //H 的码表           数组元素下标:21
0xC7,                                       //L 的码表           数组元素下标:22
0xC6,                                       //C 的码表    数组元素下标:23          表示温度为'正'摄氏度
0x86,                                       //E 的码表           数组元素下标:24          表示温度为'负'摄氏度
0x22,                                       //第0点上限符号的码表 数组元素下标25
0x14,                                       //第0点下限符号的码表 数组元素下标26       
0x7A,                                       //第1点上限符号的码表 数组元素下标27
0x75,                                       //第1点下限符号的码表 数组元素下标28
                                                   };
/*延时函数:延时‘z’毫秒*/
void delayms(uint z)
{
        uint x,y;
        for(x=z;x>0;x--)          
                for(y=110;y>0;y--);
}

/*DS18B20的复位,初始化函数*/
void dsreset(void)
{
        uint i;
        ds=0;
        i=103;
        while(i>0)i--;
        ds=1;
        i=4;
        while(i>0)i--;
}

/*读1位数据函数*/
bit tempreadbit(void)
{
        uint i;
        bit dat;
        ds=0;i++;               
        ds=1;i++;i++;
        dat=ds;
        i=8;while(i>0)i--;
        return(dat);
}

/*读一个字节数据函数*/
uchar tempread(void)
{
        uchar i,j,dat;
        dat=0;
        for(i=1;i<=8;i++)
        {
                j=tempreadbit();
                dat=(j<<7)|(dat>>1);
        }
        return(dat);
}

/*向DS18B20写一个字节数据*/
void tempwritebyte(uchar dat)
{
        uint i;
        uchar j;
        bit testb;
        for(j=1;j<=8;j++)
        {
                testb=dat&0x01;
                dat=dat>>1;
                if(testb)//写1
                {
                        ds=0;
                        i++;i++;
                        ds=1;
                        i=8;while(i>0)i--;
                }
                else
                {
                        ds=0;//写0
                        i=8;while(i>0)i--;
                        ds=1;
                        i++;i++;
                }
        }
}

void match_rom(uchar a)                //18B20匹配ROM
{
        char i;
        //
//        Display();                      //数码管显示
        //
        tempwritebyte(0x55);                //发送匹配ROM命令
        if(a==1)                        //匹配ROM1
        {
                for(i=0;i<8;i++)
                tempwritebyte(str_red);//发送18B20的序列号,先发送低字节
        }
        if(a==2)                        //匹配ROM2
        {
                for(i=0;i<8;i++)
                tempwritebyte(str_yellow);//发送18B20的序列号,先发送低字节
        }
}

/*DS18B20开始获取温度并且转换*/
void tempchange(uint ds_num_trans)
{
        dsreset();
//        switch(ds_num)
        {
//                case 0:
                delayms(1);
//                tempwritebyte(0xcc); //写跳过读ROM指令
                match_rom(ds_num_trans);
                tempwritebyte(0x44); //写温度转换指令
//                delayms(1);
        }
}

/*读寄存器中存储的温度数据*/
uint get_temp()
{
        uchar a,b,i;
        dsreset();
        delayms(1);
        i=ds_num;
//        tempwritebyte(0xcc);//写跳过读ROM指令
        match_rom(i);//ds_num);          //匹配ROM
        delayms(2);
        tempwritebyte(0xbe);//0XBEH:读暂存器,读内部RAM中9字节的内容
        delayms(1);
        a=tempread();
        b=tempread();                  //读低8位
        temp=b;                                  //读高8位
        temp<<=8;                          //两个字节组合为1个字
        temp=temp|a;                  
        f_temp=temp*0.0625;          //温度在寄存器中为12位,分辨率为0.0625度
        temp=f_temp*10+0.5;          //
        f_temp=f_temp+0.05;          //乘以10 表示小数点后面只取1位,加0.5是四舍五入
        return temp;                  //temp是整型
}

/*数据显示程序*/
void display(uchar num,uchar dat)
{       
           P2=(P2&(0xF0));//关闭显示等价于(WELA1=0;WELA2=0;WELA3=0;WELA4=0;)//关闭显示 P2=(P2&(0xF0))
          switch(num)                         //读取显示位
                {
                        case 1:        WELA1=1;break;//分别为数码管从左到右的1-4位
                        case 2:        WELA2=1;break;
                        case 3:        WELA3=1;break;
                        case 4:        WELA4=1;break;
                        default: break;       
                };
                P1=table;delayms(3);P2=(P2&(0xF0));
}

/*显示函数 t 传递的是整形温度值*/
void dis_temp(uint s,uint t)        //温度处理并且调用显示
{
        uchar i;
        uint dis;
        dis=s;
        switch(dis)
        {        case 0:        //显示温度值
                        {
                        i=t/100;               
                        display(1,i);                //数码管由左到右第一位:显示温度的十位       
                        i=t%100/10;       
                        display(2,i+10);         //数码管由左到右第二位:显示温度的个位
                        i=t%100%10;       
                        display(3,i);                //数码管由左到右第三位:显示温度的小数位
                        display(4,23);                //数码管由左到右第四位:显示显示单位'C'       
                        };break;
                case 1:        //显示高温上限
                        {
                        display(1,21);                //数码管由左到右第一位:显示‘H’
                        i=t/100;
                        display(2,i);               //数码管由左到右第二位:显示温度上限的十位
                        i=t%100/10;
                        display(3,i+10);        //数码管由左到右第三位:显示温度上限的个位
                        display(4,23);                //数码管由左到右第四位:显示显示温度单位‘C’
                        };break;
                case 2:        //显示低温下限
                        {
                        display(1,22);        //数码管由左到右第一位:显示'L'
                        i=t/100;               
                        display(2,i);        //数码管由左到右第二位:显示低温下限的十位       
                        i=t%100/10;       
                        display(3,i+10);//数码管由左到右第三位:显示低温下限的个位   
                        display(4,23);        //数码管由左到右第四位:显示‘.C’单位
                        };break;
        }
}       
/*蜂鸣器报警+LED闪烁*/
void warn(uint s,uint led_num)
{
        uchar i;
        uint led_num1;
        beep=0;
        led_num1=led_num;
        if(led_num1==1)
        {
                led_yellow=1;
                led_red=0;       
        }
        else if(led_num1==2)
        {
                led_red=1;
                led_yellow=0;       
        }
        i=s;
        while(i--)
                dis_temp(key1num,get_temp());
                beep=1;
        if(led_num==2)
                led_red=1;
        else if(led_num==2)
                led_yellow=1;
                i=s;
          while(i--)
                  dis_temp(key1num,get_temp());
}

/*温度报警处理函数*/
void deal(uint t,uint warn_high,uint warn_low)
{
        uchar i=40;
        if((t<((warn_low)*10)))
                        warn(8,ds_num);
        else if(t>((warn_high)*10))
                        warn(16,ds_num);
        else if(t>((warn_low)*10)&&(t<(warn_high)*10))
                        while(i--)
                        dis_temp(key1num,get_temp());
                       
}

void inter_init()
{
        TMOD|=0x01;   //使用模式1,16位定时器
        ET0=1;          //开T0中断
//        TR0=0;
        EA=1;                        //开总中断
        EX0=1;          //开外部中断0
        EX1=1;          //开外部中断1
        IT0=0;          //IT0=0电平触发,IT=1边沿触发
        TR0=1;
}

/*主函数*/
void main()
{
        inter_init();        //中断初始化
        while(1)
        {
                if(key1num==0)
                {
                        if(ds_num==1)
                        {
                                led_yellow=1;
                                led_red=0;//红色的LED点亮
                                tempchange(ds_num);//匹配第一个ROM 读取第一个DS18B20的温度
//                                dis_temp(key1num,get_temp());//显示温度
                                deal(get_temp(),warn_high,warn_low);
                        }
                        else if(ds_num==2)
                        {
                                tempchange(ds_num);//匹配第二个ROM
                                led_yellow=0;//        黄色的LED点亮
                                led_red=1;
//                                dis_temp(key1num,get_temp());//读取第二个DS18B20的温度
                                deal(get_temp(),warn_high,warn_low);//显示温度
                        }
                }
                else if(key1num==1)
                        dis_temp(key1num,((warn_high)*10));        //显示温度上限值
                else if(key1num==2)
                        dis_temp(key1num,((warn_low)*10));        //显示温度下限值
        }
}
/*外部中断0:主按键P3^2:主按键功能号设置函数*/
void key1_num() interrupt 0          //外部中断0
{
        if(key1==0)                                  //判断按键       
        {
                delayms(10);
                if(key1==0)
                {
                        key1num++;                  //功能号加1
                        if(key1num==3)          //功能号复位
                        key1num=0;                  //
                        while(!key1);          //等待按键释放
                }
        }
}

/*外部中断2:副按键P3^3:高温低温报警设置功能函数*/
void key2_func() interrupt 2       //外部中断1
{
        switch(key1num)                               //导入判断功能号
        {
                case 0:{                                               //功能号0:显示温度
                                if(key2==0)
                                {
                                        delayms(10);
                                        if(key2==0)
                                        {
                                                ds_num++;
                                                if(ds_num==3)
                                                {
                                                        if(key2_num==0)
                                                        {
                                                        ds_num=1;
                                                        TR0=~(TR0);
                                                        }
                                                }
                                        while(!key2);
                                        }
                                }
                       
                        };break;
                case 1:{                                       //功能为1:设置温度上限值
                                if(key2==0)                       //按键处理
                                {
                                        delayms(10);
                                        if(key2==0)               //
                                        {
                                                warn_high++; //温度上限值加1
                                                if(warn_high==warn_high_limit)//报警上限值到warn_high_limit时复位 为warn_high_reset
                                                        warn_high=warn_high_reset;          //
                                                while(!key2); //等待按键释放
                                        }
                                }
                     };break;
                case 2:                                  //功能号为2:设置温度下限值
                {
                        if(key2==0)
                        {
                                delayms(10);
                                if(key2==0)
                                {
                                        warn_low--;        //温度下限值减1,
                                        if(warn_low==warn_low_limit)//报警上限值到warn_low_limit时复位为 warn_low_reset
                                                warn_low=warn_low_reset; //
                                                while(!key2);//等待按键释放
                                };                               
                        }
                };break;
                default:break;
        }
}

/*定时器0中断处理函数*/
void Timer0_deal() interrupt 1
{
        TH0=0x70;//定时40毫秒                        //(65536-2000)/256;//重新赋值 2ms
        TL0=0x00;//                                                //(65536-2000)%256;
        t0_num++;
        if(t0_num==25)//151)//2000)                  //4000ms 定时6秒之后
        {
                t0_num=0;
                ds_num++;
                if(ds_num==3)
                ds_num=1;
        }
}

lijinen 发表于 2012-7-30 10:16:56

非常好的资料,谢谢楼主!

sdlibin007 发表于 2012-9-30 17:47:10

很有参考价值~~~~~~~~~~~~~~~~~

ufowanli 发表于 2012-10-6 19:09:42

怎么没使用mos管呢。

sunbingbing 发表于 2012-10-10 07:25:36

{:smile:赞一个,学习中

xts 发表于 2012-10-10 08:43:40

楼主是个帅哥,回头买了温度传感器模块,来试试,先记号下!

wyshrs 发表于 2012-10-10 09:39:14

谢谢楼主分享,学习之

boshi1987 发表于 2013-1-8 15:23:18

不错不错 谢谢分享
页: [1]
查看完整版本: STC89C51 单总线多路DS18B20温度测量及监控系统【提供源代码】