基于单片机的多点温度检测系统设计

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

集成电路课程设计
课题:基于AT89C51单片机的多点温度测量系统设计*名:**
班级:测控12-1
学号: ************
指导老师:***
日期: 2014-11
目录
一、绪论
二、总体方案设计
三、硬件系统设计
1主控制器
2 显示模块
3温度采集模块
(1)DS18B20的内部结构
(2)高速暂存存储器
(3)DS18B20的测温功能及原理
(4)DS18B20温度传感器与单片机的连接
(5)单片机最小系统总体电路图
四、系统软件设计
五、系统仿真
六、设计总结
七、参考文献
八、附源程序代码
一、绪论
在现代工业控制中和智能化仪表中,对于温度的控制,恒温等有较高的要求,如对食品的管理,冰箱的恒温控制,而且现在越来越多的地方用到多点温度测量,比如冰箱的保鲜层和冷冻层是不同的温度这就需要多点的测量和显示可以让用户直观的看到温度值,并根据需要调节冰箱的温。

它还在其他领域有着广泛的应用,如:消防电气的非破坏性温度检测,电力、电讯设备之过热故障预知检测,空调系统的温度检测。

温度检测系统应用十分广阔。

本设计采用DALLAS最新单线数字温度传感器DS18B20 简介新的"一线器件"体积更小、适用电压更宽、更经济DALLAS 半导体公司的数字化温度传感器DS18B20是世界上第一片支持"一线总线",测量温度范围为-55°C~+125°C,在-10~+85°C范围内,精度为±0.5°二、设计过程及工艺要求
1、基本功能
(1)检测两点温度
(2)两秒间隔循环显示温度
2、主要技术参数
测温范围:-30℃到+99℃
测量精度:±0.0625℃
显示精度:±0.1℃
显示方法:LCD循环显示
3、系统设计
系统使用AT89C51单片机对两个DS18B20进行数据采集,并通过1602LCD液晶显示器显示所采集的温度。

DS18B20以单总线协议工作,51单片机首先分别发送复位脉冲,使信号上所有的DS18B20芯片都被复位,程序先跳过ROM,启动DS18B20进行温度变换,再读取存储器的第一位和第二位读取温度,通过I/O口传到1602LCD显示。

1 2 3
图(1)DS18B20引脚图
引脚定义如图(1):
(1) GND为电源地;
(2) DQ为数字信号输入/输出端;
(3) Vcc为外接供电电源输入端(在寄生电源接线方式时接地)。

4、设计原理框图
图(2)原理框图
三、硬件设计
1、主控制器(单片机)
基于设计的要求要使用AT89C51单片机作为本系统设计的核心器件。

由于 AT89C51 单片机是一种带 4K 字节闪烁可编程可擦除只读存储器的低电压,高性能cMOS8 位微处理器。

该器件采用 ATMEL 高密度非易失存储器制造技术制造,与工业标准的 MCS-51 指令集和输出管脚相兼容。

由于将多功能 8 位CPU 和闪烁存储器组合在单个芯片中,ATMEL 的 AT89C51 是一种高效微控制器,为很多嵌入式控制系统提供了一种灵活性高且价廉的方案,所以本系统采用AT89C51 单片机作为系统的主控制器。

其特点如下:
① 4K 字节可编程闪速程序存储器:1000 次循环写/擦
②全静态工作:OHz-24MHz
③三级程序存储器锁定
④ 128 X 8 位内部数据存储器,32 条可编程 I/0 线
⑤两个十六位定时器/计数器,六个中断源
⑥可编程串行通道,低功耗闲置和掉电模式
2. 显示模块
本设计要求用LCD 显示器来显示测出的温度。

LCD系列中LM016L型号的为2行16列液晶,可显示2行16列英文字符,有8位数据总线D0-D7,RS,R/W,EN三个控制端口(共14线),工作电压为5V。

没背光,和常用的1602B功能和引脚一样(除了调背光的二个线脚)。

可以完全实现本设计的显示功能。

3.温度采集模块
本设计用的是DS18B20温度传感器,它是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。

DS18B20内部结构
(1) DS18B20的内部结构如下图所示。

图(3) DS18B20内部结构图
DS18B20有4个主要的数据部件:
① 64位激光ROM。

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

②温度灵敏元件。

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

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

④配置寄存器。

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

DS18B20在0工作时按此
寄存器中的分辨率将温度转换成相应精度的数值,其各位定义如图(4)所示。

TM R1 R0 1 1 1 1 1 MSB DS18B20配置寄存器结构图LSB
图(4)
其中,TM:测试模式标志位,出厂时被写入0,不能改变;R0、R1:温度计分辨率设置位,其对应四种分辨率如下表所列,出厂时R0、R1置为缺省值:R0=1,R1=1(即12位分辨率),用户可根据需要改写配置寄存器以获得合适的分辨率。

配置寄存器与分辨率关系表:
R0 R1 温度计分辨率/bit 最大转换时间/us
0 0 9 93.75
0 1 10 187.5
1 0 11 375
图(5)
(2)高速暂存存储器
高速暂存存储器由9个字节组成,其分配如下图所示。

当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。

单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式如图所示。

对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变为原码,再计算十进制值。

LSB DS18B20 存储器映像图MSB
图(6)
(3)DS18B20的测温功能及原理
温度值格式图DS18B20 温度数据表:
图(7)
典型对应的温度值表:
(4)DS18B20温度传感器与单片机的连接
图(9)单片机最小系统LCD显示屏电路:
图(10)LCD显示屏电路
(5)具体总体电路图如下:
图(11)总体硬件图
四、软件设计
1、主程序方案
主程序调用了4个子程序和一个欢迎开机画面的程序,4个子程序分别是液晶初始化、DS18B201的初始化、DS18B202的初始化、和液晶显示数据的程序。

(1)液晶初始化程序:8位数据端口,2行显示,5*7点阵、开启显示, 无光标、清屏、AC 递增, 画面不动。

(2)分别对两个DS18B20温度传感器初始化程序:初始化,读写一个字节,
(3)液晶显示的子程序:确定液晶字符的输入位置,将字符输出到液晶显示
(4)液晶显示温度程序:先读DS18B20当前温度,将温度转化成液晶字符显示。

将各个功能程序以子程序的形式写好,当写主程序的时候,只需要调用子程序调用指令使得程序结构清晰,无论是修改还是维护都比较方便。

将功能程序段写成子程序的形式,除了方便调用之外,还有一个好处那就是以后写程序的时候如果要用到,就可以直接调用这个单元功能模块。

2、流程图
主程序流程图:
图(11)主程序流程图
图(12)液晶初始化流程图
图(13)DS13B20的读取数据流程图
图(14)液晶显示流程图
五、调试仿真
开机画面:
XTAL2
18
XTAL1
19
ALE 30EA
31
PSEN 29RST 9
P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P1.01P1.12P1.23P1.34P1.45P1.56P1.67P1.78
P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD
17
P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U1
AT89C51
30.8
DQ 2VCC 3GND 1
FIRST
DS18B20
+5V
D 7
14
D 613D 512D 411D 310D 29D 18D 07
E 6
R W 5R S 4V S S 1V D D 2V E E
3
LCD1
LM016L
X1
12MHz
C1
22pF
C2
22pF
G N D
C3
20uF R1
1k
+5V
G N D
23456789
1RP1
10K
+5V
17.2
DQ 2VCC 3GND 1
SECOND
DS18B20
图(15)开机画面
保持两秒后显示第一个温度:
XTAL2
18
XTAL1
19
ALE 30EA
31
PSEN 29RST 9
P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P1.01P1.12P1.23P1.34P1.45P1.56P1.67P1.78
P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD
17
P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U1
AT89C51
30.8
DQ 2VCC 3GND 1
FIRST
DS18B20
+5V
D 7
14
D 613D 512D 411D 310D 29D 18D 07
E 6
R W 5R S 4V S S 1V D D 2V E E
3
LCD1
LM016L
X1
12MHz
C1
22pF
C2
22pF
G N D
C3
20uF R1
1k
+5V
G N D
23456789
1RP1
10K
+5V
17.2
DQ 2VCC 3GND 1
SECOND
DS18B20
图(16)显示第一个温度
保持两秒后显示第二个传感器测量的温度:
XTAL2
18
XTAL1
19
ALE 30EA
31
PSEN 29RST 9
P0.0/AD039P0.1/AD138P0.2/AD237P0.3/AD336P0.4/AD435P0.5/AD534P0.6/AD633P0.7/AD732P1.01P1.12P1.23P1.34P1.45P1.56P1.67P1.78
P3.0/RXD 10P3.1/TXD 11P3.2/INT012P3.3/INT113P3.4/T014P3.7/RD
17
P3.6/WR 16P3.5/T115P2.7/A1528P2.0/A821P2.1/A922P2.2/A1023P2.3/A1124P2.4/A1225P2.5/A1326P2.6/A1427U1
AT89C51
30.8
DQ 2VCC 3GND 1
FIRST
DS18B20
+5V
D 7
14
D 613D 512D 411D 310D 29D 18D 07
E 6
R W 5R S 4V S S 1V D D 2V E E
3
LCD1
LM016L
X1
12MHz
C1
22pF
C2
22pF
G N D
C3
20uF R1
1k
+5V
G N D
23456789
1RP1
10K
+5V
17.2
DQ 2VCC 3GND 1
SECOND
DS18B20
图(17)显示第二个温度
如此循环显示两个温度,仿真成功。

六、设计总结
AT89C51的时钟为12M ,I/O 口可达32个,较高的时钟频率和丰富的I/O ,都为实现电路功能提供了非常有利的条件。

同时也AT89S51内含4KB FLASH ROM ,开发环境友好,易用,方便,加上Proteus 仿真大大加快本系统设计开发。

在此次设计中学会了对Proteus 的基本使用,对里面一些基本元件的英文,如电阻RES 、电容CAP 、晶振CRYSTAL 等,学会了连线和运行。

在设计过程中也遇到一些问题,由于LCD 是现实的字符型数据,数字不能直接送去显示,所有对于数字的显示首先要转换为字符格式,方法为:数字+‘0’;对于温度传感器的小数处理也遇到一些问题,两个选的是12位,精度为0.0625,DS18B20的温度寄存器里低八位的低四位为小数部分,小数的值为0.0625*低八位的低四位,但是由于单片机的数据处理能力较差,不能处理小数的乘法运算,用上方法就显示错误,后来想到可以把小数先变成整数处理,令低八位的低四位为t ,小数后的第一位=625*t/1000,然后将这个数字在小数点后显示即可。

其实该本设计还有很多的不足,本实验是用单片机的多个I/O 口来驱动多路,DS18B20是一总线结构,每一个DS18B20 在其ROM 中都存有一个其唯一的48位序列号,在出厂前已写入片内RMO 中,主机在进行操作程序前必须逐一接入18B20 用读ROM(33H)命令将该18B20 的序列号读出并登录.当主机需要对众多在线的DS18B20 的某一个进行操作,首先要发出匹配ROM 命令(55H),紧接着主机提供64位序列(包括该DS8B20的48位序列号),之后操作就是针对该DS18B20的.而所谓跳过ROM 命令.即为:之后的操作是对所有DS18B20 的,所以可以在一根总线上挂多个DS18B20。

七、主要参考资料:
[1] 林志琦.基于Proteus的单片机可视化软硬件仿真[M].北京:北京航空航天大学出版社,2006.9
[2] 周润景,张丽娜.基于PROTEUS的电路及单片机系统设计与仿真[M].北京:北京航空航天大学出版社,2006.5
[3] 张靖武,周灵彬.单片机系统的PROTEUS设计与仿真[M].北京:电子工业出版社,2007.4
[4] 周润景,张丽娜.PROTEUS入门实用教程[M].北京:机械工业出版社,2007.9
[5] 楼然苗,李光飞.51系列单片机设计实例[M].北京:北京航空航天大学出版社,2003.3
[6] 楼然苗,李光飞.单片机课程设计指导[M].北京:北京航空航天大学出版社,2007.7
[7]. 贾东耀,汪仁煌. 数字温度传感器在仓库温度检测系统的应用[J]. 传感器世界,2001
[8] DALLAS DS18B20数据手册[Z].http://
八、附源程序代码
#include <REG51.H>
#include <intrins.h>
#include <math.h>
#define uint unsigned int
#define uchar unsigned char
uchar temp_value; //温度值
uchar TempBuffer[7];
void show_time(); //液晶显示程序
uchar temp_value1; //温度值
uchar TempBuffer1[7];
char xiaoshu=0;
char xiaoshu1=0;
void show_time1();
/***********1602液晶显示部分子程序****************/
char done,count,temp,flag,up_flag,down_flag;
//Port Definitions**********************************************************
sbit LcdRs = P2^0;
sbit LcdRw = P2^1;
sbit LcdEn = P2^2;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
sbit DQ = P1^7; //温度传送数据IO口
sbit DQ1=P1^6;
//内部等待函数************************************************************************** unsigned char LCD_Wait(void)
{
LcdRs=0;
LcdRw=1; _nop_();
LcdEn=1; _nop_();
LcdEn=0;
return DBPort;
}
//向LCD写入命令或数据************************************************************
#define LCD_COMMAND 0 // Command
#define LCD_DATA 1 // Data
#define LCD_CLEAR_SCREEN 0x01 // 清屏
#define LCD_HOMING 0x02 // 光标返回原点
void LCD_Write(bit style, unsigned char input)
{
LcdEn=0;
LcdRs=style;
LcdRw=0; _nop_();
DBPort=input; _nop_();//注意顺序
LcdEn=1; _nop_();//注意顺序
LcdEn=0; _nop_();
LCD_Wait();
}
//设置显示模式************************************************************
#define LCD_SHOW 0x04 //显示开
#define LCD_HIDE 0x00 //显示关
#define LCD_CURSOR 0x02 //显示光标
#define LCD_NO_CURSOR 0x00 //无光标
#define LCD_FLASH 0x01 //光标闪动
#define LCD_NO_FLASH 0x00 //光标不闪动
void LCD_SetDisplay(unsigned char DisplayMode)
{
LCD_Write(LCD_COMMAND, 0x08|DisplayMode);
}
//设置输入模式************************************************************
#define LCD_AC_UP 0x02
#define LCD_AC_DOWN 0x00 // default
#define LCD_MOVE 0x01 // 画面可平移
#define LCD_NO_MOVE 0x00 //default
void LCD_SetInput(unsigned char InputMode)
{
LCD_Write(LCD_COMMAND, 0x04|InputMode);
}
//初始化LCD************************************************************ void LCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38); //8位数据端口,2行显示,5*7点阵LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR); //开启显示, 无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN); //清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE); //AC递增, 画面不动
}
//液晶字符输入的位置************************
void GotoXY(unsigned char x, unsigned char y)
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
//将字符输出到液晶显示
void Print(unsigned char *str)
{
while(*str!='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
/***********ds18b20子程序*************************/
/***********ds18b20延迟子函数(晶振12MHz )*******/
void delay_18B20(unsigned int i)
{
while(i--);
}
/**********ds18b20初始化函数**********************/
void Init_DS18B20(void)
{
unsigned char x=0;
DQ = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时大于480us
DQ = 1; //拉高总线
delay_18B20(14);
x=DQ; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);
}
/***********ds18b20读一个字节**************/
unsigned char ReadOneChar(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{ DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b20写一个字节****************/
void WriteOneChar(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{ DQ = 0;
DQ = dat&0x01;
delay_18B20(5); DQ = 1;
dat>>=1;
}
}
/**************读取ds18b20当前温度************/
void ReadTemp(void)
{
unsigned char a=0;
unsigned char b=0;
char t;
long tt;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度
delay_18B20(100);
a=ReadOneChar(); //读取温度值低位
b=ReadOneChar(); //读取温度值高位
temp_value=b<<4;
temp_value+=(a&0xf0)>>4;
t=a&0x0f;
tt=t*625;
xiaoshu=tt/1000;
}
void temp_to_str() //温度数据转换成液晶字符显示
{ TempBuffer[0]=temp_value/10+'0'; //十位
TempBuffer[1]=temp_value%10+'0'; //个位
TempBuffer[2]='.';
TempBuffer[3]=xiaoshu+'0';
TempBuffer[4]=0xdf;
TempBuffer[5]='C';
TempBuffer1[6]='\0';
}
void Delay1ms(unsigned int count)
{
unsigned int i,j;
for(i=0;i<count;i++)
for(j=0;j<120;j++);
}
void show_time() //液晶显示程序
{
ReadTemp(); //开启温度采集程序
temp_to_str();
GotoXY(0,0);
Print("first");
GotoXY(0,1);//温度数据转换成液晶字符
Print("temp:");
GotoXY(6,1); //液晶字符显示位置
Print(TempBuffer); //显示温度
Delay1ms(400); //扫描延时
}
/***********ds18b20子程序*************************/
/***********ds18b20延迟子函数(晶振12MHz )*******/
/**********ds18b20初始化函数**********************/
void Init_DS18B201(void)
{
unsigned char x=0;
DQ1 = 1; //DQ复位
delay_18B20(8); //稍做延时
DQ1 = 0; //单片机将DQ拉低
delay_18B20(80); //精确延时大于480us
DQ1 = 1; //拉高总线
delay_18B20(14);
x=DQ1; //稍做延时后如果x=0则初始化成功x=1则初始化失败delay_18B20(20);
}
/***********ds18b20读一个字节**************/
unsigned char ReadOneChar1(void)
{
uchar i=0;
uchar dat = 0;
for (i=8;i>0;i--)
{ DQ1 = 0; // 给脉冲信号
dat>>=1;
DQ1 = 1; // 给脉冲信号
if(DQ1)
dat|=0x80;
delay_18B20(4);
}
return(dat);
}
/*************ds18b201写一个字节****************/
void WriteOneChar1(uchar dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{ DQ1 = 0;
DQ1 = dat&0x01;
delay_18B20(5); DQ1 = 1;
dat>>=1;
}
}
/**************读取ds18b201当前温度************/
void ReadTemp1(void)
{
unsigned char a=0;
unsigned char b=0;
unsigned char t=0;
long tt;
Init_DS18B201();
WriteOneChar1(0xCC); // 跳过读序号列号的操作
WriteOneChar1(0x44); // 启动温度转换
delay_18B20(100); // this message is wery important
Init_DS18B201();
WriteOneChar1(0xCC); //跳过读序号列号的操作
WriteOneChar1(0xBE); //读取温度寄存器等(共可读9个寄存器)前两个就是温度
delay_18B20(100);
a=ReadOneChar1(); //读取温度值低位
b=ReadOneChar1(); //读取温度值高位
temp_value1=b<<4;
temp_value1+=(a&0xf0)>>4;
t=a&0x0f;
tt=t*625;
xiaoshu1=tt/1000;
}
void temp_to_str1() //温度数据转换成液晶字符显示
{ TempBuffer1[0]=temp_value1/10+'0'; //十位
TempBuffer1[1]=temp_value1%10+'0'; //个位
TempBuffer1[2]='.';
TempBuffer1[3]=xiaoshu1+'0';
TempBuffer1[4]=0xdf; //温度符号
TempBuffer1[5]='C';
TempBuffer1[6]='\0';
}
void show_time1() //液晶显示程序
{
ReadTemp1(); //开启温度采集程序
temp_to_str1();
GotoXY(0,0);
Print("second");
GotoXY(0,1);//温度数据转换成液晶字符
Print("temp:");
GotoXY(6,1); //液晶字符显示位置
Print(TempBuffer1); //显示温度
Delay1ms(400); //扫描延时
}
main()
{
LCD_Initial(); //液晶初始化
Init_DS18B20( ) ; //DS18B20初始化
Init_DS18B201( );
GotoXY(2,0);
Print("welcome!");
GotoXY(1,1);
Print("design by zw!");
ReadTemp();
ReadTemp1();
Delay1ms(2000);
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);
while(1)
{
show_time(); //液晶显示数据
// flag=0;
Delay1ms(2000);
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);
show_time1();
// flag=0;
Delay1ms(2000);
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);
}
}。

相关文档
最新文档