版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
多点温度计设计课程设计方案课程设计要求1.1.1.基本要求利用数字温度传感器与单片机结合来测量温度。利用数字温度传感器DS18B20采集温度信号,计算后用LED1602字符型液晶显示相应的温度值。数字温度计所测量的温度采用数字显示,控制器使用单片机AT89C51,测温传感器使用DS18B20。首先进行预设计,根据选定硬件电路方案,充分利用单片机软、硬件资源。主要设计指标有测量两点或两点以上的温度,测温范围均为:0~100℃;每点温度分辨力:0.0625℃;测量速率:2次/秒自动连续测量。1.1.2.扩展要求用图形液晶显示温度曲线,当前温度、单位等,利用单片机实现一些扩展功能,如:实现超温报警等,或结合自身能力实现其他功能。课程设计内容1.2.1设计方案根据课程设计要求,制定课程设计方案。采用专用集成数字化温度传感器DS18B20测温,它具有接口简单、直接数字量输出、精度高等优点。DS18B20是DALLAS公司的最新单线数字温度传感器,它的温度检测与数字检测数据全集成于一个芯片之上,测量范围为-55~+125℃,在-10~+85℃内,精度为±0.0625℃,完全可以满足设计指标要求。在DS18B20中的每个器件上都有独一无二的序列号,这个序列号是出厂前已经刻录在DS18B20中,需要用户使用前进行读取。它还可以实现“一线总线”的数字方式传输,即在一个端口上,可以挂很多数字温度传感器,通过读取每个DS18B20的序列号,进行匹配后完成多个DS18B20的测温过程,电路简单,易于实现。另DS18B20支持3~5.5V的电源范围,使得系统设计更加方便灵活。DS18B20支持报警温度设置,用户设定的报警温度保存在EEPROM存储器,满足部分扩展要求,并且掉电后依然保存,方便随时的通断电。单片机控制模块以ATMEL公司生产的AT89C52单片机为主控核心,AT89C52单片机价格便宜,语言简单,是单片机初学者的基本入门课程,对于初学者来说使用容易,且可用性强。在完成对DS18B20所采集的温度进行读取、输出并控制LED1602实时显示外,为了满足扩展要求,增加显示时间模块,完成对时间的设置,以达到设计要求。温度显示模块选用字符型LED1602,1602使用技术成熟,价格便宜,对于实时显示温度、单位等可以满足要求。按键模块直接使用普通按键,操作简单,价格便宜。系统框图如图1所示。AT89C51AT89C51单片机主控制模块蜂鸣器报警电路串口(供电和程序下载)复位和时钟振荡电路1602液晶显示2个DS18b20测温电路图1多点测温系统框图1.2.2设计内容根据制定的实验方案,进行课程设计,其内容包括硬件电路设计和系统软件设计,其主要模块包括AT89C52单片机主控制模块、多个DS18B20测温模块、LED1602液晶显示模块和按键模块。硬件电路较为简单,参照单片机AT89C52和数字温度传感器DS18B20的工作原理和技术手册,以及实验方案中的蜂鸣器设计、按键设计,完成硬件电路图的设计和绘制。系统软件分为两大部分,DS18B20的序列号读取程序和温度测量程序。根据DS18B2的工作过程和读写时序、AT89C52工作特点和想要达到的设计效果,进行程序的编写。具体工作过程为:下载读序列号程序,读取两个DS18B20中的序列号,并记录下来;根据读取的序列号更改数组内容后,重新下载程序,进行多点测温过程,由DS18B20温度传感器芯片测量当前温度,通过程序匹配不同的DS18B20,传送各个DS18B20的测量值,将结果送入单片机;通过AT89C52单片机芯片对送入的测量温度读数进行计算和转换,并将此结果送入液晶显示模块,同时判断是否超过设定的警戒温度,决定蜂鸣器是否工作;LED1602模块将送来的值显示于显示屏上。单片机通过扫描按键,进入不同的子程序,完成时间的显示。课程设计原理1.3.1DS18B20工作原理DS18B20概述DS18B20数字温度传感器是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。DS18B20产品的特点只要求一个端口即可实现通信。在DS18B20中的每个器件上都有独一无二的序列号。实际应用中不需要外部任何元器件即可实现测温。测量温度范围在-55.C到+125.C之间。数字温度计的分辨率用户可以从9位到12位选择。内部有温度上、下限告警设置。DS18B20引脚功能描述见表1。表1DS18B20详细引脚描述DS18B20引脚图如图2所示。DS18B20的主要特性(1)适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电
。(2)独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯
。(3)DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上,实现组网多点测温。(4)DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内。
(5)温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃
(6)可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃可实现高精度测温。
(7)在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快
。(8)测量结果直接输出数字温度信号,以"一线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力
。(9)负压特性:电源极性接反时,芯片不会因发热而烧毁,但不能正常工作。DS18B20内部结构DS18B20的内部框图如图2所示。64位ROM存储器件独一无二的序列号。暂存器包含两字节(0和1字节)的温度寄存器,用于存储温度传感器的数字输出。暂存器还提供一字节的上线警报触发(TH)和下线警报触发(TL)寄存器(2和3字节),和一字节的配置寄存器(4字节),使用者可以通过配置寄存器来设置温度转换的精度。暂存器的5、6和7字节器件内部保留使用。第八字节含有循环冗余码(CRC)。使用寄生电源时,DS18B20不需额外的供电电源;当总线为高电平时,功率由单总线上的上拉电阻通过DQ引脚提供;高电平总线信号同时也向内部电容CPP充电,CPP在总线低电平时为器件供电。(注:INTERNALVDD-内部VDD64-BITROMAND1-wirePROT-64位ROM和单线端MEMORYCONTROLLOGIC-存储器控制逻辑SCRATCHPAD暂存器TEMPERATURESENSOR温度传感器ALARMHIGHTRIGGER(TH)REGISTER上限温度触发ALARMLOWTRIGGER(TL)REGISTER下限温度触发8-BITCRCGENERTOR8位CRC产生器POWERSUPPLLYSENSE电源探测PARASITEPOWERCIRCUIT寄生电源电路)。图2DS18B20内部框图DS18B20中4个主要数据部件①光刻ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码。64位光刻ROM的排列是:开始8位(28H)是产品类型标号,接着的48位是该DS18B20自身的序列号,最后8位是前面56位的循环冗余校验码。光刻ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的。②DS18B20中的温度传感器可完成对温度的测量。以12位转化为例:用16位符号扩展的二进制补码读数形式提供,以0.0625℃/LSB形式表达,其中S为符号位。这是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,如表2所示。(注:TEMPERATURE-温度,DIGITALOUTPUT-数字输出)表2DS18B20温度数据表③DS18B20温度传感器的存储器DS18B20温度传感器的内部存储器包括一个高速暂存RAM和一个非易失性的可电擦除的EEPROM,后者存放高温度和低温度触发器TH、TL和结构寄存器。④配置寄存器表3配置寄存器低五位一直都是"1",TM是测试模式位,用于设置DS18B20在工作模式还是在测试模式。在DS18B20出厂时该位被设置为0,用户不要去改动。R1和R0用来设置分辨率,如表4所示:(DS18B20出厂时被设置为12位)表4R1与R0确定传感器分辨率设置表DS18B20工作过程初始化ROM命令跟随着需要交换的数据;功能命令跟随着需要交换的数据。访问DS18B20必须严格遵守这一命令序列,如果丢失任何一步或序列混乱,DS18B20都不会响应主机。a.初始化:DS18B20所有的数据交换都由一个初始化序列开始。由主机发出的复位脉冲和跟在其后的由DS18B20发出的应答脉冲构成。当DS18B20发出响应主机的应答脉冲时,即向主机表明它已处在总线上并且准备工作。b.ROM命令:ROM命令通过每个器件64-bit的ROM码,使主机指定某一特定器件(如果有多个器件挂在总线上)与之进行通信。DS18B20的ROM如表3-6所示,每个ROM命令都是8bit长。c.功能命令:主机通过功能命令对DS18B20进行读/写Scratchpad存储器,或者启动温度转换。DS18B20的功能命令如表5所示。表5DS18B20功能命令表DS18B20信号方式DS18B20采用严格的单总线通信协议,以保证数据的完整性。该协议定义了几种信号类型:复位脉冲、应答脉冲、写0、写1、读0和读1。除了应答脉冲所有这些信号都由主机发出同步信号。总线上传输的所有数据和命令都是以字节的低位在前。a.初始化序列:复位脉冲和应答脉冲在初始化过程中,主机通过拉低单总线至少480µs,以产生复位脉冲(TX)。然后主机释放总线并进入接收(RX)模式。当总线被释放后,4.7kΩ的上拉电阻将单总线拉高。DS18B20检测到这个上升沿后,延时15µs~60µs,通过拉低总线60µs~240µs产生应答脉冲。初始化波形如图3所示。图3初始化脉冲b.读和写时序:在写时序期间,主机向DS18B20写入指令;而在读时序期间,主机读入来自DS18B20的指令。在每一个时序,总线只能传输一位数据。读/写时序如图4所示。写时序存在两种写时序:“写1”和“写0”。主机在写1时序向DS18B20写入逻辑1,而在写0时序向DS18B20写入逻辑0。所有写时序至少需要60µs,且在两次写时序之间至少需要1µs的恢复时间。两种写时序均以主机拉低总线开始。产生写1时序:主机拉低总线后,必须在15µs内释放总线,然后由上拉电阻将总线拉至高电平。产生写0时序:主机拉低总线后,必须在整个时序期间保持低电平(至少60µs)。在写时序开始后的15µs~60µs期间,DS18B20采样总线的状态。如果总线为高电平,则逻辑1被写入DS18B20;如果总线为低电平,则逻辑0被写入DS18B20。读时序DS18B20只能在主机发出读时序时才能向主机传送数据。所以主机在发出读数据命令后,必须马上产生读时序,以便DS18B20能够传送数据。所有读时序至少60µs,且在两次独立的读时序之间至少需要1µs的恢复时间。每次读时序由主机发起,拉低总线至少1µs。在主机发起读时序之后,DS18B20开始在总线上传送1或0。若DS18B20发送1,则保持总线为高电平;若发送0,则拉低总线。当传送0时,DS18B20在该时序结束时释放总线,再由上拉电阻将总线拉回空闲高电平状态。DS18B20发出的数据在读时序下降沿起始后的15µs内有效,因此主机必须在读时序开始后的15µs内释放总线,并且采样总线状态。DS18B20在使用时,一般都采用单片机来实现数据采集。只需将DS18B20信号线与单片机1位I/O线相连,且单片机的1位I/O线可挂接多个DS18B20,就可实现单点或多点温度检测。图4DS18B20读/写时序图DS18B20测温原理DS18B20的读写时序和测温原理与DS1820相同,只是得到的温度值的位数因分辨率不同而不同,且温度转换时的延时时间由2s减为750ms。DS18B20测温原理如图5所示。图中低温度系数晶振的振荡频率受温度影响很小,用于产生固定频率的脉冲信号送给计数器1。高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。计数器1和温度寄存器被预置在-55℃所对应的一个基数值。计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累加,此时温度寄存器中的数值即为所测温度。图3中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。图5DS18B20测温原理框图1.3.2LED1602工作原理LED1602简介字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,20*2和40*2行等的模块。一般1602字符型液晶显示器实物如图6所示。图61602实物图LED1602的基本参数及引脚功能1602LED分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别。1602LED主要技术参数:显示容量:16×2个字符芯片工作电压:4.5—5.5V工作电流:2.0mA(5.0V)模块最佳工作电压:5.0V字符尺寸:2.95×4.35(W×H)mm引脚功能说明:1602LED采用标准的14脚(无背光)或16脚(带背光)接口,各引脚接口说明如表6所示。表61602引脚说明表编号符号引脚说明编号符号引脚说明1VSS电源地9D2数据2VDD电源正极10D3数据3VL液晶显示偏压11D4数据4RS数据/命令选择12D5数据5R/W读/写选择13D6数据6E使能信号14D7数据7D0数据15BLA背光源正极8D1数据16BLK背光源负极第1脚:VSS为地电源。第2脚:VDD接5V正电源。第3脚:VL为液晶显示器对比度调整端,接正电源时对比度最弱,接地时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度。第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。第5脚:R/W为读写信号线,高电平时进行读操作,低电平时进行写操作。当RS和R/W共同为低电平时可以写入指令或者显示地址,当RS为低电平R/W为高电平时可以读忙信号,当RS为高电平R/W为低电平时可以写入数据。第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。第7~14脚:D0~D7为8位双向数据线。第15脚:背光源正极。第16脚:背光源负极。LED1602的时序及指令说明1602液晶模块内部的控制器共有11条控制指令,如表7所示。表71602控制指令表序号指令RSR/WD7D6D5D4D3D2D1D01清显示00000000012光标返回000000001*3置输入模式00000001I/DS4显示开/关控制0000001DCB5光标或字符移位000001S/CR/L**6置功能00001DLNF**7置字符发生存贮器地址0001字符发生存贮器地址8置数据存贮器地址001显示数据存贮器地址9读忙标志或地址01BF计数器地址10写数到CGRAM或DDRAM)10要写的数据内容11从CGRAM或DDRAM读数11读出的数据内容1602液晶模块的读写操作、屏幕和光标的操作都是通过指令编程来实现的。(说明:1为高电平、0为低电平)指令1:清显示,指令码01H,光标复位到地址00H位置。指令2:光标复位,光标返回到地址00H。指令3:光标和显示模式设置I/D:光标移动方向,高电平右移,低电平左移S:屏幕上所有文字是否左移或者右移。高电平表示有效,低电平则无效。指令4:显示开关控制。D:控制整体显示的开与关,高电平表示开显示,低电平表示关显示C:控制光标的开与关,高电平表示有光标,低电平表示无光标B:控制光标是否闪烁,高电平闪烁,低电平不闪烁。指令5:光标或显示移位S/C:高电平时移动显示的文字,低电平时移动光标。指令6:功能设置命令DL:高电平时为4位总线,低电平时为8位总线N:低电平时为单行显示,高电平时双行显示F:低电平时显示5x7的点阵字符,高电平时显示5x10的点阵字符。指令7:字符发生器RAM地址设置。指令8:DDRAM地址设置。指令9:读忙信号和光标地址BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。指令10:写数据。指令11:读数据。与HD44780相兼容的芯片时序表如表8所示。表8基本操作时序表读状态输入RS=L,R/W=H,E=H输出D0—D7=状态字写指令输入RS=L,R/W=L,D0—D7=指令码,E=高脉冲输出无读数据输入RS=H,R/W=H,E=H输出D0—D7=数据写数据输入RS=H,R/W=L,D0—D7=数据,E=高脉冲输出无读写操作时序如图7和图8所示。图7读操作时序图8写操作时序LED1602的RAM地址映射及标准字库表液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,图9是1602的内部显示地址。图91602LCD内部显示地址在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,无需人工干预。每次输入指令前都要判断液晶模块是否处于忙的状态。1602液晶模块内部的字符发生存储器(CGROM)已经存储了160个不同的点阵字符图形,如图10所示,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,比如大写的英文字母“A”的代码是01000001B(41H),显示时模块把地址41H中的点阵字符图形显示出来,我们就能看到字母“A”图10字符代码与图形对应图LED1602的初始化(复位)过程延时:15mS写指令:38H(不检测忙信号)延时:5mS写指令:38H(不检测忙信号)延时:5mS写指令:38H(不检测忙信号)以后每次写指令、读/写数据操作均需要检测忙信号。写指令38H:显示模式设置写指令08H:显示关闭写指令01H:显示清屏写指令06H:显示光标移动设置写指令0CH:显示开及光标设置课程设计硬件电路设计单片机最小系统模块以AT89C52为核心组成的单片机最小系统,主要包括时钟振荡电路,复位电路。正5V电源接到89C52的40脚(VCC)和20脚(GND)接地。时钟振荡电路的18脚(XTAL1)和19脚(XTAL2)外接12MHz的晶振和2个30pF的电容,振荡频率就是晶振的固有频率,经过一定的电路连接实现设计的功能。复位电路采用上电自动复位和手动复位相结合的方式接到89C52的9脚。时间调节的按键模块包括时、分、光标调节和计数按键组成,分别接在单片机I/O口的P1.0~P1.3口,并通过10K的上拉电阻接5V电源。单片机最小系统原理图如图11所示。图11单片机最小系统电路图DS18B20测温电路由于DS18B20工作在单总线方式,所以它与单片机的接口电路非常简单。采用“一线总线”的数字方式传输,将两个DA18B20的数字输入输出引脚(引脚2)以并联的方式接在单片机I/O口的P2.3口,引脚1(GND)接地,引脚3(VDD)通过一个4.7K的上拉电阻接5V电源。蜂鸣器报警电路,驱动三极管的基极通过一个1K的电阻接在单片机I/O口的P2.4口,三极管集电极接5V电压源,发射机接蜂鸣器VDD脚,蜂鸣器另一管脚接地。具体电路图如图12所示。图12DS18B20测温电路LED1602显示电路LED1602液晶数据输入输出口DB0~DB7通过一个10K的上拉排阻分别接在单片机的P0.0~P0.7,1602的GND、VO和BGGND接地,VCC和BGVCC接5V电压源。具体电路图如图13所示。图13LED1602显示电路系统总电路图综合以上各部分电路,系统总体电路图如图14所示。图14系统总电路图课程设计软件设计与流程图系统软件流程图鸣报警器调用报警模块显示温度数据处理读DS18B20温度值匹配DS18B20显示DS18B20OK读DS18B20序列号DS18B20存在?初始化鸣报警器调用报警模块显示温度数据处理读DS18B20温度值匹配DS18B20显示DS18B20OK读DS18B20序列号DS18B20存在?初始化显示DS18B20ERRORN显示DS18B20ERRORYDS18B20温度超限DS18B20温度超限NY图15系统软件流程图系统源程序(附录3)3.2.1读取序列号程序3.2.2多点测温程序课程设计成果Proteus仿真结果Proteus软件是英国LabCenterElectronics公司出版的EDA工具软件它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前比较好的仿真单片机及外围器件的工具。它可以仿真51系列、AVR、PIC、ARM、等常用主流单片机。还可以直接在基于原理图的虚拟原型上编程,再配合显示及输出,能看到运行后输入输出的效果。对于工程设计及教学起到很大的辅助功能。本设计首先采用Proteus进行软件仿真,对设计方案进行验证和反复修改,减少了更改硬件电路的麻烦和对硬件的损伤,对设计效果可以提前进行明朗的验证和查错。具体仿真结果如图16、17所示。图16读序列号仿真结果Proteus软件中默认的DS18B20的序列号为2830C5B80000008E,将多点测温程序中的数组改为以上序列号,进行仿真,测温结果如图所示。图17多点测温仿真结果实物测试结果与数据记录4.2.1测试结果实物测试结果与仿真结果相同,完成了设计要求,具体实物测试结果图如下。系统总图图18系统总图硬件部分图19硬件电路软件部分图20软件程序读序列号结果DS18B20壹号序列号为28622C430400009C。图21读序列号1DS18B20贰号序列号为2883614304000087。图22读序列号实时测温结果测试时间为19:32:36。图23实时测温1测试时间为20:16:50。图24实时测温24.2.2数据记录多点测温的环境是实验室,所以无法取到较低和较高的温度,故测试范围在15~35℃,将本系统两点测温结果的平均值与用水银温度计测得的结果进行比较,对设计系统进行误差分析。数据记录如表9所示。表9测试数据记录(单位:摄氏度)测试结果试验次数两点测量的平均值真实值绝对误差相对误差115.30649219.61031322.00952424.8040450.00000626.40769726.50377827.00370927.50727100.003531128.528.50.00.0000010.006821329.506781430.003331531.303111632.603081733.802951835.435.40.00.00000总结与分析4.2.2结果总结由实验数据表格可以看出,在实验室条件下,该系统能较好的完成两个点测温的要求,完成课程设计的基本要求。本系统的拓展功能有利用软件设计温度上下限,当温度超过界限时,蜂鸣器响,实现报警;LED1602增加时间显示部分,可直接记录温度测量的时间点,方便数据分析。该系统功能实现的过程是通过DS18B20数字温度传感器进行采温,然后经过单片机的处理和转换,输入到1602液晶进行温度的实时显示,同时利用单片机设置实时显示时间,方便温度测量。4.2.3优缺点分析本系统能够完成两点测温,通过比较和计算两点温度的平均值,比单点测温可以更精确地得到实际温度值,可以应用于对温度精确值要求较高的地方,所得误差较小。本系统存在一些不足,DS18B20是固定的,不能够灵活的测量空间中任意位置点的温度;DS18B20随温度的升高测温精确程度会逐渐下降,产生非线性误差,因此需要对数据进行更为广泛的分段,利用查表法,在不同温度区域内通过程序的补偿找回温度的漂移,这样的工作量就比较复杂和庞大;现有的实验装备虽然可靠,但是实际效应较为低下,只能测量空气状态下的室温,无法投入到现实测量中,例如水温的测量,这便需要防水处理,势必会引入新的误差因素,造成更为复杂的误差曲线,系统的稳定性和安全性随之大幅下降。心得与体会本次单片机的课程设计虽然过程有些曲折,但总结最后,我收获了很多。它真正的培养我了作为一名工程师所应具备的素质,过程中我新学习了Keil、Proteus软件的使用。同时,在老师的严格要求下,第一次我完成了一个完整的设计过程,从开题报告到中期检查,再到最后的终期检查,这样一个完整过程的经历,无论是对大四的毕业设计,还是对以后的工作学习都有很大的帮助。设计过程中,开始我认为很简单,但实际做起来遇到了各种各样的问题,最大的问题就是DS18B20序列号的读取,这是多点测温和单点测温的最大的不同,单点测温大多跳过了DS18B20序列号的读取,而多点测温正是利用序列号的不同实现一线多点测温。在查阅大量资料,仔细研究DS18B20的特性的基础上,最终完成了设计要求,并实现了一些拓展功能。但未能实现绘制温度变化曲线,原因是LED1602为字符型液晶,无法完成图形的绘制,以后可利用图形型液晶如12864代替进行后续研究。本次课程设计不仅仅是完成设计的要求,更重要的是对于我的综合能力的锻炼,从硬件电路的设计、焊接,到软件的编写、调试,期间遇到的各种问题的解决,资料的研究与查找,软件的学习与应用,这些让我更加具有了系统工程意识,也锻炼了我面对问题、解决问题的能力,感谢学院和老师开设这门课程,也感谢老师的指导。课程设计元器件表(附录1)课程设计检查表(附录2)附录3:系统源程序读取序列号程序#include<reg52.h>#defineucharunsignedchar#defineuintunsignedintsbitDS=P2^3;//根据实实际情况设定DS18B20端口ucharcodetable[]={"0123456789ABCDEF"};//用于1602显示ucharsn[8];//4个器件的序列号,先读出单个序列号后填上才可以读取温度/************1602部分******************/sbitrs=P2^0;sbitrw=P2^1;sbitlcden=P2^2;voiddelay1602(uintz){uintx,y;for(x=z;x>0;x--)for(y=110;y>0;y--);}voidwrite_com(ucharcom)//写命令{rs=0;lcden=0;P0=com;delay1602(5);lcden=1;delay1602(5);lcden=0;}voidwrite_date(uchardate)//写数据{rs=1;lcden=0;P0=date;delay1602(5);lcden=1;delay1602(5);lcden=0;}voidinit_lcd()//初始化{lcden=0;rw=0;write_com(0x38);write_com(0x0c);write_com(0x06);write_com(0x01);write_com(0x80);}/*************DS18B20部分****************/voiddelayb(uintcount)//延时{uinti;while(count){i=200;while(i>0)i--;count--;}}voiddsreset()//DS18B20初始化{uinti;DS=0;i=103;while(i>0)i--;DS=1;i=4;while(i>0)i--;}bitreadbit()//读一位{uinti;bitdat;DS=0;i++;//小延时一下DS=1;i++;i++;dat=DS;i=8;while(i>0)i--;return(dat);}ucharreadbyte()//读一个字节{uchari,j,dat;dat=0;for(i=1;i<=8;i++){j=readbit();dat=(j<<7)|(dat>>1);//读出的数据最低位在最前面,这样刚好一个字节在DAT里}return(dat);//将一个字节数据返回}voidwritebyte(uchardat)//写一个字节到DS18B20里{uinti;ucharj;bittestb;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++;}}}voidrom()//读取序列号{uchari;dsreset();//复位delayb(1);//延时writebyte(0x33);//发送读序列号子程序for(i=0;i<8;i++)//因为是8个字节,所以要读取8次{sn[i]=readbyte();//读取序列号}}/************主程序及显示部分*************/main(){uchari,c,l,h;init_lcd();//初始化1602while(1){rom();//调用读序列号子程序delayb(100);//如果是不断地读取的话可以不延时for(i=0;i<8;i++)//因为是8个字节,所以要循环8次,每次显示一个字节{l=(sn[i]&0xf0)>>4;//获取低四位h=sn[i]&0x0f;//获取高四位write_com(0x80+c);//显示位置write_date(table[l]);//显示低四位的16进制码write_date(table[h]);//显示高四位的16进制码c++;c++;//每显示一个字节,显示位置右移两位}while(1);}}多点测温程序#include<reg52.h>#include<intrins.h>#include<absacc.h>#defineucharunsignedchar#defineuintunsignedint#defineBUSY0x80//lcd忙检测标志#defineDATAPORTP0//定义P0口为LCD通讯端口sbitWRITE_ALARM=P1^1;//分+sbitGREEN_ALARM=P1^2;//分-sbitspeaker=P2^4;//接蜂鸣器sbitLCM_RS=P2^0;//数据/命令端sbitLCM_RW=P2^1;//读/写选择端sbitLCM_EN=P2^2;//LCD使能信号sbitad_busy=P3^2;//adc中断方式接口sbitDQ=P2^3;ucharcodetabnum1[]={0x28,0x62,0x2C,0x43,0x04,0x00,0x00,0x9C};ucharcodetabnum2[]={0x28,0x83,0x61,0x43,0x04,0x00,0x00,0x87};ucharcodetable[8]={0x0c,0x12,0x12,0x0c,0x00,0x00,0x00,0x00};//摄氏温度符号uchardata*p;uchardata*q;uchardatadisdata1[6];uchardatadisdata2[6];ucharpress=0;//定义并初始化记录切换温度计按钮按下的次数ucharad_data;//ad采样值存储ucharseconde=0;//定义并初始化时钟变量ucharminite=0;ucharhour=12;ucharmstcnt=0;uinttvalue;//温度显示变量uchartflag,flagdat,t,hh1;ucharK;uchart,set;bitON_OFF=0;bitoutflag;ucharcodestr0[]={"---::---"};ucharcodestr1[]={"CC"};voiddelay_LCM(uint);//LCD延时子程序voidinitLCM(void);//LCD初始化子程序voidlcd_wait(void);//LCD检测忙子程序voidwr_new();voidWriteCommandLCM(ucharWCLCM,ucharBusyC);//写指令到LCD子函数voidWriteDataLCM(ucharWDLCM);//写数据到LCD子函数voidDisplayOneChar(ucharX,ucharY,ucharDData);//显示指定坐标的一个字符子函数voidDisplayListChar(ucharX,ucharY,ucharcode*DData);//显示指定坐标的一串字符子函数voidinit_timer0(void);//定时器初始始化voiddisplayfun1(void);voiddisplayfun2(void);voiddisplayfun3(void);voiddisplayfun4(void);voidkeyscan(void);//键盘扫描子程序voidset_adj(void);voidinc_key(void);voiddec_key(void);voiddelay_18B20(unsignedinti);voidb20_Matchrom(uchara);voidInit_DS18B20(void);ucharReadOneChar(void);voidWriteOneChar(unsignedchardat);ReadTemperature(ucharz);voidad0809(void);voidplayalarm(void);/******延时K*1ms,12.000mhz********/voiddelay_LCM(uintk){uinti,j;for(i=0;i<k;i++){for(j=0;j<60;j++){;}}}/*****写指令到LCD子函数*********/voidWriteCommandLCM(ucharWCLCM,ucharBusyC){if(BusyC)lcd_wait();DATAPORT=WCLCM;LCM_RS=0;//选中指令寄存器LCM_RW=0;//写模式LCM_EN=1;_nop_();_nop_();_nop_();LCM_EN=0;}/****写数据到LCD子函数****/voidWriteDataLCM(ucharWDLCM){lcd_wait();//检测忙信号DATAPORT=WDLCM;LCM_RS=1;//选中数据寄存器LCM_RW=0;//写模式LCM_EN=1;_nop_();_nop_();_nop_();LCM_EN=0;}/******LCD写新字符*****/voidwr_new()//写新字符{uchari;WriteCommandLCM(0x40,0);for(i=0;i<8;i++){WriteDataLCM(table[i]);}}/******LCD内部等待函数*****/voidlcd_wait(void){DATAPORT=0xff;LCM_EN=1;LCM_RS=0;LCM_RW=1;_nop_();while(DATAPORT&BUSY){LCM_EN=0;_nop_();_nop_();LCM_EN=1;_nop_();_nop_();}LCM_EN=0;}/*******LCD初始化子函数*******/voidinitLCM(){DATAPORT=0;delay_LCM(15);WriteCommandLCM(0x38,0);//三次显示模式设置,不检测忙信号delay_LCM(5);WriteCommandLCM(0x38,0);delay_LCM(5);WriteCommandLCM(0x38,0);delay_LCM(5); wr_new();WriteCommandLCM(0x38,1);//8bit数据传送,2行显示,5*7字型,检测忙信号WriteCommandLCM(0x08,1);//关闭显示,检测忙信号WriteCommandLCM(0x01,1);//清屏,检测忙信号WriteCommandLCM(0x06,1);//显示光标右移设置,检测忙信号WriteCommandLCM(0x0c,1);//显示屏打开,光标不显示,不闪烁,检测忙信号}/*显示指定坐标的一个字符子函数*/voidDisplayOneChar(ucharX,ucharY,ucharDData){Y&=1;X&=15;if(Y)X|=0x40;//若y为1(显示第二行),地址码+0X40X|=0x80;//指令码为地址码+0X80WriteCommandLCM(X,0);WriteDataLCM(DData);}/*显示指定坐标的一串字符子函数*/voidDisplayListChar(ucharX,ucharY,ucharcode*DData){ucharListLength=0;Y&=0x01;X&=0x0f;while(X<16){DisplayOneChar(X,Y,DData[ListLength]);ListLength++;X++;}}/*ds18b20延迟子函数(晶振12MHz)*/voiddelay_18B20(uinti){while(i--);}/*ds18b20初始化函数*/voidInit_DS18B20(){ucharx=0;DQ=1;//DQ复位delay_18B20(8);//稍做延时DQ=0;//单片机将DQ拉低delay_18B20(80);//精确延时大于480usDQ=1;//拉高总线delay_18B20(14);delay_18B20(20);}/***********ds18b20读一位********/bitreadbit()//读一位{uinti;bitdat;DQ=0;i++;//小延时一下DQ=1;i++;i++;dat=DQ;i=8;while(i>0)i--;return(dat);}/***********ds18b20读一个字节********/unsignedcharReadOneChar(void){uchari=0;uchardat=0;for(i=8;i>0;i--){DQ=0;//给脉冲信号dat>>=1;DQ=1;//给脉冲信号if(DQ)dat|=0x80;delay_18B20(4);}return(dat);}/****ds18b20写一个字节*******/voidWriteOneChar(uchardat){unsignedchari=0;for(i=8;i>0;i--){DQ=0;DQ=dat&0x01;delay_18B20(5);DQ=1;dat>>=1;}}/****匹配18b20ROM***/voidb20_Matchrom(uchara)//匹配ROM{charj;WriteOneChar(0x55);//发送匹配ROM命令if(a==1){for(j=0;j<8;j++)WriteOneChar(tabnum1[j]);//发送18B20的序列号,先发送低字节}if(a==2){for(j=0;j<8;j++)WriteOneChar(tabnum2[j]);//发送18B20的序列号,先发送低字节}}/****读取ds18b20当前温度****/ReadTemperature(ucharz){unsignedchara,b;floattt;ucharHtemp=40,Ltemp=10;Init_DS18B20();WriteOneChar(0xcc);Init_DS18B20();if(z==1){b20_Matchrom(1);//匹配ROM1}if(z==2){b20_Matchrom(2);//匹配ROM2}WriteOneChar(0x44);//启动温度转换delay_18B20(100);Init_DS18B20();WriteOneChar(0xcc);Init_DS18B20();if(z==1){b20_Matchrom(1);//匹配ROM1}if(z==2){b20_Matchrom(2);//匹配ROM2}WriteOneChar(0xBE);//读取温度寄存器等(共可读9个寄存器)前两个就是温度delay_18B20(100);a=ReadOneChar();//读取温度值低位b=ReadOneChar();//读取温度值高位tvalue=b;tvalue<<=8;tvalue=tvalue|a;if(tvalue<0x0fff)tflag=0;else{tvalue=~tvalue+1;tflag=1;}tt=tvalue*0.0625;if(tt>Htemp||tt<Ltemp)speaker=0;elsespeaker=1;tvalue=tt*10;return(tvalue);}/*****************显示函数******************************/ds1820disp_1(uchar*p)//温度值显示{ucharflagdat; uinttva1; tva1=ReadTemperature(1);p=&disdata1[0];*(p+1)=tva1/1000+0x30;//百位数*(p+2)=tva1%1000/100+0x30;//十位数*(p+3)=tva1%100/10+0x30;//个位数*(p+5)=tva1%10+0x30;//小数位*(p+4)=0x2e;if(tflag==0){flagdat=0x20;//正温度不显示符号*p=flagdat;}else{flagdat=0x2d;//负温度显示负号:-*p=flagdat;}if(*(p+1)==0x30){*(p+1)=0x20;//如果百位为0,不显示if(*(p+2)==0x30){*(p+2)=0x20;//如果百位为0,十位为0也不显示}}}ds1820disp_2(uchar*q)//温度值显示{ucharflagdat;uinttva2; tva2=ReadTemperature(2);q=&disdata2[0];*(q+1)=tva2/1000+0x30;//百位数*(q+2)=tva2%1000/100+0x30;//十位数*(q+3)=tva2%100/10+0x30;//个位数*(q+5)=tva2%10+0x30;//小数位*(q+4)=0x2e;if(tflag==0){flagdat=0x20;//正温度不显示符号*q=flagdat;}else{flagdat=0x2d;//负温度显示负号:-*q=flagdat;}if(*(q+1)==0x30){*(q+1)=0x20;//如果百位为0,不显示if(*(q+2)==0x30){*(q+2)=0x20;//如果百位为0,十位为0也不显示}}}/***液晶显示子函数1正常显示***/voiddisplayfun1(void){uchardata*p1,*q1;WriteCommandLCM(0x0c,1);//显示屏打开,光标不显示,不闪烁,检测忙信号DisplayListChar(0,0,str0);DisplayListChar(0,1,str1);DisplayOneChar(3,0,hour/10+0x30);//液晶上显示小时DisplayOneChar(4,0,hour%10+0x30);DisplayOneChar(6,0,minite/10+0x30);//液晶上显示分DisplayOneChar(7,0,minite%10+0x30);DisplayOneChar(9,0,seconde/10+0x30);//液晶上显示秒DisplayOneChar(10,0,seconde%10+0x30);ds1820disp_1(p1);DisplayOneChar(1,1,disdata1[0]);DisplayOneChar(2,1,disdata1[1]);DisplayOneChar(3,1,disdata1[2]);DisplayOneChar(4,1,disdata1[3]);DisplayOneChar(5,1,disdata1[4]);DisplayOneChar(6,1,disdata1[5]);ds1820disp_2(q1);DisplayOneChar(9,1,disdata2[0]);DisplayOneChar(10,1,disdata2[1]);DisplayOneChar(11,1,disdata2[2]);DisplayOneChar(12,1,disdata2[3]);DisplayOneChar(13,1,disdata2[4]);DisplayOneChar(14,1,disdata2[5]);}/***液晶显示子函数2******/voiddisplayfun2(void){uchardata*p1,*q1;WriteCommandLCM(0x0c,1);//显示屏打开,光标不显示,不闪烁,检测忙信号DisplayListChar(0,0,str0);DisplayListChar(0,1,str1);DisplayOneChar(6,0,minite/10+0x30);DisplayOneChar(7,0,minite%10+0x30);DisplayOneChar(9,0,seconde/10+0x30);DisplayOneChar(10,0,seconde%10+0x30);ds1820disp_1(p1);DisplayOneChar(1,1,disdata1[0]);DisplayOneChar(2,1,disdata1[1]);DisplayOneChar(3,1,disdata1[2]);DisplayOneChar(4,1,disdata1[3]);DisplayOneChar(5,1,disdata1[4]);DisplayOneChar(6,1,disdata1[5]);ds1820disp_2(q1);DisplayOneChar(9,1,disdata2[0]);DisplayOneChar(10,1,disdata2[1]);DisplayOneChar(11,1,disdata2[2]);DisplayOneChar(12,1,disdata2[3]);DisplayOneChar(13,1,disdata2[4]);DisplayOneChar(14,1,disdata2[5]);WriteCommandLCM(0x0f,1);//显示屏打开,光标显示,闪烁,检测忙信号DisplayOneChar(3,0,hour/10+0x30);DisplayOneChar(4,0,hour%10+0x30);}/****液晶显示子函数3******/voiddisplayfun3(void){uchardata*p1,*q1;WriteCommandLCM(0x0c,1);//显示屏打开,光标不显示,不闪烁,检测忙信号DisplayListChar(0,0,str0);DisplayListChar(0,1,str1);DisplayOneChar(3,0,hour/10+0x30);DisplayOneChar(4,0,hour%10+0x30);DisplayOneChar(9,0,seconde/10+0x30);DisplayOneChar(10,0,seconde%10+0x30);ds1820disp_1(p1);DisplayOneChar(1,1,disdata1[0]);DisplayOneChar(2,1,disdata1[1]);DisplayOneChar(3,1,disdata1[2]);DisplayOneChar(4,1,disdata1[3]);DisplayOneChar(5,1,disdata1[4]);DisplayOneChar(6,1,disdata1[5]);ds1820disp_2(q1);DisplayOneChar(9,1,disdata2[0]);DisplayOneChar(10,1,disdata2[1]);DisplayOneChar(11,1,disdata2[2]);DisplayOneChar(12,1,disdata2[3]);DisplayOneChar(13,1,disdata2[4]);DisplayOneChar(14,1,disdata2[5]);WriteCommandLCM(0x0f,1);//显示屏打开,光标显示,闪烁,检测忙信号DisplayOneChar(6,0,minite/10+0x30);DisplayOneChar(7,0,minite%10+0x30);}/********键盘扫描子函数*******/voidkeyscan(void){ucharxx;//局部变量P1=0xff;if(P1!=0xff){delay_LCM(50);if(P1!=0xff){xx=P1;switch(xx)//根据按键状态,调用不同的子函数{case0xfe:set_adj();break;case0xfd:inc_key();break;case0xfb:dec_key();break;case0xf7:ON_OFF=!ON_OFF;break;default:break;}}}}/*******设定工作模式子函数********/voidset_adj(void){delay_LCM(100);set++;if(set>=3)set=0;}/********按键加法子函数***********/voidinc_key(void){delay_LCM(100);switch(set){case0:if(P1==0xf7)ON_OFF=!ON_OFF;break;case1:hour++;if(hour>=23)hour=23;break;case2:minite++;if(minite>=59)minite=59;break;case3:K++;if(K>=99)K=99;break;default:break;}}/********按键减法子函数*********/voiddec_key(void){delay_LCM(100);switch(set){case0:if(P1==0xf7)ON_OFF=!ON_OFF;break;case1:hour--;if(hour<=0)hour=0;break;case2:minite--;if(minite<=0)minite=0;break;case3:K--;if(K<=1)K=1;break;default:break;}}/********定时器t0初始化**********/voidinit_timer0(void){TMOD=0x01;//time0为定时器,方式1TH0=0x3c;//预置计数初值TL0=0xb0;EA=1;ET0=1;TR0=1;}/*****定时器t0中断子函数*******/voidtimer0(void)interrupt1using0//定时器0方式1,50ms中断一次{TH0=0x3c;TL0=0xb0;mstcnt++;if(mstcnt>=20){seconde++;mstcnt=0;}if(seconde>=60){minite++;seconde=0;}if(minite>=60){hour++;minite=0;}if(hour>=24){hour=0;}keyscan();//按键扫描}/***********主函数*************/voidmain(void){P1=0xff;//初始化p1口,全设为1delay_LCM(500);//延时500ms启动initLCM();//LCD初始化init_timer0();//时钟定时器0初始化Init_DS18B20();DisplayListChar(0,0,str0);DisplayListChar(0,1,str1);while(1){keyscan();//按键扫描switch(set)//LCD根据工作模式显示{keyscan();//按键扫描case0:displayfun1();delay_LCM(1000);break;//正常工作显示case1:displayfun2();delay_LCM(1000);break;//调整时显示case2:displayfun3();delay_LCM(1000);break;//调整分显示default:break;}delay_18B20(1000);}}基于C8051F单片机直流电动机反馈控制系统的设计与研究基于单片机的嵌入式Web服务器的研究MOTOROLA单片机MC68HC(8)05PV8/A内嵌EEPROM的工艺和制程方法及对良率的影响研究基于模糊控制的电阻钎焊单片机温度控制系统的研制基于MCS-51系列单片机的通用控制模块的研究基于单片机实现的供暖系统最佳启停自校正(STR)调节器单片机控制的二级倒立摆系统的研究基于增强型51系列单片机的TCP/IP协议栈的实现基于单片机的蓄电池自动监测系统基于32位嵌入式单片机系统的图像采集与处理技术的研究基于单片机的作物营养诊断专家系统的研究基于单片机的交流伺服电机运动控制系统研究与开发基于单片机的泵管内壁硬度测试仪的研制基于单片机的自动找平控制系统研究基于C8051F040单片机的嵌入式系统开发基于单片机的液压动力系统状态监测仪开发模糊Smith智能控制方法的研究及其单片机实现一种基于单片机的轴快流CO〈,2〉激光器的手持控制面板的研制基于双单片机冲床数控系统的研究基于CYGNAL单片机的在线间歇式浊度仪的研制基于单片机的喷油泵试验台控制器的研制基于单片机的软起动器的研究和设计基于单片机控制的高速快走丝电火花线切割机床短循环走丝方式研究基于单片机的机电产品控制系统开发HYPERLINK"/de
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 儿童甲亢甲减及糖尿病诊断及治疗
- 2025年娄底市辅警招聘考试题库附答案解析
- 2025年甘孜藏族自治州雅江县辅警招聘考试题库附答案解析
- 2025年定西市岷县辅警招聘考试题库附答案解析
- 2025年丹东市东港市辅警招聘考试题库附答案解析
- 2025年包头市东河区辅警招聘考试题库附答案解析
- 仿生瓣膜结构设计-洞察与解读
- 无人机实时动监测-洞察与解读
- 并购财务效应分析-洞察与解读
- 社交媒体对纸品风格的推动-洞察与解读
- 物理因子治疗冲击波疗法
- 2025金沙辅警考试真题
- 药学三基考试试题(带答案)
- 2025年6月黑吉辽蒙高考地理真题完全解读
- 宾馆消防业管理制度
- 传媒策划试题及答案模板
- 测量实训室管理制度
- 煤矿工人井下封闭心理建设
- 国家职业标准-电力电气设备安装工 (试行) (2024 年版)
- 公司质量红线管理制度
- 2025年反洗钱测试题
评论
0/150
提交评论