(整理)多路温度检测及报警系统单片机课程设计

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

.................
辽东学院信息技术学院
微控制器原理与接口技术课程设计报告
设计题目:多路温度检测及报警系统
专业班级:电子信息工程、B1006
姓名:田洪雨
教师评语:
成绩评阅教师张俊芳日期
一、摘要
本课程设计是基于DS18B20在LCD1602液晶显示的多路温度检测及报警系统。

本课题以AT89C51单片机系统为核心,能对多点温度进行实时巡检。

DS18B20是一种可组网的高精度数字式温度传感器,由于其具有单总线的独特优点,可以使用户轻松的组建起传感器网络,并可使多点温度测量电路变得简单、可靠。

本文结合实际使用经验,介绍了DS18B20温度传感器在单片机下的硬件连接及软件编程,并给出了软件流程图。

关键词:DS18B20、LCD1602、高低温报警
二、课程设计目的
通过《单片机原理与应用》课程设计,使学生掌握单片机及其扩展系统设计的方法和设计原则及相应的硬件调试的方法。

进一步加深单片机及其扩展系统设计和应用的理解。

三、课程设计题目
多路温度检测及报警系统
四、课程设计内容及要求
1、设计内容:
1)有上电指示灯;
2)能正确手动复位;
3)有4位数码管显示,能按照分秒进制显示时间;
4)自定义的扩展功能。

2、设计要求:
1)独立设计原理图及相应的硬件电路。

2)针对选择的设计题目,设计系统软件。

软件要做到:操作方便,实用性强,稳定可靠。

3)设计说明书格式规范,层次合理,重点突出。

并附上设计原理图及相应的源程序。

五、系统硬件电路设计
系统主要由硬件和软件两大部分构成,当接收到系统发出的温度转换命令后, DS18B20开始进行温度转换操作并把转化后的结果放到16 位暂存寄存器中的温度寄存器内,然后与系统进行数据通信,系统将温度读出并驱动LED 数码管显示。

如果温度值低于设定下限值或高于设定上限值,则自动启动报警装置。

由于DS18B20 单总线通信功能是分时完成的,它有严格的时隙概念,因此
读写时序很重要。

该系统结构图
1、单片机最小系统电路设计
AT89S51 是低电压,高性能 CMOS 8
位单片机,片内含 8k
bytes 的可反复擦写的
Flash 只读程序存储器和
256 bytes
的随机存取数据存储器(RAM ),器件采用高密度、非易失性存储技术生产,与标准 MCS-51 指令系统及8052产品引脚兼容,片内置通用8位中央处理器(CPU )和 Flash 存储单元,功能强大 AT89S51单片机适合于许多较为复杂控制应用场合。

AT89S51单片机为40引脚双列直插芯片,有四个I/O 口P0、P1、P2、P3,每一条I/O 线都能独立地作输出或输入。

AT89S51 DIP 管脚封装
单 片 机 AT89S51
按键电路
复位电路
报警电路
显示电路
测温电路
AT89S51其结构图如图所示
(1)一个8位微处理器CPU
(2)片内数据存储器RAM和特殊功能寄存器SFR
(3)片内程序存储器ROM
(4)两个定时/计数器T0、T1,可用作定时器,也可用以对外部脉冲进行计数(5)四个8位可编程的并行I/O端口,每个端口既可作输入,也可作输出(6)一个串行端口,用于数据的串行通信
(7)中断控制系统
(8)内部时钟电路
功能特性概述:AT89S51 提供以下标准功能:8k字节 Flash 闪速存储器,256字节内部 RAM,32 个 I/O 口线,3 个 16 位定时/计数器,一个 6 向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟电路。

同时,AT89S52 可降至 0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。

空闲方式停止 CPU 的工作,但允许 RAM,定时/计数器,串行通信口及中断系统继续工作。

掉电方式保存 RAM 中的内容,但振荡器停止工作并禁止其它所有部件工作直到下一个硬件复位。

单片机AT89S52的P0口作为输入口。

P0与DS12887的AD相连,进行时间图2-3数据的采集;P3.7(RD)与DS12887的17脚DS相连,P3.3与DS12887的19脚IRQ相连,P2.7与DS12887的13脚CS相连;30脚ALE与DS12887的14脚AS相连。

单片机的第18引脚和19引脚接时钟电路,XTAL1接外部晶振和微调电容的一端,XTAL2接外部晶振和微调电容的另一端。

对外接电容的值虽然没
图2-4 主控电路及其最小系统电路图
有严格的要求,但电容的大小会影响震荡器频率的高低、震荡器的稳定性、起振的快速性和温度的稳定性。

因此,此系统电路的晶体振荡器的值为11.0592MHz,电容应尽可能的选择陶瓷电容,电容值约为22μF。

第9引脚为复位输入端,接上电容,电阻后构成上电复位电路。

20引脚为接地端,40引脚为电源端。

/EA 端(31引脚)接+5V电压。

由此就构成了单片机主控模块的最小系统,如图2-4
所示。

2、DS18B20电路设计
DSl820数字温度计是美国Dallas公司生产的数字温度计,它提供9位(二进制)温度读数,指示器件的温度。

信息经过单线接口送入DSl8B20或从DSl8B20送出,因此从主机CPU到DSl8B20仅需一条线。

DSl820的电源可以由数据线本身提供而不需要外部电源。

因为每一个DSl820在出厂时已经给定了唯一的序号,因此任意多DSl820可以存放在同一条单线总线上。

这允许在许多不同的地方放置温度敏感器件。

DSl820的测量范围从-55到+125,增量值为0.5,可在l s(典型值)内把温度变换成数字。

每一个DSl820包括一个唯一的64位长的序号,该
序号值存放在DSl820内部的ROM(只读存贮器)中。

开始8位是产品类型编码(DSl820编码均为10H)。

接着的48位是每个器件唯一的序号,最后8位是前面56位的CRC(循环冗余校验)码。

以下是DS18b20的内部结构图。

DS18B20有4个主要的数据部件:
① 64位激光ROM。

64位激光ROM从高位到低位依次为8位CRC、48位序列号和8位家族代码(28H)组成。

②温度灵敏元件。

③非易失性温度报警触发器TH和TL。

可通过软件写入用户报警上下限值。

④配置寄存器。

配置寄存器为高速暂存存储器中的第五个字节。

DS18B20在0工作时按此寄存器中的分辨率将温度转换成相应精度的数值
DS18B20的测温范围为-55℃~+125℃,在-10℃~+85℃范围内,精度为±0.5℃。

在电压低于3.4v时精度误差较大。

在本系统中使用了两个DS18b20温度传感器,测温范围为0℃~100℃,另外根据器件稳定工作的特点,考虑到驱动能力的不足,采用外加5V电源以满足传感器精度高的要求。

本系统为多点温度测试。

DS18B20采用外部供电方式,理论上可以在一根数据总线上挂256个DS18B20,但实际应用中发现,如果挂接20个以上的DS18B20就会产生功耗问题。

另外单总线长度也不宜超过0.5M,否则会影响到数据的传输。

在这种情况下我们可以采用分组的方式,用单片机的多个I/O来驱动多路DS18B20。

在实际应用中还可以使用一个MOSFET将I/O口线直接和电源相连,起到上拉的作用。

在本电路板的设计中考虑到初步实践的准确性,暂使用2个DS18B20连接单片机的P3.2口。

对DS18B20的设计,需要注意以下问题
(1)对硬件结构简单的单线数字温度传感器DS18B20 进行操作,需要用较为复杂的程序完成。

编制程序时必须严格按芯片数据手册提供的有关操作顺序进行,读、写时间片程序要严格按要求编写。

尤其在使用DS18B20 的高测温分辨力时,对时序及电气特性参数要求更高。

(2)有多个测温点时,应考虑系统能实现传感器出错自动指示,进行自动DS18B20 序列号和自动排序,以减少调试和维护工作量。

(3)测温电缆线建议采用屏蔽4 芯双绞线,其中一对线接地线与信号线,另一组接VCC和地线,屏蔽层在源端单点接地。

DS18B20 在三线制应用时,应将其三线焊接牢固;在两线应用时,应将VCC与GND接在一起,焊接牢固。

若VCC脱开未接,传感器只送85.0 ℃的温度值。

(4)实际应用时,要注意单线的驱动能力,不能挂接过多的DS18B20,同时还应注意最远接线距离。

另外还应根据实际情况选择其接线拓扑结构。

3、LCD1602电路设计
由于液晶显示器每一个点在收到信号后就一直保持那种色彩和亮度,恒定发光,而不像阴极射线管显示器(CRT)那样需要不断刷新新亮点。

因此,液晶显示器画质高且不会闪烁。

数字式接口液晶显示器都是数字式的,和单片机系统的接口更加简单可靠,操作更加方便。

体积小、重量轻液晶显示器通过显示屏上的电极控制液晶分子状态来达到显示的目的,在重量上比相同显示面积的传统显示器要轻得多。

功耗低相对而言,液晶显示器的功耗主要消耗在其内部的电极和驱动IC上,因而耗电量比其它显示器要少得多。

LCD1602的实物图如图4,主要参数如下:
·显示容量:16×2个字符
·芯片工作电压:4.5—5.5V
·工作电流:2.0mA(5.0V)
·模块最佳工作电压:5.0V
·字符尺寸:2.95×4.35(W×H)mm
1602液晶显示采用标准的16脚接口,其中:(模块背面有标注)
第1脚:VSS为地电源
第2脚:VDD接5V正电源
第3脚:V0为液晶显示器对比度调整端,接正电源时对比度最弱,接地电源时对比度最高,对比度过高时会产生“鬼影”,使用时可以通过一个10K的电位器调整对比度
第4脚:RS为寄存器选择,高电平时选择数据寄存器、低电平时选择指令寄存器。

第5脚:RW为读写信号线,高电平时进行读操作,低电平时进行写操作。

当RS和RW共同为低电平时可以写入指令或者显示地址;当RS为高电平、RW 为低电平时可以写入数据。

第6脚:E端为使能端,当E端由高电平跳变成低电平时,液晶模块执行命令。

第7~14脚:D0~D7为8位双向数据线。

第15~16脚:空脚
1602液晶模块内部的字符发生存储器(CGROM)已经存储了不同的点阵字符图形,这些字符有,阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码,其中数字与字母同ASCII码兼容。

它的读写操作、屏幕和光标的操作都是通过指令编程来实现的。

(说明: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的点阵字符(有些模块是DL:
高电平时为8位总线,低电平时为4位总线)
指令7:字符发生器RAM地址设置指令8:DDRAM地址设置
指令9:读忙信号和光标地址BF:为忙标志位,高电平表示忙,此时模块不能接收命令或者数据,如果为低电平表示不忙。

指令10:写数据
指令11:读数据
指令表:
序号指令RS RW D7 D6 D5 D4 D3 D2 D1 D0
1 清屏0 0 0 0 0 0 0 0 0 1
2 光标返回0 0 0 0 0 0 0 0 1 *
3 输入模式0 0 0 0 0 0 0 1 I/D S
4 显示控制0 0 0 0 0 0 1 D C B
5 光标/字符移位0 0 0 0 0 1 S/C R/L * *
6 功能0 0 0 0 1 DL N F * *
7 置字符
0 0 0 1 字符发生存贮器地址
发生器地址
0 0 1 显示数据存贮器地址
8 置数据
存贮器地址
0 1 BF 计数器地址
9 读忙标志
和地址
10 写数据到指令
1 0 要写的数据
7.8所设地址
1 1 读出的
11 从指令7.8所设
的地址读数据
六、系统软件设计
软件是系统的主要组成部分,也是整个调试的重点和难点工作。

本系统的软件由C语言编写,程序的主要功能是负责温度的实时显示、读出并处理DS18B20的测量的当前温度值。

开始
执行初始化时序
发出跳过ROM
匹配命令
启动温度转换
延时750mS等待
温度转换完成
执行初始化时序
发出匹配
ROM命令
1
CRC 校练
正确?
温度数据格式转换
结束
读取便笺存储器内
容并进行CRC 校练
发出读便笺
存储器命令
发出64位序列号
1
N
Y
七、实验结果
当温度小于10度或者高于60度时,报警灯亮。

八、心得体会
本次课程设计再一次的加深了我们对控制理论与单片机控制技术的理解,锻炼了我们的实践能力。

在本次课程设计以前,我一直认为我已经把单片机学懂了,谁知道到了课程设计的时候才发现原来并不是那么一回事,学海无涯,我也终于对这句话有了更深刻的认识。

通过两周的单片机综合课程设计,我巩固了以前学的知识,并学了些新的东西,做课设之前我们找了很多的资料,仔细研究了所需器件的说明书,通过看说明书我知道了各个部件的连线,主要是串口通信的研究,以前我们做系统都是由单机组成的,这种只能是很小的系统,大系统为了实现其功能常常需要多机通信。

从做这次课设,我收获还是很多的,要问从这次课设学到什么,那就是持之以恒,无论遇到多大的难题都要想办法去解决。

而且任何难题都有解决的办法,只要你坚持不懈,努力探索,终会找到。

通过这次课设,我们学到的不仅是理论知识,并且学到了很多的生活知识,每天我都在付出没有浪费这三周的时间,付出才有收获,当我们成功时内心很高兴。

我们只有把所学的理论知识与实践相结合起来,从理论中得出结论,才能提高自己的实际动手能力和独立思考的能力。

在设计的过程中遇到问题,可以说得是困难重重,这毕竟第一次做多机通信,难免会遇到过各种各样的问题,同时在设计的过程中发现了自己的不足之处,对以前所学过的知识理解得不够深刻,掌握得不够牢固,通过这次课程设计之后,一定把以前所学过的知识重新温故。

这次课程设计终于顺利完成了,在此要感谢胡老师对我们悉心的指导与帮助。

在设计过程中,我通过查阅大量有关资料,与同学交流经验和自学,并上网查找等方式,使自己学到了不少知识,也经历了不少艰辛,但收获同样巨大。

在整个设计中我懂得了许多东西,也培养了我独立工作的能力。

相信会对今后的学习工作生活有非常重要的影响。

而且大大提高了缜密思考的能力,使我充分体会到了在创造过程中探索的艰难和成功时的喜悦。

虽然这个设计做的也不太好,但是在设计过程中所学到的东西是这次课程设计的最大收获和财富,使我受益颇多。

附录A:电路原理图
附录B:程序清单
#include<reg51.h>
#include<intrins.h>
#define uint unsigned int
#define uchar unsigned char
#define data 1000
#define lcd_date P0
sbit lcd_en=P2^2;
sbit lcd_rw=P2^1;
sbit lcd_rs=P2^0;
sbit key0=P1^0;
sbit key1=P1^1;
sbit led=P1^7;
uchar code lcdtable[]={"0123456789- "};
uchar code error[12]={"no facility"};
uchar rom_id[3][8]={ {0x28,0xc4,0x14,0x11,0x00,0x00,0x00,0x89},
{0x28,0xc4,0x14,0x10,0x00,0x00,0x00,0x06}}; uchar dispbuf[8];
uchar dispbuf1[8];
uint data1=50000;
uchar tem1,tem2,temt1,temt2;
uint temper1;//温度寄存器
uint temper11;
uint temper22;
uint temper2;
uint tempert1;//温度阀值R-min
uint tempert2;//温度阀值R-max
uint tempert11;
uint tempert22;
#define NOP3() _nop_();_nop_();_nop_()
sbit DQ=P3^3;
bit flag_init; //DS18B20是否存在标志
void delay_us(unsigned int tt)
{
while(tt--)
{
;
}
}
void delay_ms(unsigned int tms) {
unsigned char i;
while(tms--)
for(i=123;i>0;i--)
;
}
void Write_com(uchar com)
{
lcd_rs=0;
lcd_rw=0;
lcd_date=com;
delay_ms(2);
lcd_en=1;
delay_ms(2);
lcd_en=0;
}
void Write_dat(uchar dat)
{
lcd_rs=1;
lcd_rw=0;
lcd_date=dat;
delay_ms(2);
lcd_en=1;
delay_ms(2);
lcd_en=0;
}
void lcd_init()
{
lcd_rw=0;
lcd_en=0;
delay_ms(15);
Write_com(0x38);
delay_ms(5);
Write_com(0x38);
delay_ms(5);
Write_com(0x38);//显示模式设置Write_com(0x08);//显示关闭
Write_com(0X01);//清屏
Write_com(0x06);//显示光标移动设置
Write_com(0X0c);//显示开及光标设置
}
/****DS18B20初始化**************************************/ void reset()
{
flag_init=1;
EA=0;
DQ=1;
NOP3();
DQ=0;
delay_us(60);//480~960us 556
DQ=1;
delay_us(5);//60us
flag_init=DQ;
delay_us(25);//241us
EA=1;
}
/****写一个字节函数*************************************/ void Write_Byte(uchar dat)
{
uchar i;
DQ=1;
EA=0;
for(i=8;i>0;i--)
{
DQ=0;
DQ=(bit)(dat&0x01);
delay_us(5);//61us
DQ=1;
dat>>=1;
}
EA=1;
}
/*****读数据函数*****************************/
uchar Read_Byte()
{
uchar i,date;
date=0;
DQ=1;
EA=0;//关中断
for(i=8;i>0;i--)
{
DQ=0;
date>>=1;
DQ=1;
NOP3();
if(DQ)
{
date|=0x80;
}
delay_us(5);//61us
}
EA=1;//开中断
return(date);
}
void match_rom(uchar rom_id[])
{
uchar n;
reset();
Write_Byte(0x33);
for(n=0;n<8;n++)
rom_id[n]=Read_Byte();
}
void get_tem()
{
uchar teml,temh;
reset();
Write_Byte(0xcc);
Write_Byte(0x44);//启动温度转换
delay_ms(800);//750ms
match_rom(0);
Write_Byte(0xbe);//读取温度转换结果teml=Read_Byte();
temh=Read_Byte();
temper11=(temh*256+teml);
if(temper11&0x8000)
{
temper1=(~temper11+1)*0.625;
tem1=1;
}
else
{
temper1=(temh*256+teml)*0.625;
tem1=0;
}
}
void get1_tem()
{
uchar teml,temh;
reset();
Write_Byte(0xcc);
Write_Byte(0x44);//启动温度转换
delay_ms(800);//750ms
match_rom(1);
Write_Byte(0xbe);//读取温度转换结果teml=Read_Byte();
temh=Read_Byte();
temper22=(temh*256+teml);
if(temper22&0x8000)
{
temper2=(~temper22+1)*0.625;
tem2=1;
}
else
{
temper2=(temh*256+teml)*0.625;
tem2=0;
}
}
update()
{
if(tem1)
{
dispbuf[0]=10;
if(temper1/100)
dispbuf[1]=temper1/100;
else
dispbuf[1]=11;
dispbuf[2]=temper1%100/10;
dispbuf[3]=temper1%10;
}
else
{
if(temper1/1000)
{
dispbuf[0]=temper1/1000;
dispbuf[1]=temper1%1000/100;
}
else
{
dispbuf[0]=11;
if(temper1/100)
dispbuf[1]=temper1/100;
else
dispbuf[1]=11;
}
dispbuf[2]=temper1%100/10;
dispbuf[3]=temper1%10;
}
if(tem2)
{
dispbuf[4]=10;
if(temper2/100)
dispbuf[5]=temper2/100;
else
dispbuf[5]=11;
dispbuf[6]=temper2%100/10;
dispbuf[7]=temper2%10;
}
else
{
if(temper2/1000)
{
dispbuf[4]=temper2/1000;
dispbuf[5]=temper2%1000/100;
}
else
{
dispbuf[4]=11;
if(temper2/100)
dispbuf[5]=temper2/100;
else
dispbuf[5]=11;
}
dispbuf[6]=temper2%100/10;
dispbuf[7]=temper2%10;
}
}
update_1()
{
if(tempert1/1000)
{
dispbuf1[0]=tempert1/1000;
dispbuf1[1]=tempert1%1000/100;
}
else
{
dispbuf1[0]=11;
if(tempert1/100)
dispbuf1[1]=tempert1/100;
else
dispbuf1[1]=11;
}
dispbuf1[2]=tempert1%100/10;
dispbuf1[3]=tempert1%10;
if(tempert2/1000)
{
dispbuf1[4]=tempert2/1000;
dispbuf1[5]=tempert2%1000/100;
}
else
{
dispbuf1[4]=11;
if(tempert2/100)
dispbuf1[5]=tempert2/100;
else
dispbuf1[5]=11;
}
dispbuf1[6]=tempert2%100/10;
dispbuf1[7]=tempert2%10;
}
ds_inti()
{
led=0;
tempert1=100;
tempert2=600;
}
void disp()
{
Write_com(0xc0);
Write_dat('1');
Write_dat(':');
Write_dat(lcdtable[dispbuf[0]]);
Write_dat(lcdtable[dispbuf[1]]);
Write_dat(lcdtable[dispbuf[2]]);
Write_dat('.');
Write_dat(lcdtable[dispbuf[3]]);
Write_com(0xc9);
Write_dat('2');
Write_dat(':');
Write_dat(lcdtable[dispbuf[4]]);
Write_dat(lcdtable[dispbuf[5]]);
Write_dat(lcdtable[dispbuf[6]]);
Write_dat('.');
Write_dat(lcdtable[dispbuf[7]]);
Write_com(0x80);
Write_dat('L');
Write_dat(':');
Write_dat(lcdtable[dispbuf1[0]]);
Write_dat(lcdtable[dispbuf1[1]]);
Write_dat(lcdtable[dispbuf1[2]]);
Write_dat('.');
Write_dat(lcdtable[dispbuf1[3]]);
Write_com(0x89);
Write_dat('H');
Write_dat(':');
Write_dat(lcdtable[dispbuf1[4]]);
Write_dat(lcdtable[dispbuf1[5]]);
Write_dat(lcdtable[dispbuf1[6]]);
Write_dat('.');
Write_dat(lcdtable[dispbuf1[7]]); }
key() interrupt 3
{
TH1=(65536-data1)>>8;
TL1=(65536-data1)%256;
if(key0==0)
{
tempert1+=10;
if(tempert1>1280)
tempert1=0;
while(key0==0);
}
if(key1==0)
{
tempert2-=10;
if(tempert2>1280)
tempert2=1280;
while(key1==0);
}
}
void init_mcu()
{
TMOD=0x01;
TH1=(65536-data1)>>8;
TL1=(65536-data1)%256;
ET1=1;TR1=1;
EA=1;
}
void alarm()
{
if((temper1<tempert1||temper1>tempert2)||(temper2<tempert1||temper 2>tempert2))
{ led=1;}
else
{ led=0;}
}
// 主函数
void main()
{
uchar i;
init_mcu();
ds_inti();
close_led();
lcd_init();
while(1)
{
reset();
if(flag_init)//不存在时
{
Write_com(0x80);
for(i=0;i<12;i++)
{
Write_dat(error[i]);
}
}
else//存在时
{
get_tem();
get1_tem();
update();
update_1();
disp();
alarm();
}
}
}。

相关文档
最新文档