概述
目 录
摘 要 I
ABSTRACT II
第1章 绪论 1
1.1 设计任务及要求 1
1.2 设计总体方案及方案论证 1
1.3 温度测量的方案与分析 2
1.3.1芯片选择 2
1.3.2实现方法简介 2
1.3.3 方案设计 2
第2章 芯片简介 4
2.1 STC89C52芯片简介 4
2.1.1引脚功能说明 4
2.2 DS18B20简介 7
2.2.1芯片简介 7
2.2.2 DS18B20外形和内部结构 7
2.2.3 DS18B20温度值 9
2.2.4 DS18B20的工作时序 10
2.2.5 DS18B20与单片机的典型接口设计 11
2.2.6 DS18B20的各个ROM命令 12
2.3 HC595简介 14
2.3.1芯片简介 14
2.3.2 74HC595特点 14
2.3.3引脚图及各引脚功能 14
2.4小结 15
第3章 系统硬件电路的设计 16
3.1主控制电路和测温控制电路原理图 16
3.2驱动电路与显示电路模块原理图 17
3.3小结 17
第4章 软件编程与功能调试 18
4.1 系统软件设计整体思路 18
4.2 系统程序流图 18
4.3小结 22
第5章 仿真分析与实物制作 23
5.1 PROTUES软件简介 23
5.2 实物制作 23
5.3小结 24
结 论 25
参考文献 26
致 谢 28
附 录 29
附录一:原理图 29
附录二:PCB设计 30
附录三:仿真调试 31
第1章 绪论
1.1 设计任务及要求
本次设计一个以单片机为核心的温度箱实时温度测量控制系统,可实现的功能为:
(1)测量温度值精度为±0.1℃。
(2)系统允许的误差范围为0.1℃以内。
(3)系统可由用户预设温度值,测温范围为-55℃~+125℃。
(4)到达用户预设温度时,电机转动给温度箱降温。
(5)显示当前时间。
1.2 设计总体方案及方案论证
在日常生活及工农业生产中经常要用到温度的检测及控制,传统的测温元件有热电偶和热点阻。而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,需要比较多的外部硬件支持,硬件电路复杂,软件调试复杂,制作成本高[1]。
本温度箱设计采用美国DALLAS半导体公司继DS18B20之后推出的一种改进智能温度传感器DS18B20作为检测元件,测温范围为-55℃~+125℃,最大分辨率可达0.0625℃。DS18B20可以直接读出被测量的温度值,而采用3线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点[2]。
按照系统设计功能的要求,确定系统由5个模块组成:主控制器STC89C52,温度传感器DS18B20,驱动显示电路。温度箱总体电路框图如图1-1所示。
图1-1 总体电路图
1.3 温度测量的方案与分析
1.3.1芯片选择
本设计的测温系统采用芯片DS18B20, DS18B20是DALLAS公司的最新单线数字温度传感器,它的体积更小、适用电压更宽、更经济,DS18B20是世界上第一片支持“一线总线”接口的温度传感器,具有一线总线独特而且经济的特点[3-7]。采用智能温度传感器DS18B20作为检测元件,测温范围为-55℃~+125℃,最大分辨率可达0.0625℃。DS18B20可以直接读出被测量的温度值,而且采用3线制与单片机相连,减少了外部的硬件电路,具有低成本和易使用的特点。
1.3.2实现方法简介
DS18B20采用外接电源方式工作,一线测温的一线与STC89C52的P3.7连并加上上拉电阻使其工作,测出的数据存放在寄存器10H–12H中,将数据经过BCD码转换后送LED显示[8][9]。具体实现步骤见软件设计章节。
1.控制部分
单片机STC89S52具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用,系统应用三节电池供电。
2. 显示部分
显示电路采用6位共阴7段LED数码管,采用74HC595移位寄存器进行驱动,其中一个数码管显示通道数,另外5个数码管显示该通道的温度值,实现实时测量[10]。
3. 温度采集部分
DS18B20温度传感器是美国DALLAS半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温。这一部分主要完成对温度信号的采集和转换工作,由DS18B20数字温度传感器及其与单片机的接口部分组成。数字温度传感器DS18B20把采集到的温度通过数据引脚传到单片机的P1.0口,单片机接受温度并存储。此部分只用到DS18B20和单片机,硬件很简单方案设计[11-15]。
1.3.3 方案设计
方案一: P1.0-P1.7各与一个DS18B20相连,实现8通道自动温度检测系统;其中一个数码管显示通道号,另外五个显示温度。
方案二:P2.5与两个DS18B20相连,P2.6与另外两个DS18B20相连。用一个开关显示不同通道的温度。其中显示部分用MAX7219[10][11]驱动8个数码管。方案比较:虽然方案二硬件系统比较简单,但是软件部分比较复杂。另外鉴于现在的水平,故选择比较简单的方案一。
#include <REG51.H>
#include <intrins.h>
//#include "LCD1602.h"
//#include "DS1302.h"
#define uint unsigned int
#define uchar unsigned char
sbit DS1302_CLK = P2^2; //实时时钟时钟线引脚
sbit DS1302_IO = P2^1; //实时时钟数据线引脚
sbit DS1302_RST = P2^0; //实时时钟复位线引脚
sbit wireless_1 = P3^0;
sbit wireless_2 = P3^1;
sbit wireless_3 = P3^2;
sbit wireless_4 = P3^3;
sbit ACC0 = ACC^0;
sbit ACC7 = ACC^7;
char hide_sec,hide_min,hide_hour,hide_day,hide_week,hide_month,hide_year; //秒,分,时到日,月,年位闪的计数
sbit Set = P3^4; //模式切换键
sbit Up = P3^5; //加法按钮
sbit Down = P3^6; //减法按钮
sbit out = P3^7; //立刻跳出调整模式按钮
sbit DQ = P1^0; //温度传送数据IO口
char done,count,temp,flag,up_flag,down_flag;
uchar temp_value; //温度值
uchar TempBuffer[5],week_value[2];
void show_time(); //液晶显示程序
/***********1602液晶显示部分子程序****************/
//Port Definitions**********************************************************
sbit LcdRs = P2^5;
sbit LcdRw = P2^6;
sbit LcdEn = P2^7;
sfr DBPort = 0x80; //P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
//内部等待函数**************************************************************************
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!='