数字温度计设计报告

单片机原理与应用技术

课程设计报告(论文)

基于单片机控制的数字温度计

专业班级:       应教121     

姓  名:        董镇玉     

时    间:      2014.1.9      

指导教师 :    宋长源 李晓娟   

20##年   01 月 0 9  日

单片机课程设计项目系列:

基于单片机控制的数字温度计

一.     设计要求

(一)基本功能

1.      测温范围-50℃—110℃

2.     精度误差不大于0.1℃

3.     LED数码直读显示   

(二)扩展功能

1实现语音报数

2可以任意设定温度的上下限报警功能

二.计划完成时间   三周

1第一周完成软件和硬件的整体设计,同时按要求上交设计报告一份。

2第二周完成软件的具体设计和硬件的制作。

3第三周完成软件和硬件的联合调试。

基于单片机控制的数字温度计

应教121 董镇玉

摘要:数字温度计在我们的日常生活中非常常见,广泛应用于我们的日常生活和工业生产。随着科技的发展,电子技术也日新月异,18b20芯片就是其中杰作之一。本设计是基于单片机控制的数字温度计,用18b20温度传感器来检测温度,用AT89s52单片机来控制,最终通过数码管来显示温度。

关键词:18b20    数码管  单总线

1引言

随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字温度计就是一个典型的例子,但人们对它的要求越来越高,要为现代人工作、科研、生活、提供更好的更方便的设施就需要从数单片机技术入手,一切向着数字化控制,智能化控制方向发展。本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温准确,其输出温度采用数字显示,主要用于对测温比较准确的场所,或科研实验室使用,该设计控制器使用单片机AT89S51,测温传感器使用DS18B20,用4位一体共阳极LED数码管以串口传送数据,实现温度显示,能准确达到以上要求。

2 总体设计方案

2.1 设计思路

    按照设计要求,要用LED数码管直读显示温度。可以通过单片机的IO口然后通过编码来实现。至于获取温度可以有两种办法,传统的用热敏电阻通过A/D转换,还可以用最新的温度传感器芯片来实现。

2.1.1方案一

由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化的电压或电流采集过来,进行A/D转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到A/D转换电路,感温电路比较麻烦,误差也较大。

2.1.2 方案二

进而考虑到用温度传感器,在单片机电路设计中,大多都是使用传感器,所以这是非常容易想到的,所以可以采用一只温度传感器DS18B20,此传感器,可以很容易直接读取被测温度值,进行转换,而且精度较高,就可以满足设计要求。

从以上两种方案,很容易看出,采用方案二,电路比较简单,软件设计也比较简单,精度也较高,故采用了方案二。

2.2方案二的总体设计框图

温度计电路设计总体设计方框图如图1所示,控制器采用单片机AT89S51,温度传感器采用DS18B20,用3位LED数码管以串口传送数据实现温度显示。

 

图1 总体设计方框图

3设计原理分析

3.1温度传感器

3.1.1 温度传感器介绍

DS18B20温度传感器是DALLAS公司推出的数字化温度传感器,采用单总线协议,与处理器接口仅需一个IO端口,无需任何外部元件,直接将环境温度转化为数字信号,以数字码方式串行输出,比较方便。

实物如图2所示:

DS18B20温度传感器特性

1、适应电压范围宽,电压范围在3.0~5.5,可由数据线供电;  

2、独特的单线接口方式,可节约处理器的IO口资源;

图2  18B20实物图

3、使用中不需要外围元件,全部传感元件和转换电路集成在一个形如三极管的集成电路里,非常方便;

4、测温范围:-55°C~+125°C;

5、可编程分辨率为9~12位,对应的精度为0.5°C、0.25°C、0.125°C和

   0.0625°C,精度比较高;

6、负压特性,电源极性接反时,芯片不会因发热而烧坏,但无法正常工作。

应用范围

1、冷冻库、粮仓、电信电力机房

2、缸体、空调等设备等等

64位ROM的结构开始8位是产品类型的编号,接着是每个器件的惟一的序号,共有48位,最后8位是前面56位的CRC检验码,这也是多个DS18B20可以采用一线进行通信的原因。温度报警触发器TH和TL,可通过软件写入户报警上下限。

DS18B20温度传感器的内部存储器还包括一个高速暂存RAM和一个非易失性的可电擦除的EERAM。高速暂存RAM的结构为8字节的存储器,结构如图3所示。头2个字节包含测得的温度信息,第3和第4字节TH和TL的拷贝,是易失的,每次上电复位时被刷新。第5个字节,为配置寄存器,它的内容用于确定温度值的数字转换分辨率。DS18B20工作时寄存器中的分辨率转换为相应精度的温度数值。该字节各位的定义如图2所示。低5位一直为1,TM是工作模式位,用于设置DS18B20在工作模式还是在测试模式,DS18B20出厂时该位被设置为0,用户要去改动,R1和R0决定温度转换的精度位数,来设置分辨率。



图3 DS18B20字节定义

高速暂存RAM的第6、7、8字节保留未用,表现为全逻辑1。第9字节读出前面所有8字节的CRC码,可用来检验数据,从而保证通信数据的正确性。

当DS18B20接收到温度转换命令后,开始启动转换。转换完成后的温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的第1、2字节。单片机可以通过单线接口读出该数据,读数据时低位在先,高位在后,数据格式以0.0625℃/LSB形式表示。

当符号位S=0时,表示测得的温度值为正值,可以直接将二进制位转换为十进制;当符号位S=1时,表示测得的温度值为负值,要先将补码变成原码,再计算十进制数值。

3.1.2 工作原理

涉及DS18B20内部的指令

  CCH—跳过ROM。直接向18B20发温度交换命令,适用于一个从机工作。

    44H—温度转换。启动ds18b20进行温度转换。

    BEH—读暂存器。读内部RAM中的温度数据。

3.1.3 工作时序

初始化

1、先将数据线置高电平1

2、延时

3、数据线拉低

4、延时750us(范围是480~960us)

5、数据线拉高

6、延时等待(15~60us),如果初始化成功,则在15~60us后DS18B20产生一 个低电平0,此时初始化成功。

DS18B20写数据

1、数据线先置低

2、延时为15us

3、采集期间延时45us,此时按照从低位到高位的顺序发送数据

4、然后将数据线拉高

5、重复上述几步,直到发送完整个字节

6、最后将数据线拉高

从DS18B20读数据

1、首先将数据线拉低

2、延时15us

3、采集期间延时45us

4、上述过程重复,直到读取完一个字节

5、最后将数据线拉高

3.2 DS18B20温度传感器与单片机的接口电路

DS18B20可以采用电源供电方式,此时DS18B20的1脚接地,2脚作为信号线,3脚接电源.如图4所示单片机端口接单线总线,。

当DS18B20处于写存储器操作和温度A/D转换操作时,总线上必须有强的上拉,上拉开启时间最大为10us。由于单线制只有一根线,因此发送接口必须是三态的。这里我用18B20的数据端接单片机的P3^2口,因为89s52单片机的P3口有内部上拉,所以这里我没有再加上拉电阻。

图4度传感器与单片机的接口电路

3.3 显示电路

    显示电路使用的一个四位一体的共阳极数码管,采用动态扫描。这种显示最大的优点就是使用口资源比较少。因为是共阳的数码管,这里段选端我用单片机的P0口连接,位选端用P1口。这样可以节省掉P0口上拉电阻,P1口处于电路更稳定的考虑,我用了上拉电阻。连接方式如图5所示。

             

图5单片机与数码管连接方式

3.4设置温度上下限和报警电路

  设置温度上下限我过四个独立按键来实现,报警电路通过三个发光二极管和蜂鸣器来实现。具体连接方式如图6所示。当温度正常不超过上下限时,绿色发光二级管亮。当超过上限温度时,红色发光二极管亮,并且蜂鸣器报警。当温度低于下限时,黄色发光二极管亮,并且蜂鸣器报警。用一个PNP型三极管来驱动蜂鸣器。三极管基极接单片机的P3^7口,平时输出高电平,当超过上下限时输出低电平,三极管导通,驱动蜂鸣器工作。四个按键可以用来调整温度的上下限,切换上下限调整和正常显示。

图6报警电路

3.5系统软件算法分析

系统程序主要包括主程序,读出温度子程序,温度转换命令子程序,计算温度子程序,显示数据刷新子程序等,显示子程序,设置高低温子程序,报警子程序,显示程序。

3.5.1主程序

主程序的主要功能是负责调用各个子函数可以分块一次执行,保证电路正常工作。主程序里面先给单片机各个端口赋初值,然后执行芯片初始化程序,再读取温度并计算,最后送给数码管显示并和上下限温度比较来决定是否报警。显示函数里面最后加入一个延时函数,每一秒钟更新一次温度,以确保显示的是最新的温度。主程序流程图如图7所示。

3.5.2 读出温度子程序

读出温度子程序的主要功能是读出RAM中的9字节,在读出时需进行CRC校验,校验有错时不进行温度数据的改写。其程序流程图如图8示

3.5.3温度转换命令子程序

温度转换命令子程序主要是发温度转换开始命令,当采用12位分辨率时转换时间约为750ms,在本程序设计中采用1s显示程序延时法等待转换的完成。温度转换命令子程序流程图如上图,图9所示

 

                                              

                                              

      图7主程序流程图                                                                    图8读温度流程图

                               

图9 温度转换流程图

3.5.4 计算温度子程序

计算温度子程序将RAM中读取值进行BCD码的转换运算,并进行温度值正负的判定,其程序流程图如图10所示。

 

                                                

图10 计算温度流程图

3.5.5报警电路子程序

流程图: 可选过程: 得到温度通过18b20得到温度以后,因为需要保留一位小数,所以返回的温度值是其实际值得十倍。所以需要先除以十,得到的数再和设置的高低温度比较,相应的输出不同的电平。程序流程图如图11所示

 

流程图: 决策: 是否超过上下限                                                           

 

                                                                        

 

图11报警电路流程图

4结束语

    经过将近三周的单片机课程设计,终于完成了我的数字温度计的设计,虽然没有完全达到设计要求,但是还是很高兴的。

在本次设计的过程中,我遇到了很多问题。板子刚做好的时候,通上电后什么都不显示,自己也很着急,弄了半天效果依旧。后来通过请教别的同学和测试,发现原来最小系统就没接好,又接好后只有两个数码管会工作。通过检修,原来是数码管装反了。经过这次实习,我发现了自己的许多不足,对单片机根本不够了解,不熟悉。通过这次动手调试,掌握了一定的调试电路的方法。在电路设计中,任何一个微小的问题都会带来大麻烦。以后做事一定要小心认真,可以为后期节省很多时间。从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高,这就是我在这次课程设计中的最大收获

参考文献

[1] 李朝青.单片机原理及接口技术(简明修订版).杭州:北京航空航天大学出版社,1998

[2] 李广弟.单片机基础[M].北京:北京航空航天大学出版社,1994

[3] 阎石.数字电子技术基础(第三版). 北京:高等教育出版社,1989

[5] 叶挺秀.应用电子学[M].杭州:浙江大学出版社,1994

附录1原理图

附录2仿真图

                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              附录3  C源程序

#include <reg52.h>

#include <intrins.h>

#define uint unsigned int

#define uchar unsigned char

#define dula P0       //段选

#define wela P1           //位选

sbit DQ = P3^2;  sbit k1 = P2^4;     sbit k2 = P2^5;  sbit k3 = P2^6; 

sbit k4 = P2^7;  sbit led3 = P2^0;   sbit led2 = P2^1;

sbit led1 = P2^2;  sbit buzzer = P3^7;

void display(uint first,uint second,uint third,uint forth);

void delay_ms(unsigned int timer);

                       

void ShowTem();

void SetLowTem();void SetHighTem();void initalarm();void alarm();void delay_us(uchar a);void init1820();void write1820(uchar a);unsigned char read1820(void);uchar gettemp();unsigned char idata flag;uchar show[4] = {1,2,3,4};void delay_us(uchar a) {

    while(--a);

}

void init1820()

{

 DQ = 1; _nop_();

 DQ = 0;      //拉低数据线,准备Reset OneWire Bus;

 delay_us(125);  //延时510us,Reset One-Wire Bus.

 delay_us(125);

 DQ = 1;      //提升数据线;

 delay_us(15);  //延时35us;

 while(DQ)     //等待Slave 器件Ack 信号;

 { _nop_(); }

 delay_us(60);  //延时125us;

 DQ = 1;      //提升数据线,准备数据传输;

}

//******write********

void write1820(uchar a)

{

    uchar i;

 for(i=0;i<8;i++)

 {if(a & 0x01)  //低位在前;

   {DQ = 0;    //结束Recovery time;

    _nop_();_nop_();_nop_();

    DQ = 1;   } //发送数据;

  else

   DQ = 0;    //结束Rec time;

    _nop_();_nop_();_nop_(); 

    //DQ = 0;  } //发送数据;

  delay_us(30);  //等待Slave Device采样;

  DQ = 1;      //Recovery;

  _nop_();      //Recovery Time Start;

  a >>= 1;

  }

}

//*******read************

unsigned char read1820(void)

{

unsigned char i;

unsigned char tmp=0;

 DQ = 1;  _nop_();     //准备读;

 for(i=0;i<8;i++)

 {

  tmp >>= 1;    //低位先发;

  DQ = 0;      //Read init;

  _nop_();     //2ms;

  DQ = 1;      //必须写1,否则读出来的将是不预期的数据;

  delay_us(2);   //延时9us;

  _nop_();

  if(DQ)      //在12us处读取数据;

   tmp |= 0x80;

  delay_us(30);  //延时55us;

  DQ = 1;   _nop_();   //恢复One Wire Bus;

  }

 return tmp; }

//**********************************************************

uchar gettemp()

{  unsigned int tp;

float temp;

   init1820();

   write1820(0xcc);

 //  delay_ms(2);

   write1820(0x44);

 

   init1820();

   write1820(0xcc);

   write1820(0xbe);

   show[0]=read1820();

   show[1]=read1820();

   init1820();

   tp=show[1]*256+show[0];

   flag = show[1] >> 7;        //判断温度正负,正时flag = 0;负时flag = 1;

   if(flag == 0)

   {temp=tp;

   tp =temp*0.0625*10+0.5;

   }

   if(flag == 1)

   {tp=tp-1;

    tp=~tp;

    temp=tp;

   tp = temp*0.0625*10+0.5;

   }

 

   return tp;

}

extern unsigned char idata flag;       //定义外部变量,温度正负标志

uint HNum = 50,LNum = 10;        //报警温度的高低值

uint Tem;

/***************

* 函 数:显示温度函数

* 参 数:无

* 返 回: 无

****************/

void ShowTem()

{

      Tem = gettemp();                    /* 读取18b20温度*/

      if(flag == 1)                       //显示负温度

      display(Tem%10,Tem%100/10,(Tem%1000)/100,16);

      if(flag == 0)               //显示正温度

      display(Tem%10,Tem%100/10,(Tem%1000)/100,Tem/1000);

}

/***************

* 函 数:设置低温温度报警值函数

* 参 数:无

* 返 回: 无

****************/

void SetLowTem()

{  

      while(1)

      {

          display((LNum*10)%10,LNum%10,(LNum%100)/10,18);

          if(k2 == 0)

          delay_ms(50);   //按键消抖

          if(k2 == 0)

          {   while(!k2);   //等待按键释放

              LNum++;

          }

          if(k3 == 0)

             delay_ms(50);    //按键消抖

         if(k3 == 0)

         {    while(!k3);      //等待按键释放

              LNum--;

         }

          if(k4 == 0)

         delay_ms(50);    //按键消抖

         if(k4 == 0)

         {    while(!k4);     //等待按键释放

              break;

             } 

       }

}

/***************

* 函 数:设置高温温度报警值函数

* 参 数:无

* 返 回: 无

****************/

void SetHighTem()

{

 

  if(k1 == 0)           //按键消抖

      delay_ms(10);

      if(k1 == 0)

      {

     while(!k1);        //等待按键释放

      while(1)

      {

             display((HNum*10)%10,HNum%10,(HNum%100)/10,17);

          if(k1 == 0)

         delay_ms(50);    //按键消抖

         if(k1 == 0)

         {   while(!k1);   //等待按键释放           

               SetLowTem();   //设置低温报警温度

               break;

         }

          if(k2 == 0)

         delay_ms(50);    //按键消抖

         if(k2 == 0)

         {   while(!k2);   //等待按键释放

             HNum++;

         }

          if(k3 == 0)

             delay_ms(50);    //按键消抖

         if(k3 == 0)

         {    while(!k3);      //等待按键释放

              HNum--;

         }

          if(k4 == 0)

         delay_ms(50);    //按键消抖

         if(k4 == 0)

         {  while(!k4);   //等待按键释放

            break;

         }  

          }

      }  

      ShowTem();

}

/***************

* 函 数:led和蜂鸣器初始化

* 参 数:无

* 返 回: 无

****************/

void initalarm()

{

      led1 = 0;led2 = 0;led3 = 0;buzzer = 1;

}

void alarm()

{

    Tem = gettemp();

    Tem=Tem/10;

    if(Tem > HNum)

    {

        led2 = 1;led1 = 0;led3 = 0;buzzer = 0;    //蜂鸣器工作

    }

    else if(Tem < LNum)

    {

        led3 = 1;led1 = 0;led2 = 0; buzzer = 0;

    }

    else

    {

        led1 = 1;led2 = 0;led3 = 0;buzzer = 1;

    }

}

   

/********************

*函数名:display.c

*说明:数码管显示18b20温度

*********************/

uchar code table[]={       //共阳极数码管显示

0xc0,0xf9,0xa4,0xb0,

0x99,0x92,0x82,0xf8,

0x80,0x90,0x88,0x83,

0xc6,0xa1,0x86,0x8e,

0xbf,0x89,0xc7};        //16是“-” ,17是“H”,18是“L”

uchar code table1[]={      //第三个数码管有小数点,所以不一样

0x40,0x79,0x24,0x30,

0x19,0x12,0x02,0x78,

0x00,0x10,0x08,0x03,

0x46,0x21,0x06,0x0e};

void display(uint first,uint second,uint third,uint forth)      {  

        wela = 0x01;

    dula = table[first];delay_ms(5);

    dula = 0xff;        wela = 0x02;

    dula = table1[second];delay_ms(5);

    dula = 0xff;wela = 0x04;

    dula = table[third];delay_ms(5);

    dula = 0xff;wela = 0x08;

    dula = table[forth];

    delay_ms(5);dula = 0xff;       

}

void delay_ms(uint timer)

{

    uint i,j;

    for(i=0; i<timer; i++)

        for(j=0; j<110; j++);

}

void main()

{

   initalarm();

   while(1)

   {

      SetHighTem();

      alarm();

   }

}

附录4 实物图

相关推荐