单片机测温系统论文

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

摘要:本设计采用4位数码管显示系统,以AT89S52单片机为核心,由键盘、温度采集,温度上限报警等功能模块组成。

系统采用数字温度传感器DS18B20采集温度数据,数码管同步显示上限温度设定值和当前测量值。

可通过按键以1℃的步进改变上限温度设定值,系统复位后上限报警温度默认为30℃。

当测试温度高于报警温度上限值时,蜂鸣器就会报警。

关键字:单片机DS18B20 数码管蜂鸣器报警
基于DS18B20测温的单片机温度控制系统
一、功能要求:
(1)能测量环境温度信息,要求能用2位或多位LED显示。

(2)要求具有报警功能,当温度超过报警温度上限时要能报警,报警上限要能够通过键盘设定。

(3)电源能通过计算机的USB口供电,以节约制作成本。

二、方案论证:
1.显示部分:
显示部分是本次设计的重要组成部分,一般有以下两种方案:
方案一:
采用LCD显示。

LCD液晶显示具有丰富多样性、灵活性、电路简单、易于控制而且功耗小等优点,对于信息量多的系统,是比较适合的。

方案二:
采用LED显示。

虽然译码驱动装置较多,但也很方便,主要成本低。

且本设计只需要显示温度,信息量不大。

经过综合考虑,采取方案二。

2.温度采集:
方案一:
采用热敏电阻,可满足40摄氏度至90摄氏度测量范围,但热敏电阻精度、重复性、可靠性较差,对于检测小于1摄氏度的信号是不适用的。

方案二:
采用温度传感器DS18B20。

DS18B20可以满足从-55摄氏度到+125摄氏度测量范围,且DS18B20测量精度高,增值量为0.5摄氏度,在一秒内把温度转化成数字,测得的温度值的存储在两个八位的RAM中,单片机直接从中读出数据转换成十进制就是温度,使用方便。

基于DS18B20的以上优点,我们决定选取DS18B20来测量温度
三、总体方案:
系统结构框图
系统主要包括数据采集模块,单片机控制模块,显示模块和温度设置模块,
驱动电路五个部分。

系统框图如图1 所示。

其中数据采集模块负责实时采集温度数据,采集到的温度数据传输到单片
机,由单片机处理后的数据送显示部分显示。

设置模块可设置预定温度,当检测温度高于报警上限温度时,蜂鸣器将会报警。

图1. 系统框图
四、系统硬件设计:
1. AT89S52单片机最小系统:
最小系统包括晶体振荡电路、复位开关和电源部分。

图2为AT89S52单片机的最小系统。

图2 最小系统电路图
2.温度测量模块:
温度测量传感器采用DALLAS公司DS18B20的单总线数字化温度传感器,测温范围为-55℃~125℃,可编程为9位~12位A/D转换精度,测温分辨率达到0.0625℃,采用寄生电源工作方式,CPU只需一根口线便能与DS18B20通信,占用CPU口线少,可节省大量引线和逻辑电路。

接口电路如图3所示。

图3
DS18B20测量电路
3.蜂鸣器报警模块:
蜂鸣器需要三极管放大电流来驱动,一开始由于使用的电阻太大,导致电流较小,蜂鸣器不响,后来并了一个电阻就好了。

电路如图4所示:
图4 报警电路
4.LED显示模块:
显示部分选用4位共阳数码管。

由于数码管的驱动电流较大,所以在设计时加上了三极管9013作为驱动电路。

数码管和单片机的接口如图5所示:
图5数码管显示电路5.整体电路:
系统电路如图6
图6 整体电路
(1)主程序流程图
图7主程序流程图(2
图8 中断程序流程图
AT89S52 是一种低功耗、高性能CMOS8位微控制器,具有
8K 在系统可编程 Flash 存储器。

使用Atmel 公司高密度非易
失性存储器技术制造,与工业80C51 产品指令和引脚完全兼
容。

片上Flash允许程序存储器在系统可编程,亦适于常规编
程器。

在单芯片上,拥有灵巧的8 位CPU 和在系统可编程
Flash,使得AT89S52为众多嵌入式控制应用系统提供高灵活、
超有效的解决方案。

AT89S52具有以下标准功能: 8k字节
Flash,256字节RAM,32 位I/O 口线,看门狗定时器,2 个
数据指针,三个16 位定时器/计数器,一个6向量2级中断
结构,全双工串行口,片内晶振及时钟电路。

另外, AT89S52引脚图AT89S52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。

空闲模式下,CPU 停止工作,允许RAM、定时器/计数器、串口、中断继续工作。

掉电保护方式下,RAM内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。

DS18B20是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器。

与传统的热敏电阻相比,他能够直接读出被测温度并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。

可以分别在93.75 ms和750 ms内完成9位和12位的数字量,并且从DS18B20读出的信息或写入DS18B20的信息仅需要一根口线(单线接口)读写,温度变换功率来源于数据总线,总线本身也可以向所挂接的DS18B20供电,而无需额外电源。

因而使用DS18B20可使系统结构更趋简单,可靠性更高。

他在测温精度、转换时间、传输距离、分辨率等方面较DS1820有了很大的改进,给用户带来了更方便的使用和更令人满意的效果。

DS18B20工作原理
DS18B20的读写时序和测温原理
与DS1820相同,只是得到的温度值
的位数因分辨率不同而不同,且温度
转换时的延时时间由2s 减为750ms。

DS18B20测温原理如图所示。

图中低
温度系数晶振的振荡频率受温度影
响很小,用于产生固定频率的脉冲信
号送给计数器1。

高温度系数晶振随温度变化其振荡率明显改变,所产生的信号作为计数器2的脉冲输入。

计数器1和温度寄存器被预置在-55℃所对应的一个基数值。

计数器1对低温度系数晶振产生的脉冲信号进行减法计数,当计数器1的预置值减到0时,温度寄存器的值将加1,计数器1的预置将重新被装入,计数器1重新开始对低温度系数晶振产生的脉冲信号进行计数,如此循环直到计数器2计数到0时,停止温度寄存器值的累
加,此时温度寄存器中的数值即为所测温度。

图中的斜率累加器用于补偿和修正测温过程中的非线性,其输出用于修正计数器1的预置值。

DS18B20的初始化
(1)先将数据线置高电平“1”。

(2)延时(该时间要求的不是很严格,但是尽可能的短一点)
(3)数据线拉到低电平“0”。

(4)延时750微秒(该时间的时间范围可以从480到960微秒)。

(5)数据线拉到高电平“1”。

(6)延时等待(如果初始化成功则在15到60毫秒时间之内产生一个由DS18B20所返回的低电平“0”。

据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时控制)。

(7)若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第(5)步的时间算起)最少要480微秒。

(8)将数据线再次拉高到高电平“1”后结束。

DS18B20的写操作
(1)数据线先置低电平“0”。

(2)延时确定的时间为15微秒。

(3)按从低位到高位的顺序发送字节(一次只发送一位)。

(4)延时时间为45微秒。

(5)将数据线拉到高电平。

(6)重复上(1)到(6)的操作直到所有的字节全部发送完为止。

(7)最后将数据线拉高。

DS18B20的读操作
(1)将数据线拉高“1”。

(2)延时2微秒。

(3)将数据线拉低“0”。

(4)延时15微秒。

(5)将数据线拉高“1”。

(6)延时15微秒。

(7)读数据线的状态得到1个状态位,并进行数据处理。

(8)延时30微秒。

六、系统调试:
下图为系统测试的当前温度值,显示在4位LED数码管上。

下图为系统进入中断,设置报警上限温度。

下图为系统电路板的反面焊接详情。

八、参考文献
[1]童诗白,华成英.模拟电子技术基础[M].北京:高等教育出版社,2006
[2]阎石主编数字电子技术基础北京:高等教育出版社,1998
[3]邹应全 51系列单片机原理与实验教程西安电子科技大学出版社,2007
[4]/
程序:
#include"reg52.h"
#include<stdio.h>
#define Alarm 10
sbit DQ=P2^4;
sbit Beep=P3^4;
unsigned char tempL=0,tempH=0;
unsigned char flag=0;
unsignedinttemperature,negtemper;
unsigned char idataaddrdat[2]={0x0,0x0};
unsigned char
tab[]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};
unsigned char
tab1[]={0x40,0x79,0x24,0x30,0x19,0x12,0x02,0x78,0x00,0x10}; unsigned char dispbuf[3]={0,0,0};
unsigned char warning=30;
bit on=1,off=0;
void delay(unsigned int i)
{
while(i--)
}
void beep(bit i)
{
Beep=i;
}
void Init_DS18B20(void) //初始化程序
{
unsigned char x=0;
DQ=1; //DQ先置高
delay(8); //稍延时
DQ=0; //发送复位脉冲
delay(85); //延时(>480us)
DQ=1; //拉高数据线
delay(14); //等待(15—60us)
x=DQ;
delay(20);
}
ReadOneChar(void)
{
unsigned char i=0; //主机数据线先从高电平拉至低电平unsigned char dat=0; //保持1ms以上,再使数据线for(i=8;i>0;i--) //升为高电平,从而产生读信号,每个{DQ=1; //读周期最短的持续时间为60us,各个读
delay(1); //周期之间必须有1ms以上的高电平恢复期
DQ=0;
dat>>=1;
DQ=1;if(DQ)
dat|=0x80;
delay(4);
}
return(dat);
}
voidWriteOneChar(unsigned char dat)
{ //数据线从高电平拉至低电平,产生写unsigned char i=0; //起始信号,15ms之内将所需写的位送for(i=8;i>0;i--) //到数据线上,在15—60ms之间对数据线{ //进行采样,如果是高电平就写1,低就写0 DQ=0; //在开始另一个写周期前必须有1ms以上的高电平
DQ=dat&0x01; //恢复期
delay(5);
DQ=1;
dat>>=1;
}
delay(4);
}
ReadTemperature(void)
{
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的操作
WriteOneChar(0x44); //启动温度转换
delay(125); //转换需要一点时间,延时
Init_DS18B20(); //初始化
WriteOneChar(0xcc); //跳过读序列号的操作
WriteOneChar(0xbe); //读温度寄存器
tempL=ReadOneChar(); //读出温度的低位LSB
tempH=ReadOneChar(); //读出温度的高位MSB
temperature=(tempH*256)+tempL; //温度转换,对高、低位做相应return(temperature); //的运算,转化为实际温度
}
voidDispbuf(unsigned int temper)
{
unsigned char temp;
dispbuf[2]=(temper>>4)/10; //取十位
dispbuf[1]=(temper>>4)%10; //取各位
temp=temper&0x0F;
dispbuf[0]=temp * 625/1000; //小数近似处理
}
unsigned char getkey() //键盘扫描
{
P2=0xff;
if (P2==0xfe)
{
delay(12000);
if (P2!=0xfe) ;
else return P2;
}
if (P2==0xfd)
{
delay(12000);
if (P2!=0xfd) ;
else return P2;
}
if (P2==0xfb)
{
delay(12000);
if (P2!=0xfb) ;
else return P2;
}
}
Inter0_process() interrupt 2 //外部中断1
{
unsigned char key;
int i;
unsigned char dis=0x01;
unsignedint j;
for(j=5000;j>0;j--)
{
key=getkey(); //取键值
if(key==0xfe) //如+键按下,则温度值递增
{
warning++;
delay(80);
}
if(key==0xfd) //如-键按下,则温度递减
{
warning--;
delay(80);
}
if(key==0xfb) //按键退出中断
j=1;
for(i=0;i<2;i++) //设置两位报警值,并在LED上显示
{
P1=dis;
dis<<=1;
if(i==0)
P0=tab[warning%10];
else
P0=tab[warning/10];
delay(200);
}
dis=0x01;
}
}
main()
{
unsigned char i,npos=0x01;
P0=0xff;
P2=0xff;
P1=0xff;
EX1=1; //开中断1
IT1=1; //下降沿触发
ET1=1;
EA=1; //开总中断
while(1)
{
if((temperature&0xf000)==0xf000) //判断是否为负温度
{
ReadTemperature();
for(i=0;i<4;i++) //4为LED显示
{
negtemper=(~temperature)+1; //取原码
Dispbuf(negtemper); //取位值
P1=npos;
npos<<=1; //循环使能
if(i==1) //第二位显示有点
{
P0=tab1[dispbuf[i]]; //查表显示
delay(500);
}
else if(i==3) //显示负号
P0=0xbf;
else
{
P0=tab[dispbuf[i]];
delay(500);
}
}
npos=0x01;
}
else //如不是负温度
{
for(i=0;i<3;i++) //显示3位
{
ReadTemperature(); //读温度值
Dispbuf(temperature);
if(((temperature>>4)&0xff)>=warning)//温度值大于报警温//度值则报警
beep(on); //蜂鸣器响
else beep(off); //不响
P1=npos;
npos<<=1; //循环显示
if(i==1)
P0=tab1[dispbuf[i]];
else
P0=tab[dispbuf[i]];
delay(100);
}
npos=0x01;
}
}
}。

相关文档
最新文档