基于单片机的智能温度监测系统设计

发布者:朝霞暮雨最新更新时间:2022-04-02 来源: eefocus关键字:单片机 手机看文章 扫描二维码
随时随地手机看文章

智能温度检测系统是通过硬件电路设计和软件编程驱动的结合方式,实现0℃~99℃范围内的温度智能监测。可通过LCD实时显示实际温度和预设温度,当温度超出预设范围时及时报警,而且报警声用电子乐曲或音乐音符实现。


前言

本次设计的主要思路是利用51系列单片机,数字温度传感器DS18B20和1602LCD液晶显示,构成实现温度检测与显示的单片机控制系统,即数字温度计。通过对单片机编写相应的程序,达到能够实时检测周围温度的目的。 通过对本课题的设计能够熟悉数字温度计的工作原理及过程,了解各功能器件(单片机、DS18B20、LCD)的基本原理与应用,掌握各部分电路的硬件连线与程序编写,最终完成对数字温度计的总体设计。其具体的要求如下: 1、根据设计要求,选用AT89C51单片机为核心器件; 2、温度检测器件采用DS18B20数字式温度传感器,利用单总线式连接方式与单片机的串行接口P3.3引脚相连; 3、显示电路采用1602LCD液晶显示温度值,此类液晶模块不仅可以显示数字、字符,还可以显示各种图形符号以及少量自定义符号,人机界面友好,使用操作也更加灵活、方便,使其日益成为各种仪器仪表等设备的首选。


系统的开发过程

本设计主要介绍了用单片机和数字温度传感器DS18B20相结合的方法来实现温度的采集,以单片机AT89C51芯片为核心,温度传感器DS18B20和1602LCD液晶显示,构成了一个多功能单片机数字温度计。其主要研究内容包括两方面,一是对系统硬件部分的设计,包括温度采集电路和显示电路;二是对系统软件部分的设计,应用C语言实现温度的采集与显示。通过利用数字温度传感器DS18B20进行设计,能够满足实时检测温度的要求,同时通过1602LCD的显示功能,可以实现不间断的温度显示。其总体设计框图一如下:

 

图一:总体设计框图

第一节AT89C51简介

AT89C51是美国ATMEL公司生产的低功耗,高性能CMOS8位单片机,片内含4kbytes的可编程的Flash只读程序存储器,兼容标准8051指令系统及引脚,并集成了 Flash 程序存储器,既可在线编程(ISP),也可用传统方法进行编程,因此,低价位AT89C51单片机可应用于许多高性价比的场合,可灵活应用于各种控制领域,对于简单的测温系统已经足够。单片机AT89C51具有低电压供电和体积小等特点,四个端口只需要两个口就能满足电路系统的设计需要,很适合便携手持式产品的设计使用系统可用二节电池供电。芯片AT89C51的引脚排列如图二所示:

 

图二:AT89C51单片机引脚图

第二节晶振电路的设计

单片机晶振电路的设计如图三所示。XTAL1(X1)为反向振荡放大器的输入及内部时钟工作电路的输入。按照理论上AT89C51使用的是12MHz的晶振,但实测使用11.0592MHz。所以设计者通常用的是11.0592MHz。 

 

图三:单片机晶振电路

第三节温度采集电路的设计

DALLAS 最新单线数字温度传感器DS18B20是一种新型的“一线器件”,其体积更小、更适用于多种场合、且适用电压更宽、更经济。DALLAS 半导体公司的数字化温度传感器DS18B20是世界上第一片支持“一线总线”接口的温度传感器。温度测量范围为-55~+125 摄氏度,可编程为9~12 位转换精度,测温分辨率可达0.0625摄氏度,分辨率设定参数以及用户设定的报警温度存储在EEPROM 中,掉电后依然保存。被测温度用符号扩展的16位数字量方式串行输出;其工作电源既可以在远端引入,也可以采用寄生电源方式产生;多个DS18B20可以并联到3 根或2 根线上,CPU只需一根端口线就能与诸多DS18B20 通信,占用微处理器的端口较少,可节省大量的引线和逻辑电路。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。本设计的温度采集电路如图四所示。

 

图四:温度采集电路图

第五节温度显示电路的设计

显示器常用作单片机最简单的输出设备,用以显示单片机的运行结果和运行状态等。常用的显示器主要有LED和LCD,它们都具有耗电少、成本低、线路简单、寿命长等优点,广泛应用于单片机显示数字量的场合。设计中采用LCD显示器。液晶显示器(LCD)具有功耗低、体积小、质量轻、功耗小的特点。点阵字符型液晶显示器把LCD控制器、点阵驱动器、字符存储器集成在一块印刷电路板上,构成便于应用的液晶模块。此类液晶模块不仅可以显示数字、字符,还可以显示各种图形符号以及少量自定义符号,并且可以实现屏幕的上下左右滚动、文字的闪烁等功能,人机界面友好,使用操作也更加灵活、方便,使其日益成为各种仪器仪表等设备的首选。图五为本设计的显示电路图。

 

图五:显示电路图

第六节应用软件介绍

本设计主要用Proteus仿真软件和Keil编译软件。

本设计主要用Proteus仿真软件和Keil编译软件 4.1.1 Proteus的介绍 

Proteus软件是英国Labcenter electronics公司出版的EDA工具软件。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件,它是目前最好的仿真单片机及外围器件的工具,虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学教师、致力于单片机开发应用的科技工作者的青睐。Proteus是世界上著名的EDA工具(仿真软件),从原理布图、代码调试到单片机与外围电路协同仿真,一键切换发到PCB设计,真正实现了从 概念到产品的完整设计。是目前世界上唯一将电路仿真软件、PCB设计软件和虚拟模型仿真软件三合一的设计平台,其处理器模型支持8051、HC11、PIC10/12/16/18/24/30/DsPIC33、AVR、ARM、8086HE MSP430等,2010年即将增加Cortex和DSP系列处理器,并持续增加其他系列处理器模型。在编译方面,它也支持IAR、Keil和MPLAB等多种编译器。


Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统,与汇编相比,C语言在功能上、结构性、可读性、可维护性上有明显的优势,因而易学易用。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部分组合在一起。运行Keil软件需要WIN98、NT、WIN2000、WINXP等操作系统。如果你使用C语言编程,那么Keil几乎就是你的不二之选,即使不使用C语言而仅用汇编语言编程,其方便易用的集成环境、强大的软件仿真调试工具也会令你事半功倍。


系统测试情况

进入测试,开关不闭合,系统默认显示1602LCD显示当前采集的温度,当温度变化时,系统实时采集DS18B20的温度并显示出来,当采集的温度超过系统所设置的上限或者下限的时候,系统自动报警,开关闭合,显示报警温度的上限值和下限值。综合仿真图如图六所示:

 

系统的优点与不足

优点:软件可以实时检测温度值,并显示,当温度超出预设范围时及时报警,并且还可以检测并显示零下温度。

缺点:只是做到了仿真程序,没有具体的硬件实现,系统运行时预设温度不能改动。

 

附录代码


#include

 

#include

 

#define uchar unsigned char

 

#define uint unsigned int

 

sbit DQ=P3^3;//DS18B20数据线

 

sbit BEEP=P3^7;//报警器

 

sbit LCD_RS=P2^0;

 

sbit LCD_RW=P2^1;

 

sbit LCD_EN=P2^2;

 

sbit K1=P1^7;

 

uchar code Temp_Disp_Title[]={" Current Temp : "};

 

uchar Current_Temp_Display_Buffer[]={"TEMP:            "};

 

uchar code Alarm_Temp[]={"ALARM TEMP Hi Lo"};

 

uchar Alarm_HI_LO_STR[]={"Hi:     Lo:      "};

 

uchar code df_Table[]={0,1,1,2,3,3,4,4,5,6,6,7,8,8,9,9};//温度小数位对照表

 

char Alarm_Temp_HL[2]={100,0};

 

uchar CurrentT=0;//当前读取的温度整数部分

 

uchar Temp_Value[]={0x00,0x00};//从DS18B20读取的温度值

 

uchar Display_Digit[]={0,0,0,0};//待显示的各温度数位

 

bit HI_Alarm=0,LO_Alarm=0;//高温低温报警标志

 

bit DS18B20_IS_OK=1;//传感器正常标志

 

uint Time0_Count=0;//定时器延时累加

 

//延时

 

void DelayMS(uint x){

 

uchar i;

 

while(x--)for(i=0;i<120;i++);

 

}

 

//读LCD状态

 

uchar Read_LCD_State(){

 

uchar state;

 

LCD_RS=0;LCD_RW=1;LCD_EN=1;DelayMS(1);state=P0;LCD_EN=0;DelayMS(1);

 

return state;

 

}

 

//忙等待

 

void LCD_Busy_Wait(){

 

while((Read_LCD_State()&0x80)==0x80);

 

DelayMS(5);

 

}

 

//写LCD指令

 

void Write_LCD_Command(uchar cmd){

 

LCD_Busy_Wait();

 

LCD_RS=0;LCD_RW=0;LCD_EN=0;P0=cmd;LCD_EN=1;DelayMS(1);LCD_EN=0;

 

}

 

//向LCD写数据

 

void Write_LCD_Data(uchar dat){

 

LCD_Busy_Wait();

 

LCD_RS=1;LCD_RW=0;LCD_EN=0;P0=dat;LCD_EN=1;DelayMS(1);LCD_EN=0;

 

 

//延时

 

void DelayXus(int x){

 

uchar i;

 

while(x--)for(i=0;i<200;i++);

 

}

 

//延时

 

void Delay(uint num){

 

while(--num);

 

}

 

//初始化DS18B20

 

uchar Init_DS18B20(){

 

uchar status;

 

DQ=1;Delay(8);

 

DQ=0;Delay(90);

 

DQ=1;Delay(8);

 

status=DQ;

 

Delay(100);

 

DQ=1;

 

return status;//初始化成功返回0

 

}

 

//读一字节

 

uchar ReadOneByte(){

 

uchar i,dat=0;

 

DQ=1;_nop_();

 

for(i=0;i<8;i++){

 

DQ=0;dat>>=1;DQ=1;_nop_();_nop_();

 

if(DQ)dat|=0x80;Delay(30);DQ=1;

 

}

 

return dat;

 

}

 

//写一个字节

 

void WriteOneByte(uchar dat){

 

uchar i;

 

for(i=0;i<8;i++){

 

DQ=0;DQ=dat&0x01;Delay(5);DQ=1;dat>>=1;

 

}

 

}

 

//读取温度值

 

void Read_Temperature(){

 

if(Init_DS18B20()==1)//DS18B20故障

 

DS18B20_IS_OK=0;

 

else{

 

WriteOneByte(0xcc);//跳过序列号

 

WriteOneByte(0x44);//启动温度转换

 

Init_DS18B20();

 

WriteOneByte(0xcc);//跳过序列号

 

WriteOneByte(0xbe);//读取温度寄存器

 

Temp_Value[0]=ReadOneByte();//读取低8位

 

Temp_Value[1]=ReadOneByte();//温度高8位

 

Alarm_Temp_HL[0]=ReadOneByte();//报警TH

 

Alarm_Temp_HL[1]=ReadOneByte();//报警TL

 

DS18B20_IS_OK=1;

 

}

 

}

 

//设置DS18B20温度报警值

 

void Set_Alarm_Temp_Value(){

 

Init_DS18B20();

 

WriteOneByte(0xcc);//跳过序列号

 

WriteOneByte(0x4e);//将设定的温度报警值写入DS18B20

 

WriteOneByte(Alarm_Temp_HL[0]);//写TH

 

WriteOneByte(Alarm_Temp_HL[1]);//写TL

 

WriteOneByte(0x7f);//12位精度

 

Init_DS18B20();

 

WriteOneByte(0xcc);//跳过序列号

 

WriteOneByte(0x48);//将设定的温度报警值写入DS18B20

 

}

 

//设置液晶显示位置

 

void Set_LCD_POS(uchar p){

 

Write_LCD_Command(p|0x80);

 

 

//在LCD上显示当前温度

 

void Display_Temperature(){

 

uchar i;

 

uchar t=150;//延时值

 

uchar ng=0;//负数标志

 

char Signed_Current_Temp;//如果为负数则取反加1,并设置负数标识

 

if((Temp_Value[1]&0xf8)==0xf8){

 

Temp_Value[1]=~Temp_Value[1];

 

Temp_Value[0]=~Temp_Value[0]+1;

 

if(Temp_Value[0]==0x00)Temp_Value[1]++;

 

ng=1;//设负数标识

 

}

 

//查表得到温度小数部分

 

Display_Digit[0]=df_Table[Temp_Value[0]&0x0f];

 

//获取温度整数部分(无符号)

 

CurrentT=((Temp_Value[0]&0xf0)>>4)|((Temp_Value[1]&0x07)<<4);

 

//有符号的当前温度值,注意此处定义为char,其值可为-128~+127

 

Signed_Current_Temp=ng?-CurrentT:CurrentT;

 

//高低温报警标志设置(与定义为char类型的Alarm_Temp_HL比较,这样可区分正负比较)

 

HI_Alarm=Signed_Current_Temp>=Alarm_Temp_HL[0]?1:0;

 

LO_Alarm=Signed_Current_Temp<=Alarm_Temp_HL[1]?1:0;

 

//将整数部分分解为三位待显示数字

 

Display_Digit[3]=CurrentT/100;

 

Display_Digit[2]=CurrentT%100/10;

 

Display_Digit[1]=CurrentT%10;

 

//刷新LCD显示缓冲

 

Current_Temp_Display_Buffer[11]=Display_Digit[0]+'0';

 

Current_Temp_Display_Buffer[10]='.';

 

Current_Temp_Display_Buffer[9]=Display_Digit[1]+'0';

 

Current_Temp_Display_Buffer[8]=Display_Digit[2]+'0';

 

Current_Temp_Display_Buffer[7]=Display_Digit[3]+'0'; 

 

//高位为0时不显示

 

if(Display_Digit[3]==0)Current_Temp_Display_Buffer[7]=' ';

 

//高位为0且次高位为0时,次高位不显示

 

if(Display_Digit[2]==0&&Display_Digit[3]==0)

 

Current_Temp_Display_Buffer[8]=' ';

 

//负数符号显示在恰当位置

 

if(ng)

 

{

 

if(Current_Temp_Display_Buffer[8]==' ')

 

Current_Temp_Display_Buffer[8]='-';

 

else if(Current_Temp_Display_Buffer[7]==' ')

 

Current_Temp_Display_Buffer[7]='-';

 

else Current_Temp_Display_Buffer[6]='-';

 

}

 

//在第一行显示标题

 

Set_LCD_POS(0x00);

 

for(i=0;i<16;i++)Write_LCD_Data(Temp_Disp_Title[i]);

 

//在第二行显示当前温度

 

Set_LCD_POS(0x40);

 

for(i=0;i<16;i++)Write_LCD_Data(Current_Temp_Display_Buffer[i]);

 

//显示温度符号

 

Set_LCD_POS(0x4d);Write_LCD_Data(0x00);

 

Set_LCD_POS(0x4e);Write_LCD_Data('C');

 

}

 

//定时器中断,控制警报声音

 

void T0_INT()interrupt 1{

 

TH0=-1000/256;

 

TL0=-1000%256;

 

BEEP=!BEEP;

 

if(++Time0_Count==400){

 

Time0_Count=0;

 

TR0=0;

 

}

 

}

 

//显示报警温度

 

void Disp_Alarm_Temperature(){

 

uchar i,ng;

 

//显示Alarm_Temp_HL数组中的报警温度值

 

//由于Alarm_Temp_HL类型为char,故可以直接进行正负比较

 

//高温报警值

 

ng=0;

 

if(Alarm_Temp_HL[0]<0)//如果为负数则取反加1

 

{

 

Alarm_Temp_HL[0]=~Alarm_Temp_HL[0]+1;

 

ng=1;

 

}

 

//分解高温各数位到待显示串中

 

Alarm_HI_LO_STR[4]=Alarm_Temp_HL[0]/100+'0';

 

Alarm_HI_LO_STR[5]=Alarm_Temp_HL[0]/10%10+'0';

 

Alarm_HI_LO_STR[6]=Alarm_Temp_HL[0]%10+'0';

 

//屏蔽高位不显示

 

if(Alarm_HI_LO_STR[4]=='0')Alarm_HI_LO_STR[4]=' ';

 

if(Alarm_HI_LO_STR[4]==' '&&Alarm_HI_LO_STR[5]=='0')

 

Alarm_HI_LO_STR[5]=' ';

 

//"-"符号显示

 

if(ng){

 

if(Alarm_HI_LO_STR[5]==' ')Alarm_HI_LO_STR[5]='-';

 

else if(Alarm_HI_LO_STR[4]==' ')Alarm_HI_LO_STR[4]='-';

 

else Alarm_HI_LO_STR[3]='-';

 

}

 

//低温报警值

 

ng=0;

 

if(Alarm_Temp_HL[1]<0)//如果为负数则取反加1

 

{

 

Alarm_Temp_HL[1]=~Alarm_Temp_HL[1]+1;

 

ng=1;

 

}

 

//分解高温各数位到待显示串中

 

Alarm_HI_LO_STR[12]=Alarm_Temp_HL[1]/100+'0';

 

Alarm_HI_LO_STR[13]=Alarm_Temp_HL[1]/10%10+'0';

[1] [2]
关键字:单片机 引用地址:基于单片机的智能温度监测系统设计

上一篇:基于单片机的LCD1602电子时钟设计
下一篇:基于单片机的电子钟设计

推荐阅读最新更新时间:2024-11-12 21:05

英飞凌用于工业照明应用的全新XMC™单片机亮相展会
2017年3月21日,英飞凌科技股份公司(FSE代码:IFX / OTCQX代码:IFNNY)携基于ARM®的全新XMC™单片机以及基于iMotion™的电机控制解决方案,亮相2017年国际嵌入式系统展。XMC单片机适用于多种工业应用,其新特性包括提供研发支持,以大幅降低设计复杂度、缩短研发周期、削减系统成本,以及帮助加快完成经DALI认证的LED设计。 电机控制专用iMOTION解决方案平台阵容壮大 英飞凌推出新一代iMOTION电机控制解决方案。其目标应用包括家用电器、空调系统、泵机、风扇和多轴飞行器等。全新iMOTION 2.0可将系统成本降低约30%,并且极其易于实现。它能让电机在10分钟内运转起来。这得益于面向磁场定
[单片机]
51单片机ADC0809电压表(12864显示,程序 + 仿真)
51单片机ADC0809电压表(12864显示,程序 + 仿真)并口;0~5V先上图正常工作图 上图:最大电压值 上图渐变电压值(最大到最小) 这是仿真图,可以进行仿真 #include reg51.h #include LCD12864.h sbit OE=P3^6; sbit EOC=P3^7; sbit CLOCK=P3^0; sbit ST=P3^3; void Lcd12864_Display(); unsigned char dat = 0.000V ; unsigned int tmp; unsigned char adc; void main() { EA=1; ET0=1; T
[单片机]
51<font color='red'>单片机</font>ADC0809电压表(12864显示,程序 + 仿真)
单片机或者嵌入式系统的开发规范化问题
随着人才流动的加快和研发周期的缩短,我们个人需要快速高效的完成自己的设计,维护和升级,公司需要人走不影响项目进度、新员工很快就能接手。这就需要:一个系统设计完成以后,它不应该仅仅是一些源代码,还应该包括各种各样的开发文档。(这对以后自己对系统的维护和升级都有很好的参考作用。而且能最大情况的避免一种情况:你改了一个BUG,却发现又出现了很多个BUG。)一个系统开发完成,它究竟应该包含那些文档,这些文档一般是怎么完成的,应该包含哪些内容?这就是系统开发的规范化问题。系统开发的规范化不仅有利于自己,也有利于公司,更有利于新手。规范化的设计让工程师工作更高效,这已经是不用争论的事实。现在在大型软件工程开发方面,这已经做得相当好。但在单片机和
[单片机]
单片机VB6对汉字的处理
在DOS时代,拥有一个华丽的汉字菜单几乎是每个高档中文应用程序必须的包装。中文Windows操作系统的出现使得高级开发平台实现全中文的提示和界面非常容易和方便。在一般的应用程序中已经很少需要去专门考虑汉字处理的问题。 但是在许多工程控制和字符串处理的环境中,汉字字符的处理仍然有别于西文字符的处理,需要加以专门的考虑。 一、VB6对汉字处理的支持 对汉字处理,VB6主要是提供了一些输入法设置方面的支持。它提供了一个ImeMode属性和ImeStatus函数来确定和设置输入法的状态。而且此属性和方法只在VB6的东亚区版本中有效。 IMEStatus函数返回一个整数,用来指定当前Windows的输入法(IME)方式。
[单片机]
<font color='red'>单片机</font>VB6对汉字的处理
[MSP430] 对MSP430单片机__delay_cycles精确延时的说明及改正
在这里, 我来讨论一下关于MSP430单片机使用__delay_cycles延时的问题. IAR for MSP430编译器提供了一个编译器内联的精确延时函数(并非真正的 函数)以提供用户精确延时使用, 该函数原型是: __intrinsic void __delay_cycles(unsigned long __cycles); 该内部函数实现__cycles个CPU周期的延时,但对于该参数的设置,我要陈述一下: __cycles需要我们传递的是CPU运行的周期个数 网上普遍的用法是: #define CPU_CLOCK 8000000 #define delay_us(us
[单片机]
avr单片机流水灯和按键抗干扰
第一次做。都是用的avr单片机ATMEGA16仿真。。有3个按键控制流水灯程序 和1个单片机按键抗干扰,左右按键要松开才行. 单片机源码: #include iom16v.h void delay(unsigned int x) { int i,j; for(i=0;i x;i++) for(j=0;j 1141;j++); } void button(int i) { if((PINC&(1 PC0))==0) { delay(20); if((PINC&(1 PC0))==0) { up(i); } while((PINC&(1 PC0))==0); } if((PINC&(1 PC1))==0) { del
[单片机]
avr<font color='red'>单片机</font>流水灯和按键抗干扰
一种基于路灯补偿电容的电缆防盗系统设计
实际应用中照明线路电缆时常出现被盗情况,不仅给国家带来损失,也严重影响了生产生活轶序。为防止电缆被盗,根据目前节能路灯照明系统采用单灯补偿电容的特性,设计了电缆防盗系统。 1 系统整体设计 电缆上所有照明电灯是并联的,电缆上的每个照明电灯又可以等效为灯丝电阻和电容的并联,因而在电缆的一端即可测得线路上并联路灯电容的大小。如果有电缆被盗,则在电缆一端测得的总电容就会减小。根据测到的电容大小,就能判断电灯的个数,再结合电缆电灯的物理拓扑,即可判断出电缆被盗的具体地点。为将电灯的电容特性,用电信号来展示,文中使用了常见的555芯片,用555芯片构成多谐振荡器,由多谐振荡器的周期公式T=(R1+2R2),Cln2可知,可将电灯的电
[单片机]
一种基于路灯补偿电容的电缆防盗系统设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved