数字温度计
第一章 概述
单片机具有集成高、功能强、可靠性高、体积小、功耗低、使用方便、价格低廉等特点,在各个领域得到了广泛的应用和发展,目前已渗透到人们工作和生活的各个角落,几乎是无所不在。 在日常生活及工业生产过程中,经常要用到温度的检测及控制,温度是生产过程和科学实验中普遍而且重要的物理参数之一。在生产过程中,为了高效地进行生产,必须对它的主要参数,如温度、压力、流量等进行有效的控制。温度控制在生产过程中占有相当大的比例。温度测量是温度控制的基础,技术已经比较成熟。传统的测温元件有热电偶和二电阻。而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,这些方法相对比较复杂,需要比较多的外部硬件支持。我们用一种相对比较简单的方式来测量。我们采用美国DALL AS 半导体公司继DS 1820之后推出的一种改进型智能温度传感器DS 18B20作为检测元件,温度范围为-55~125 ºC , 最高分辨率可达0. 0625 ºC 。DS 18B20可以直接读出被侧温度值,而且采用三线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点。
第二章 系统总体方案设计
按系统功能要求,决定控制系统采用AT89C51单片机,温度测量采用DS18B20. 系统除能确保实现要求的功能外,还可以方便地进行其功能的扩展。本文采用AT89C51作为核心元件,AT89C51是一个低电压,高性能CMOS 8位单片机带有4K 字节的可反复擦写的程序存储器(PENROM )。和128字节的存取数据存储器(RAM ),这种器件采用ATMEL 公司的高密度、不容易丢失存储技术生产,并且能够与MCS-51系列的单片机兼容。片内含有8位中央处理器和闪烁存储单元,有较强的功能的AT89C51单片机能够被应用到控制领域中。AT89C51提供以下的功能标准:4K 字节闪烁存储器,128字节随机存取数据存储器,32个I/O口,2个16位定时/计数器,1个5向量两级中断结构,1个串行通信口,片内震荡器和时钟电路。另外,AT89C51还可以进行0HZ 的静态逻辑操作,并支持两种软件的节电模式。闲散方式停止中央处理器的工作,能够允许随机存取数据存储器、定时/计数器、串行通信口及中断系统继续工作。掉电方式保存随机存取数据存储器中的内容,但震荡器停止工作并禁止其它所有部件的工作直到下一个复位。
采用美国DALLAS 公司生产的 DS18B20温度传感器,DS18B20测量温度范围为-55℃~125℃,精度误差在±0.5℃以内。DS18B20可以程序设定9~12位分辨率,及用户设定的报警温度存储在EEPROM 中,掉电后仍然保存。通过温度传感器DS18B20采集外部温度数据,由DS18B20的DS 口把数据传输给单片机,再经单片机处理后,由数码管电路把温度数据显示出来。单片机外围电路由74HC138、74HC573和LED 数码管组成。
第三章 系统框图与工作原理
系统框图如下:
工作原理:
用A T 89C 51的P 1. 3口和D S 18B 20的DS 口相连接,以实现对D S 18B 20进行初始,读写数据等操作。P0. 0~P 0.7口和74HC 573锁存器8端数据输入口相连,以存储高低电平的状态后,74HC 573锁存器的8端数据输出口和数码管的a 、b 、c 、d 、e 、f 、g 、d p 端。采用动态扫描L E D 显示,通过P 2. 0~P2. 2口和74H C 138译码器3端数据输入口相连,编译片选数据作为8位L E D 片选信号。
第四章 各部分方案选定、功能及计算
4.1、主控制器:功能及芯片选择
4.1、1单片机 AT89C51
AT89C51是一个低电压,高性能CMOS 8位单片机带有4K 字节的可反复
擦写的程序存储器(PENROM )。和128字节的存取数据存储器(RAM ),这种器件采用ATMEL 公司的高密度、不容易丢失存储技术生产,并且能够与MCS-51系列的单片机兼容。片内含有8位中央处理器和闪烁存储单元,有较强的功能的AT89C51单片机能够被应用到控制领域中。
4.1、2 单片机 AT89C51的特点
AT89C51是一种带4K 字节闪烁可编程可擦除只读存储器(FPEROM —Falsh Programmable and Erasable Read Only Memory)的低电压,高性能CMOS8位微处理器,俗称单片机。该器件采用ATMEL 高密度非易失存储器制造技术制造,与工业标准的MCS-51 指令集和输出管脚相兼容。由于将多功能8位CPU 和闪烁存储器组合在单个芯片中,ATMEL 的AT89C51是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。 1.主要特性: 与MCS-51 兼容
4K 字节可编程闪烁存储器 寿命:1000写/擦循环 数据保留时间:10年 全静态工作:0Hz-24Hz 三级程序存储器锁定 128*8位内部RAM 32可编程I/O线 两个16位定时器/计数器 5个中断源 可编程串行通道
低功耗的闲置和掉电模式 片内振荡器和时钟电路 4.1、2 温度传感器DS18B20
DS18B20的特点:
·独特的单线接口,只需1个接口引脚即可通信; ·每个器件有唯一的64位的序列号存储在内部存储器中; ·简单的分布式温度检测应用; ·无需外部器件; ·可通过数据线供电;
·测温范围从-55至+125℃,增量值为0.5℃; ·温度计分辨率有9~12位可供选择; ·最多在750ms 内将温度转换为12位数字; ·用户可定义的非易失性的温度告警设置;
·报警搜索命令可识别超过程序限定温度(温度报警条件)的器件; ·应用范围包括恒温控制工业系统、消费类产品温度计或任何热敏系统。
DS18B20工作原理:
低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送
给计数器1。高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。图3中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。
DS18B20原理图:
DS18B20是采用外部供电的方式,其中R34为上拉电阻。DS18B20 的DS 脚接于单片机的P1.3口。
DS18B20的工作时序:
复位时序:
主机总线在T0时刻发送一复位脉冲(最短为480US 低电平信号),接着在T1时刻释放总线并进入接收状态。DS18B20在检测到总线的上升沿后,等侍15-60US ,接着DS18B20在T2时刻发出存在脉冲(低电平,持续60-240US )
写0和写1时序:
当主机总线T0时刻从高拉到低时,就产生写时间隙,从T0时刻开始15US 之内就将所需要写的位送到总线上。DS18B20在T0后15-60US 间对总线采样。如果采样到低电平,则写入的位是0。惹采样到高电平,则写入的位是1。当连续写2位间的间隙应该大于1US 。
读数据时序:
主机总线从T0时刻从高拉到低电平时,总线只需要保持低电平7US 。之后在T1时刻将总线拉高,产生读时间隙,在讯时间隙在T1时刻后T2时刻前有效。TZ 距T0为15US ,也就是说。必须在T3时刻前主机完成读数据。DS18B20会在T0后的60US 内释放总线。
DS18B20数据传输格式:
DS18B20在发送数据的时候,先发最低位然后一位位的发送,直到发到最高位。 DS18B20在接收的时候,也是先收数据的最低位,然后一直收到数据的最高位。
DS18B20的工作流程图:
4.3 显示接口:
显示接口原理图如下:
采用8端共阴极型数码管,用74HC573锁存器锁存状态,用74HC138编译片选信号,采用动态扫描显示。
显示过程中:由单片机的P2.0~P2.2口接74HC138编译器输入端,再将译码器的8位输出端接到LED 的8位片选端。单片机的P0.0~P0.7接74HC573锁存器,再把锁存器的8位输出端接LED 的a 、b 、c 、d 、e 、f 、g 端。
第五章 应用系统的程序设计
系统算法分析
系统程序主要包括主程序,读出温度子程序,温度转换命令子程序,计算温度子程序,显示数据刷新子程序等。
5.1主程序
主程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值,温度测量每1s 进行一次。这样可以在一秒之内测量一次被测温度,其程序流程见图所示。
5.2读出温度子程序
读出温度子程序的主要功能是读出RAM 中的9字节,在读出时需进行CRC 校验,校验有错时不进行温度数据的改写。其程序流程图如示。
5.3温度转换命令子程序
温度转换命令子程序主要是发温度转换开始命令,当采用12位分辨率时转换时间约为750ms ,在本程序设计中采用1s 显示程序延时法等待转换的完成。温度转换命令子程序流程图如上图所示。
5.4 计算温度子程序
计算温度子程序将RAM 中读取值进行BCD 码的转换运算,并进行温度值正负的判定,其程序流程图如图所示。
5.5 显示数据刷新子程序
显示数据刷新子程序主要是对显示缓冲器中的显示数据进行刷新操作,当最高显示位为0时将符号显示位移入下一位。其程序流程图如图所示。
第六章 调试说明、使用说明
调试即及使用说明:调节DS18B20当前温度值时,LED 数码管上的温度值也会随之变化而变化。 仿真截图:
第七章 设计总结 附录A:程序清单
#include //包含头文件,一般情况不需要改动,头文件包含特殊
功能寄存器的定义
#include #include
#define uchar unsigned char #define uint unsigned int;
/* 定义端口 */ sbit seg1=P2^0; sbit seg2=P2^1; sbit seg3=P2^2;
sbit DQ=P1^3;//ds18b20 端口 sfr dataled=0x80;//显示数据端口
/******************************************************************/ /* 全局变量 */ /******************************************************************/
uint temp;
uchar flag_get,count,num,minute,second;
uchar code tab[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; //7段数码管段码表共阴 uchar str[6];
/******************************************************************/ /* 函数声明 */ /******************************************************************/
void delay1(uchar MS);
unsigned int ReadTemperature(void); oid Init_DS18B20(void);
unsigned char ReadOneChar(void); void WriteOneChar(unsigned char dat); void delay(unsigned int i);
/******************************************************************/ /* 主函数 */ /******************************************************************/ main()
unsigned char TempH,TempL; TMOD|=0x01;//定时器设置 TH0=0xef; TL0=0xf0; IE=0x82; TR0=1; P2=0x00; count=0; while(1) {
str[5]=0x39; //显示C 符号 str[1]=tab[TempH/100]; //百位温度 str[2]=tab[(TempH%100)/10]; //十位温度
str[3]=tab[(TempH%100)%10]|0x80; //个位温度, 带小数点 str[4]=tab[TempL];
if(flag_get==1) //定时读取当前温度 {
emp=ReadTemperature(); if(temp&0x8000)
{
str[0]=0x40;//负号标志 temp=~temp; // 取反加1 temp +=1; } else str[0]=0; TempH=temp>>4; TempL=temp&0x0F;
TempL=TempL*6/10;//小数近似处理 flag_get=0;} } }
/******************************************************************/ /* 定时器中断 */ /******************************************************************/
void tim(void) interrupt 1 using 1//中断,用于数码管扫描和温度检测间隔 {TH0=0xef;//定时器重装值 TL0=0xf0; num++; if (num==50) {num=0;
flag_get=1;//标志位有效 second++; if(second>=60) {second=0; minute++; }} count++; if(count==1)
{P2=0;
dataled=str[0];}//数码管扫描 if(count==2) {P2=1;
dataled=str[1];} if(count==3) { P2=2;
dataled=str[2];} if(count==4) { P2=3;
dataled=str[3];} if(count==5) { P2=4;
dataled=str[4];} if(count==6) { P2=5;
dataled=str[5]; count=0;}}
/******************************************************************/ /* 延时函数 */ /******************************************************************/
void delay(unsigned int i)//延时函数 {while(i--);}
/******************************************************************/ /* 初始化 */ /******************************************************************/ void Init_DS18B20(void) {unsigned char x=0; DQ = 1; //DQ复位
delay(8); //稍做延时 DQ = 0; //单片机将DQ 拉低 delay(80); //精确延时 大于 480us DQ = 1; //拉高总线 delay(10);
x=DQ; //稍做延时后 如果x=0则初始化成功 x=1则初始化失败 delay(5);}
/******************************************************************/ /* 读一个字节 */ /******************************************************************/ unsigned char ReadOneChar(void) {unsigned char i=0; unsigned char dat = 0; for (i=8;i>0;i--) {DQ = 0; // 给脉冲信号 dat>>=1;
DQ = 1; // 给脉冲信号 释放总线 if(DQ) dat|=0x80; delay(5);} return(dat);}
/******************************************************************/ /* 写一个字节 */ /******************************************************************/ void WriteOneChar(unsigned char dat) {unsigned char i=0; for (i=8; i>0; i--) {DQ = 0; DQ = dat&0x01; delay(5);
DQ = 1; dat>>=1;} delay(5);}
/******************************************************************/ /* 读取温度 */ /******************************************************************/ unsigned int ReadTemperature(void) {unsigned char a=0; unsigned int b=0; unsigned int t=0; Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作 WriteOneChar(0x44); // 启动温度转换 delay(200); Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)温度
a=ReadOneChar(); //低位 b=ReadOneChar(); //高位 b
附录B:数字温度计电路原理图
前两个就是