基于DS18B20的温度采集系统设计
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
2012 ~ 2013 学年第2 学期
《单片机原理与应用》
课程设计报告
题目:基于DS18B20的温度采集系统设计
专业: 自动化
班级:
电气工程系
2013年5月3日
任务书
课题名称基于DS18B20的温度采集系统设计指导教师(职称)林开司
摘要
通过系统的分析和总结 ,得出温室大气温度信号的采集传感器件所需的测量程小 ,精确度不高 ,抗干扰性较强 ,经济性较好的结论。
并以此为依据 ,选用 DS18B20数字温度传感器为温度采集器件 ,进行了温度采集系统的硬件和软件设计 ,实现了采集系统分布式采集温度信号的功能。
同时 ,通过串行总线完成了采集系统与上位计算机的连接 ,实现了采集系统的网络化监控功能。
关键词温度采集;DS18B20温度传感器;仿真;单片机
基于DS18B20的温度采集系统设计
目录
摘要 (I)
第一章 DS18B20温度传感器 (1)
1.1DS18B20的工作原理 (1)
1.2DS18B20的使用方法 (3)
第二章单片机AT89C51 (6)
2.1AT89C51简介 (6)
2.2AT89C51功能 (6)
2.3AT89C51引脚 (6)
第三章系统硬件电路设计 (9)
3.1测温控制电路原理图 (9)
3.2上电复位电路 (9)
3.3时钟电路 (9)
3.4数码管显示电路 (10)
3.5温度报警电路 (11)
第四章程序设计 (12)
4.1DS18B20复位检测子程序流程图 (12)
4.2温度转换子程序图 (12)
4.3写DS18B20子程序图 (12)
5.4读DS18B20子程序图 (13)
4.5温度计算子程序图 (14)
第五章调试与仿真 (14)
第六章结论与体会 (16)
参考文献 (17)
附录: (18)
答辩记录及评分表 (21)
第一章 DS18B20温度传感器
1.1 DS18B20的工作原理
DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s 减为750ms。
DS18B20测温原理如图3所示。
图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。
高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。
计数器1和温度寄存器被预置在-55℃所对应的一个基数值。
计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。
图3中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。
图1-1DS18B20数字温度传感器内部结构
DS18B20有4个主要的数据部件:
(1)光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。
64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码(CRC=X8+X5+X4+1)。
光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个
DS18B20的目的。
(2)DS18B20中的温度传感器可完成对温度的测量,以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB形式表达,其中S为符号位。
表1-1: DS18B20温度值格式表
这是12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0,这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际温度。
例如+125℃的数字输出为07D0H,+25.0625℃的数字输出为0191H,-25.0625℃的数字输出为FF6FH,-55℃的数字输出为FC90H。
表1-2: DS18B20温度数据表
(3)DS18B20温度传感器的存储器
DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EEPRAM,后者存放高温度和低温度触发器TH、TL和结构寄存器。
(4)配置寄存器
该字节各位的意义如下:
TM R1 R0 1 1 1 1 1
表1-3:配置寄存器结构
低五位一直都是"1",TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。
在DS18B20出厂时该位被设置为0,用户不要去改动。
R1和R0用来设置分辨率,如下表所示:(DS18B20出厂时被设置为12位)
R1 R0 分辨率温度最大转换时间
0 0 9位93.75ms
0 1 10位187.5ms
1 0 11位375ms
1 1 12位750ms
表1-4:温度分辨率设置表
表1-5 引脚功能
1.2 DS18B20的使用方法
由于DS18B20采用的是1-Wire总线协议方式,即在一根数据线实现数据的双向传输,而对AT89S51单片机来说,硬件上并不支持单总线协议,因此,我们必须采用软件的方法来模拟单总线的协议时序来完成对DS18B20芯片的访问。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。
该协议定义了几种信号的时序:初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。
而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是低位在先。
DS18B20的初始化
(1)先将数据线置高电平“1”。
(2)延时(该时间要求的不是很严格,但是尽可能的短一点)
(3)数据线拉到低电平“0”。
(4)延时750微秒(该时间的时间范围可以从480到960微秒)。
(5)数据线拉到高电平“1”。
(6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。
据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。
(7)若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。
(8)将数据线再次拉高到高电平“1”后结束。
DS18B20的写操作
(1)数据线先置低电平“0”。
(2)延时确定的时间为15微秒。
(3)按从低位到高位的顺序发送字节(一次只发送一位)。
(4)延时时间为45微秒。
(5)将数据线拉到高电平。
(6)重复上(1)到(6)的操作直到所有的字节全部发送完为止。
(7)最后将数据线拉高。
DS18B20的读操作
(1)将数据线拉高“1”。
(2)延时2微秒。
(3)将数据线拉低“0”。
(4)延时3微秒。
(5)将数据线拉高“1”。
(6)延时5微秒。
(7)读数据线的状态得到1个状态位,并进行数据处理。
(8)延时60微秒。
ROM指令表1-6 :
第二章单片机AT89C51
2.1 AT89C51简介
AT89S51美国ATMEL公司生产的低功耗,高性能CMOS 8位单片机,片内含4K BytesISP(In-system programmable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及AT89C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元。
单片机AT89S51强大的功能可为许多嵌入式控制应用系统提供高性价比的解决方案。
2.2 AT89C51功能
AT89S51提供以下标准功能:40个引脚、4K Bytes Flash片内程序存储器、128 Bytes
的随机存取数据存储器(RAM)、32个外部双向输入/输出(I/O)口、5个中断优先级2层
中断嵌套中断、2个数据指针、2个16位可编程定时/计数器、2个全
双工串行通信口、看门狗(WDT)电路、片内振荡器及时钟电路。
此外,AT89S51可降至
0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式,空闲模式,CPU暂停工作,而RAM、定时/计数器、串行通信口、外中断系统可继续工作。
掉电模式冻结振荡器而保存RAM
的数据,停止芯片其它功能直至外中断激活或硬件复位。
同时该芯片还具有PDIP、TQFP
和PLCC等三种封装形式,以适应不同产品的需求。
2.3 AT89C51引脚
P0口:P0口为一个8位漏级开路双向I/O口,也即地址/数据总线复用口。
作为输出
口用时,能驱动8个TTL逻辑门电路。
对端口写“1”时,被定义为高阻输入。
在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复
用,在访问期间激活内部上拉电阻。
在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外
接上拉电阻。
P1口:P1口是一个带内部上拉电阻的8位双向I/O口,P1口的输出缓冲级可驱动(吸收或输
出电流)4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此
时可作输入口。
作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输
出一个电流(I IL)。
P2口:P2口是一个带有内部上拉电阻的8位双向I/O口, P2口的输出缓冲级可驱动(吸收
或输出电流)4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,
此时可作输入口。
作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会)。
输出一个电流(I
IL
在访问外部程序存储器或16位地址的外部数据存储器(例如执行MOVX@DPTR指令)时,P2口送出高8位地址数据。
在访问8位地址的外部数据寄存器(例如执行MOVX@Ri指令)时,P2口线上的内容(也即特殊功能寄存器(SFR)区中P2寄存器的内容),在整个访问期间不改变。
P3口: P3口是一个带有内部上拉电阻的双向8位I/O口, P3口的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对P3口写“1”时,它们被内部的上拉电阻拉高并可
)。
作为输入端口。
作输入口使用时,被外部信号拉低的P3口将用上拉电阻输出电流(I
IL RST:复位输入。
当振荡器工作时,RST引脚出现两个机器周期以上的高电平时间将使单片机复位。
WDT溢出将使该引脚输出高电平,设置SFR AUXR的DISRTO位(地址8EH)可打开或关闭该功能。
DISRTO位缺省为RESET输出高电平打开状态。
ALE/:当访问外部存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
即使不访问外部寄存器,ALE仍以时钟振荡频率的1/6输出固定的正脉冲信号,因此它可对外输出时钟或用于定时目的。
值得注意的是:每当访问外部数据存储器时将跳过一个ALE脉冲。
对Flash存储器编程期间,该引脚还用于输入编程脉冲(PROG)。
如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。
该位置位后,只要一条MOVX和MOVC指令才会激活ALE。
此外,该引脚会被微弱拉高,单片机执行外部程序时,应设置ALE无效。
PSEN:程序存储允许(PSEN)输出是外部程序存储器的读选通信号,当AT89S51由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。
当访问外部数据存储器时,没有两次有效的PSEN信号。
EA/VPP:外部访问允许。
欲使CPU仅访问外部程序存储器(地址为0000H-FFFFH),EA 端必须保持低电平(接地)。
需要注意的是:如果加密位LB1被编程,复位时内部会锁存EA 端状态。
如EA端保持高电平(接VCC端),CPU则执行内部程序存储器中的指令。
AT89C51与DS18B20连接的Proteus电路原理图2-1
第三章系统硬件电路设计
3.1测温控制电路原理图
51单片机是此硬件电路设计的核心,单片机和DS18B20的电路连接如第二章图2-1所示。
3.2 上电复位电路
图3-1 上电复位电路
本设计中AT89C51是采用上电自动复位,如图4-2所示。
上电瞬间,RC电路充电,RST引线端出现正脉冲,只要RST端保持10ms以上的高电平,就能使单片机有效地复位。
3.3 时钟电路
此处选用内部时钟方式。
即利用其内部的振荡电路在XTAL1和XTAL2引线上外接定时组件,内部振荡电路产生自激振荡。
最常用的是在 XTAL1和XTAL2之间接晶体振荡器与电路构成稳定的自激振荡器,如图3-2电路.
图3-2 时钟电路
3.4数码管显示电路
发光二极管LED是一种通电后能发光的半导体器件,其导电性质与普通二极管类似。
它使用了8个LED发光二极管,其中7个显示字符,1个显示小数点,故通常称之为7段发光二极管数码显示器,如图4-5所示。
为了显示字符,要为 LED显示器提供段码(或称字形代码),组成一个“8”字形的7段,再加上1个小数点位,共计8段,因此提供给LED显示的段码为1个字节。
各段码位的对应关系如下:
段码位D7 D6 D5 D4 D3 D2 D1 D0
显示段dp g f e d c b a
表格3-1 各段码位的对应关系
共阳极接法:把发光二极管的阳极连在一起构成公共阳极,使用时公共阳极接+5 V, 每个发光二极管的阴极通过电阻与输入端相连。
当阳极端输入低电平时,段发光二极管就导通点亮,而输入高电平时则不点亮。
共阳极显示段码
图3-3 LED数码显示器的显示段码
本设计采用LED数码管显示电路,该显示电路由7段共阳数码管,限流电阻,三极管,基极电阻,P0口,P2口等组成。
P0口通过与电阻排与数码管的8个数据位相连,送显示数码。
电阻即可起到限流作用,又可起到上拉电阻的作用。
P2口的P2.0~P2.3通过4个10kΩ的电阻和4个三极管与4个7段数码管相连,起位选的作用。
数码管显示电路的原理图如图4-6 。
图3-4数码管显示电路图
3.5 温度报警电路
温度报警电路是检测当前温度的值并与预置的温度上下限进行比较,当当前温度超出预置的温度上下限时,系统就会立即发出报警信号。
此设计的温度报警电路是由声光报警电路组成,用到了蜂鸣器和LED发光二极管。
原理图如图4-7:
图3-5温度报警电路
第四章 程序设计
本设计的程序编写主要是对DS18B20温度传感器的程序设计,下面主要对DS18B20
的程序编写进行说明。
4.1 DS18B20复位检测子程序流程图
主机控制DS18B20完成任何操作之前必须先初始化,即主机发一复位脉冲(最短为480us 的低电平),接着主机释放总线进入接收状态,DS18B20在检测到I/O 引脚上的上升沿之后,等待15-60us 然后发出存在脉冲(60-240us 的低电平)。
如图5-3所示。
图4-1 初始化程序
DS18B20复位检测子程序的主要功能为检测DS18B20是否存在。
若存在则将标志位FLAG1置1,反则置0.后续程序可以通过判断标志位来决定进行何种操作。
流程图如图5-2:
4.2 温度转换子程序图
温度转换命令子程序主要是发温度转换命令,当采用12位分辨率时转换时间约为750ms ,流程图如图
4-2:
4.3 写DS18B20子程序图
写时间片:将数据从高电平拉至低电平,产生写起始信号。
在15us 之内将所需写的位送到数据在线,
在
15us 到60us 之间对数据线进行采样,如果采样为高电平,就写1,如果为低电平,写0就发生。
在开始另一个写周期前必须有1us 以上的高电平恢复期。
其写时序图4-3,流程
开始
发跳过rom 命令
写入子程序 发温度转换命令
返回
图4-2 温度转换子程序
图如图4-5:
图4-3 写时序
5.4 读DS18B20子程序图
读时间片:主机将数据线从高电平拉至低电平1us 以上,再使数据线升为高电平,从而
产生读起始信号。
主机在读时间片下降沿之后15us 内完成读位。
每个读周期最短的持续期为60us,各个读周期之间也必须有1us 以上的高电平恢复期。
如图5-8.
读温度子程序只读出DS18B20缓存器前4个字节的数据:温度值LSB\温度值MSB 、温
Y N
开始
发DS18B20复位命令
跳过rom 命令
发读温度命令
8位元組完
返回
存入温度缓存器
图4-5读温度子程序图
读操作 Y N
开始 R2=8
写之前复位CLR DQ
延时16us 以上
RRC A 延时100us DQ=1
R2=0
返回
SETB DQ
图4-4写入DS18B20子程序图
CLR C
度报警值TH 和TL ,并将它们分别存入25H~28H 单元中。
如图4-6:
图4-6读时序
4.5 温度计算子程序图
温度计算子程序首先判断温度值MSB 的符号位,当符号位S=0时,表示测得的温度值为正,可以直接将二进制转换为十进制;当符号位S=1时,表示测得的温度值为负,要先将补码变成原码,再计算十进制值。
计算时先将温度值LSB 的低四位取出,进行小数部分数据处理。
再将温度值LSB 的高四位和温度值MSB 的低四位取出,重新组合后进行整数部分数据处理。
如图5-9:
第五章 调试与仿真
本设计的程序编辑完成以后,通过keil 编程软件来调试,经过多次的修改调试。
N
Y
温度零
下 温度值取补码置“-”标志 置“+”标志
计算小数字BCD 值 计算整数字元BCD 值
返回
开始
图4-7计算温度BCD 码子程序
软件的仿真是用的Proteus ISIS,是英国Labcenter公司开发的电路分析与实物仿真软件。
将设计的电路图连接好,将程序加入到AT89C51中,进行仿真,和多次的修改,最终得到预测的结果。
仿真电路完整图如下:
正温度仿真
Proteus仿真总电路图-1 5-1
负温度仿真
Proteus仿真总电路图-2 5-2
第六章结论与体会
传统的检测大气温度的手段大多采用模拟温度传感器采集数据 ,并且需要经过一系的 A /D转换、信号放大和滤波等过程。
由于在电路设计、元件选择和软件设计等方面存在诸多因素的影响 ,往往容易造成系统不稳定 ,并且扩展性和网络化程度也非常差。
笔者系统地分析并归纳了温室大气的温度数据特征 ,并采用DS18B20温度传感器设计了温室温度采集系统。
经过实践论证 ,该系统可在10 ℃~85 ℃实现0. 5 ℃的采集精度。
同时 ,基于51单片机和DS18B20数字传感器的采集系统具有硬件接线简单、测量精度高、
稳定性好和抗干扰性强等诸多优点。
温室温度采集系统通过串行总线实现与上位监控机的连接 ,使系统具备了远程监控能力 ,从而实现了实时监控温室内大气温度数据的功能。
该系统在农业信息化领域和其他工业领域均具备了良好的应用和推广价值。
一周的课程设计,使我们有了很多的心得体会一开始接触这个课题时我还不知道该从何下手,很多东西不知该如何实现,经过一星期的努力,在图书馆和网上查资料,小组讨论,终于是完成了任务。
通过这次设计加深了我们对这门课程的了解,以前总是觉得理论结合不了实际,但通过这次设计使我们认识到了理论结合实际的重要性。
但由于我们知识的限制,设计还有很多不足之处,希望老师指出并教导。
课程设计是培养学生综合运用所学知识,发现,提出,分析和解决实际问题,锻炼实践能力的重要环节,是对学生实际工作能力的具体训练和考察过程。
很感激学校给了我们这次动手实践的机会,让我们学生有了一个共同学习,增长见识,开拓视野的机会。
也感谢老师对我们的指导,我们会以这次课程设计作为对自己的激励,继续学习。
参考文献
[1] 彭桂兰,张学军,张新东.温室环境计算机测控技术的研究现状和发展趋势[J].现代化农
业,2001.
[2] 彭里.温室大棚检测控制系统的研究[J ].计算机工程,2000.
[3] 何鹏,袁其,丁春欣.传感器在温室大棚环境控制中的应用[J ].计算机与农业,2002.
[4] 崔志富,赵亭荃,李建国.温度传感器在农业生产中的应用[J ].现代化农业,2002.
[5] 周月霞,孙传友. DS1820传感器及其测温方法的改进[J ].石油仪器,2002.
[6] 苏麟祥. DS1820数字温度传感器的功能特性及其设计[J ].世界采矿快报,2000.
[7] JAN AXELS ON.串行端口大全[M ].精英科技,译.北京:中国电力出版社,2001.
附录:
#include<reg51.h>
#include<intrins.h>
#define uchar unsigned char
#define uint unsigned int
sbit DQ=P2^4;
unsigned char flag,presence; //负数标志
uchar code scan[8]={0xfe,0xfd,0xfb,0xf7,0xef,0xdf,0xbf,0x7f};
uchar code table[13]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,
0x7f,0x6f,0x40,0x39,0x00};
uchar code ditab[16]={0x00,0x01,0x01,0x02,0x03,0x03,0x04,0x04,0x05,0x06,0x06,
0x07,0x08,0x08,0x09,0x09};
uchar dispbuf[8];
uchar temper[2];
uchar x=1;
//uchar x=0;
void delay(unsigned int us) reentrant
{
while(us--);
} // 延时函数
void reset(void)
{
DQ=1;
//delay(8);
DQ=0;
delay(90);
DQ=1;
delay(14);
x=DQ;
delay(20);
DQ=1;
} //复位函数
uchar readbyte(void)
{ uchar i=0;
uchar dat=0;
for(i=8;i>0;i--)
{ DQ=0;
dat>>=1;
DQ=1;
if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
} //从1820中读一个字节
void writebyte(unsigned char dat)
{
uchar i=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=dat&0x01;
delay(5);
DQ=1;
dat>>=1;
}
delay(4);
} //向1820中写入一个字节void readtemp(void)
{
uchar a=0,b=0;
reset();
while(x==0)
{
if(x==0)
reset();
else break;
}
writebyte(0xcc);
writebyte(0x44);
reset();
writebyte(0xcc);
writebyte(0xbe);
a=readbyte();
b=readbyte();
if(b>0x0f)
{ a=~a+1;
if(a==0)
b=~b+1;
else b=~b;
flag=10;
}
else flag=12;
temper[0]=a&0x0f;
a=a>>4;
temper[1]=b<<4;
temper[1]=temper[1]|a;
} //读取实时温度void scandisp()
{ unsigned char i,value;
for(i=0;i<6;i++)
{ P3=0xff;
value=table[dispbuf[i]];
if(i==3)
value|=0x80;
P0=value;
P3=scan[i];
delay(50);
}
} //动态扫描显示函数void main()
{ uchar temp=10,temp1;
while(1)
{ readtemp();
temp1=temper[0];
temp=temper[1];
if(flag==10)
dispbuf[0]=flag;
else
dispbuf[0]=temp/100;
dispbuf[3]=ditab[temp1];
dispbuf[2]=temp%10;
temp=temp/10;
dispbuf[1]=temp%10;
scandisp();
}
}
答辩记录及评分表。