西安邮电大学
通信与信息工程学院
课程设计实验报告
专业班级: 电科1003班
学生姓名: 张晓宇
学号(班内序号): 03102090(18号)
2012 年 12 月 6 日
成绩鉴定表
主题:温度报警器
摘 要:本设计主要是一个基于89C52RC单片机的测温系统,利用数字温度传感器DS18B20开发测温系统的过程,重点对传感器在单片机下的硬件连接,软件编程以及各模块系统流程进行了详尽分析,对各部分的电路也一一进行了介绍,该系统可以方便的实现温度采集和显示,并可根据需要任意设定上下限报警温度,它使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合于我们日常生活和工、农业生产中的温度测量,也可以当作温度处理模块嵌入其它系统中,作为其他主系统的辅助扩展。DS18B20与89C52RC结合实现最简温度检测系统,该系统结构简单,抗干扰能力强,适合于恶劣环境下进行现场温度测量,有广泛的应用前景。
1 前 言
随着微电子技术和微型计算机的迅猛发展,微机测量和控制技术以其逻辑简单、控制灵活、使用方便及性能价格比高的优点得到了迅猛发展和广泛应用。它不仅在航天、航空、铁路交通、冶金、电力、电讯、石油化、制造业等领域获得了广泛应用,而且其技术在日常生活中也具有广阔的应用前景。尤其是许多智能仪器和测控系统中电脑控制技术的引入,使得传统仪器、仪表设备发生了根本变化,为工业生产的自动化、智能化奠定了坚实的技术基础。
在工业生产、石油化工、电力、国防、科研领域和日常生活中,温度是极为普遍又极有意义的热工参数之一,温度是玉我们的生活,工作息息相关的物理参数。自然界中任何物理的,化学的变化过程都与温度紧密联系。温度的测量与控制直接和产品质量、提高生产率、节约能源、安全生产等重要经济技术指标相关联,因此温度测量是一个具有重要意义的技术领域。温度传感器是在温度测量系统使用量大,应用最广泛的一种传感器。
在下文中,主要研究的是单片机控制下的温度报警器,它使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合于我们日常生活和工、农业生产中的温度测量,也可以当作温度处理模块嵌入其它系统中,作为其他主系统的辅助扩展。
2硬件电路设计
温度计电路设计原理图如下图所示,控制器使用单片机89C52RC,温度传感器使用DS18B20,用液晶显示屏实现温度显示。
本温度计大体分三个工作过程。首先,由DS18820温度传感器芯片测量当前的温度,并将结果送入单片机。然后,通过89C52RC单片机芯片对送来的测量温度读数进行计算和转换,井将此结果送入液晶显示模块。最后,SMC1602A芯片将送来的值显示于显示屏上。 由图1可看到,本电路主要由DSl8B20温度传感器芯片、液晶显示模块芯片和89C52RC单片机芯片组成。其中,DSI8B20温度传感器芯片采用“一线制”与单片机相连,它独立地完成温度测量以及将温度测量结果送到单片机的工作。
3.详细介绍 DS18B20
DALLAS 最新单线数字温度传感器DS18B20是一种新型的“一线器件”,其体积更小、更适用于多种场合、且适用电压更宽、更经济。DALLAS 半导体公司的数字化温度传感器DS18B20是世界上第一片支持“一线总线”接口的温度传感器。温度测量范围为-55~+125 摄氏度,可编程为9位~12 位转换精度,测温分辨率可达0.0625摄氏度,分辨率设定参数以及用户设定的报警温度存储在EEPROM 中,掉电后依然保存。被测温度用符号扩展的16位数字量方式串行输出;其工作电源既可以在远端引入,也可以采用寄生电源方式产生;多个DS18B20可以并联到3 根或2 根线上,CPU只需一根端口线就能与诸多DS18B20 通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
1. DS18B20 的性能特点如下:
●DS18B20支持多点组网功能,多个DS18B20可以并联在唯一的三线上。
●DS18B20在使用中不需要任何外围元件,全部传感元件及转换电路集成在形如一只三极管的集成电路内
●适应电压范围更宽,电压范围:3.0~5.5V,在寄生电源方式下可由数据线供电
●温范围-55℃~+125℃,在-10~+85℃时精度为±0.5℃
●零待机功耗
●可编程的分辨率为9~12位,对应的可分辨温度分别为0.5℃、0.25℃、0.125℃和0.0625℃,可实现高精度测温
●在9位分辨率时最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字,速度更快
●用户可定义报警设置
●报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件
●测量结果直接输出数字温度信号,以"一线总线"串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力
●负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作
以上特点使DS18B20非常适用与多点、远距离温度检测系统。
DS18B20内部结构主要由四部分组成:64位光刻ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。DS18B20的管脚排列、DQ 为数据输入/输出引脚。开漏单总线接口引脚。当被用着在寄生电源下,也可以向器件提供电源;GND为地信号;VDD为可选择的VDD引脚。当工作于寄生电源时,此引脚必须接地。
4.主程序图
液晶显示屏部分
温度传感器、报警器、LED显示灯部分
5主程序设计
#include<reg52.h> //包含头文件,一般情况不需要改动,头文件包含特殊功能寄存器的定义
bit ReadTempFlag;//定义读时间标志
sbit RS = P2^0; //定义端口
sbit RW = P2^1;
sbit EN = P2^2;
sbit BUSY=P0^7;
sbit DQ=P3^2;
sbit DENG=P2^4;
sbit BUZZER=P2^7;
sbit BUTTON=P1^0;
#define RS_CLR RS=0
#define RS_SET RS=1
#define RW_CLR RW=0
#define RW_SET RW=1
#define EN_CLR EN=0
#define EN_SET EN=1
#define DataPort P0
void DelayUs2x(unsigned char t)
{
while(--t);
}
void DelayMs(unsigned char t)
{
while(t--)
{
DelayUs2x(245);
DelayUs2x(245);
}
}
void LCD_Check_Busy(void)
{
DataPort= 0xFF;
do{
RS_CLR;
RW_SET;
EN_CLR;
// _nop_();
EN_SET;}while(BUSY==1);
EN_CLR;
//return (bit)(DataPort & 0x80);
}
void LCD_Write_Com(unsigned char com)
{
LCD_Check_Busy(); //忙则等待
RS_CLR;
RW_CLR;
EN_SET;
DataPort= com;
//_nop_();
EN_CLR;
}
void LCD_Write_Data(unsigned char Data)
{
LCD_Check_Busy(); //忙则等待
RS_SET;
RW_CLR;
EN_SET;
DataPort= Data;
//_nop_();
EN_CLR;
}
void LCD_Clear(void)
{
LCD_Write_Com(0x01);
DelayMs(5);
}
void LCD_Write_String(unsigned char x,unsigned char y,unsigned char *s)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x); //表示第一行
}
else
{
LCD_Write_Com(0xC0 + x); //表示第二行
}
while (*s)
{
LCD_Write_Data( *s);
s ++;
}
}
void LCD_Write_Char(unsigned char x,unsigned char y,unsigned char Data)
{
if (y == 0)
{
LCD_Write_Com(0x80 + x);
}
else
{
LCD_Write_Com(0xC0 + x);
}
LCD_Write_Data( Data);
}
/*------------------------------------------------
初始化函数
------------------------------------------------*/
void LCD_Init(void)
{
LCD_Write_Com(0x38); /*显示模式设置*/
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
DelayMs(5);
LCD_Write_Com(0x38);
LCD_Write_Com(0x08); /*显示关闭*/
LCD_Write_Com(0x01); /*显示清屏*/
LCD_Write_Com(0x06); /*显示光标移动设置*/
DelayMs(5);
LCD_Write_Com(0x0C); /*显示开及光标设置*/
}
bit Init_DS18B20(void)
{
bit dat=0;
DQ = 1; //DQ复位
DelayUs2x(5); //稍做延时
DQ = 0; //单片机将DQ拉低
DelayUs2x(200); //精确延时 大于 480us 小于960us
DelayUs2x(200);
DQ = 1; //拉高总线
DelayUs2x(50); //15~60us 后 接收60-240us的存在脉冲
dat=DQ; //如果x=0则初始化成功, x=1则初始化失败
DelayUs2x(25); //稍作延时返回
return dat;
}
/*------------------------------------------------
读取一个字节
------------------------------------------------*/
unsigned char ReadOneChar(void)
{
unsigned char i=0;
unsigned char dat = 0;
for (i=8;i>0;i--)
{
DQ = 0; // 给脉冲信号
dat>>=1;
DQ = 1; // 给脉冲信号
if(DQ)
dat|=0x80;
DelayUs2x(25);
}
return(dat);
}
/*------------------------------------------------
写入一个字节
------------------------------------------------*/
void WriteOneChar(unsigned char dat)
{
unsigned char i=0;
for (i=8; i>0; i--)
{
DQ = 0;
DQ = dat&0x01;
DelayUs2x(25);
DQ = 1;
dat>>=1;
}
DelayUs2x(25);
}
/*------------------------------------------------
读取温度
------------------------------------------------*/
unsigned int ReadTemperature(void)
{
unsigned char a=0;
unsigned int b=0;
unsigned int t=0;
Init_DS18B20();
WriteOneChar(0xCC); // 跳过读序号列号的操作
WriteOneChar(0x44); // 启动温度转换
DelayMs(10);
Init_DS18B20();
WriteOneChar(0xCC); //跳过读序号列号的操作
WriteOneChar(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度
a=ReadOneChar(); //低位
b=ReadOneChar(); //高位
b<<=8;
t=a+b;
return(t);
}
void Init_Timer0(void);//定时器初始化
/*------------------------------------------------
串口通讯初始化
------------------------------------------------*/
void UART_Init(void)
{
SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收
TMOD |= 0x20; // TMOD: timer 1, mode 2, 8-bit 重装
TH1 = 0xFD; // TH1: 重装值 9600 波特率 晶振 11.0592MHz
TR1 = 1; // TR1: timer 1 打开
//EA = 1; //打开总中断
//ES = 1; //打开串口中断
TI=1;
}
/*------------------------------------------------
主函数
------------------------------------------------*/
void main (void)
{
int temp,max=25;
float temperature,fahrenheit,fah;
char displaytemp[16];//定义显示区域临时存储数组
char displayfsh[16];//定义显示区域临时存储数组
DENG=0x00;
BUZZER=0x00;
BUTTON=0x00;
LCD_Init(); //初始化液晶
DelayMs(20); //延时有助于稳定
LCD_Clear(); //清屏
Init_Timer0();
UART_Init();
Lcd_User_Chr(); //写入自定义字符
temp=ReadTemperature();
while (1) //主循环
{
if(!BUTTON&&ReadTempFlag==1)
{
ReadTempFlag=0;
temp=ReadTemperature();
LCD_Clear();
LCD_Write_String(0,0," ^-^ Welcome ^-^");
LCD_Write_Char(13,1,0x01);//写入温度右上角点
LCD_Write_Char(14,1,'C'); //写入字符C
temperature=(float)temp*0.0625;
sprintf(displaytemp,"Temp % 7.3f",temperature);//打印温度值
LCD_Write_String(0,1,displaytemp);//显示第二行
}
else if(BUTTON&&ReadTempFlag==1)
{
ReadTempFlag=0;
temp=ReadTemperature();
LCD_Clear(); //清屏
LCD_Write_String(0,0," ^-^ **FAH** ^-^");
LCD_Write_Char(13,1,0x01);//写入温度右上角点
LCD_Write_Char(14,1,'F'); //写入字符F
fah=((float)temp*1.8)+32;
//fah=temp+32;
fahrenheit=fah*0.0625+30;
sprintf(displayfsh,"Fah % 7.3f",fahrenheit);//打印华氏温度值
LCD_Write_String(0,1,displayfsh);//显示第二行
}
if(temp<max)
{
LCD_Write_String(0,1,"Wrong");
DENG=BUZZER=~DENG;
}
//else
//LCD_Write_String(0,0," Right");
}
}
/*------------------------------------------------
定时器初始化子程序
------------------------------------------------*/
void Init_Timer0(void)
{
TMOD |= 0x01; //使用模式1,16位定时器,使用"|"符号可以在使用多个定时器时不受影响
//TH0=0x00; //给定初值
//TL0=0x00;
EA=1; //总中断打开
ET0=1; //定时器中断打开
TR0=1; //定时器开关打开
}
/*------------------------------------------------
定时器中断子程序
------------------------------------------------*/
void Timer0_isr(void) interrupt 1
{
static unsigned int num;
TH0=(65536-2000)/256; //重新赋值 2ms
TL0=(65536-2000)%256;
num++;
if(num==300) //
{
num=0;
ReadTempFlag=1; //读标志位置1
}
6 心得体会
此次毕业设计是我大学生涯当中非常重要的一段时光,在这段时间里从最初的选题,确定题到大家一起做直到完成作品。其间,查找资料,老师指导,与同学交流,反复修改,每一个过程都是对自己能力的一次检验和充实。通过这次实践,锻炼了设计实践能力,、此次毕业设计是对我专业知识和专业基础知识一次实际检验和巩固,同时也是走向工作岗位前的一次热身。 这次设计收获很多,比如学会了查找相关资料相关标准,分析数据,提高了自己的制作能力。
终于完成了我的单片机课程设计,虽然没有完全达到设计要求,但从心底里说,还是高兴的,毕竟这次设计放了大家都尽力了,高兴之余不得不深思呀!
在本次设计的过程中,我发现很多的问题,,比如缺乏综合应用专业知识的能力,对材料的不了解等等。由于时间有限,未能完成全部安装与调试工作,对设计结果没有作出最后的检验,也感到遗憾。这次实践是对自己大学四年所学的一次大检阅,使我明白自己知识还很不全面。马上要毕业了,自己的求学之路还很长,以后更应该在工作实践中不断学习,努力使自己 成为一个对社会有所贡献的人。单片机课程设计重点就在于软件算法的设计,需要有很巧妙的程序算法,虽然以前写过几次程序,但我觉的写好一个程序并不是一件简单的事,只有我们去试着做了,才能真正的掌握,只学习理论有些东西是很难理解的,更谈不上掌握。
从这次的课程设计中,我真真正正的意识到,在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高,这就是我在这次课程设计中的最大收获。
虽然在设计的过程中遇到各种各样的困难,但最终在老师和同学的帮助下完成了设计。极大的培养了我们的科研精神,激发了我们的专业兴趣,积累了实践经验,为将来的继续学习和工作打下了基础。虽然这是我们做的一个简单的课程设计,但却让我们学到了很多。所以希望学院能够多安排一些类似的实践训练,能让学弟学妹们有更多的机会接触具有现实意义的项目,能接触更多的硬件,更好的提升自己的实践能力和综合能力。