非接触传感器单片机温度检测系统
单片机课程设计任务书
前 言
目前国内的测温手段主要依靠各种规格的热电偶和热电阻,它们均属接触式测温。在工业生产实际温度检测中,被检测物体有时处于运运状态,难以实现接触式测温, 如钢轨及道岔尖轨淬火过程温度的检测,热电偶等测温手段就无法满足测温要求。医用测温中,一般地应用于测温仪,传统的测温计反应比较慢、使用前需要严格消毒,不适合对多人进行连续温度采集。非接触式测温计所需测温时间短,不需要与体肤接触,避免了病菌交叉感染,并且可以进行数据记录与判断,实时检测和记录系统,非常适合在大型集会或各类活动中使用。
非接触传感器单片机测温系统设计主要包括主要芯片的选择及其功能简单介绍、系统硬件电路和软件程序设计。
当今世界,随着科学与技术的不断提高,各个领域对方便快捷的自动化的要求不断提高。所以,研制非接触温度检测系统,对工业中运动物体温度控制和医疗事业的发展具有重要意义。
目 录
前 言 . ............................................................... 1
目 录 . ............................................................... 3
摘 要 . ............................................................... 4
第一章 主要芯片的选择 . ............................................... 5
1.1 STC89C52单片机 . .............................................. 5
1.2 非接触式温度传感器OTP-538U . .................................. 6
1.3 LM324四运放 . ................................................. 7
1.4 ADC0809 ...................................................... 7
1.5 1602字符型LCD ............................................... 8
第二章 系统硬件电路的设计 . ........................................... 9
2.1 温度采集和放大电路 ........................................... 9
2.2 ADC转换电路 . ............................................... 10
2.3 液晶显示电路 ................................................ 10
2.4 键盘控制电路 ................................................ 11
2.5 报警电路 .................................................... 11
2.6系统原理图 . .................................................. 12
第三章 系统软件系统的设计 . .......................................... 13
3.1 程序流程图 .................................................. 13
3.2 源程序 ...................................................... 13
第四章 系统调试与性能 . .............................................. 23
结束语 . ............................................................. 24
参考文献 . ........................................................... 25
摘 要
本设计以STC89S52 单片机为核心部件。利用集合非接触式温度传OTP-538U 对温度进行采样, 通过微处理系统电路AD 转换接口电路、数据采集接u 电路、数码显示电路等主要组成电路,实现了非接触温度检测功能。
本文所研究的非接触传感器单片机测温系统由于对被测物体的辐射进行的是非接触无损测量,测量过程中不会扰乱被测部分的温度场,响应快、温度分辨率高。
关键词:STC89S52 非接触传感器 ADC0809
第一章 主要芯片的选择
1.1 STC89C52单片机
STC89C52具有以下标准功能:8k 字节Flash ,256字节RAM ,32 位I/O 口线,看门狗定时器,2 个数据指针,三个16 位定时器/计数器,一个6向量2级中断结构,全双工串行口,片内晶振及时钟电路。另外,AT89S52 可降至0Hz 静态逻辑操作,支持2种软件可选择节电模式。空闲模式下,CPU 停止工作,允许RAM 、定时器/计数器、串口、中断继续工作。掉电保护方式下,RAM 内容被保存,振荡器被冻结,单片机一切工作停止,直到下一个中断或硬件复位为止。
图1.1 89C52引脚
P0 口:P0口是一个8位的双向I/O口。当它用作输出口时,每位能驱动8个TTL 逻辑电平。对P0端口写“1”时,引脚用作高阻抗输入。
P1 口:P1 口是一个具有内部上拉电阻的8 位双向I/O 口,p1 输出缓冲器能驱动4 个TTL 逻辑电平。当对P1 端口写“1”时,内部得上拉电阻把端口拉高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL )。
P2 口:P2 口是一个具有内部上拉电阻的8 位双向I/O 口,P2 输出缓冲器能驱动4 个TTL 逻辑电平。对P2 端口写“1”时,内部的上拉电阻就会把端口拉
高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL )。
P3 口:P3 口是一个具有内部上拉电阻的8 位双向I/O 口,p2 输出缓冲器能驱动4 个TTL 逻辑电平。当我们对P3 端口写“1”时,内部上拉电阻把端口拉高,此时可以作为输入口使用。作为输入使用时,被外部拉低的引脚由于内部电阻的原因,将输出电流(IIL )。P3口亦作为AT89S52特殊功能(第二功能)使用。在flash 编程和校验时,P3口也可以接收一些控制信号。
RST: 复位输入。晶振工作时,RST 脚持续2 个机器周期高电平将使单片机复位。如果看门狗计时完成,RST 脚输出96 个晶振周期的高电平。特殊寄存器AUXR(地址8EH) 上的DISRTO 位可以使此功能无效ALE/PROG:地址锁存控制信号(ALE )是访问外部程序存储器时,锁存低8 位地址的输出脉冲。在flash 编程时,此引脚(PROG )也用作编程输入脉冲。一般情况下,ALE 以晶振六分之一的固定频率输出脉冲,这个脉冲可用来作为外部定时器或时钟使用。
PSEN:外部程序存储器选通信号(PSEN )是外部程序存储器选通信号。当 AT89S52从外部程序存储器执行外部代码时,PSEN 在每个机器周期被激活两次,但是在访问外部数据存储器时,PSEN 将不被激活。
EA/VPP:访问外部程序存储器控制信号。为使能从0000H 到FFFFH 的外部程序存储器读取指令,EA 必须接GND 。为了执行内部程序指令,EA 应该接VCC 。在flash 编程期间,EA 也接收12伏VPP 电压。
XTAL1:振荡器反相放大器和内部时钟发生电路的输入端。
XTAL2:振荡器反相放大器的输出端。
1.2 非接触式温度传感器OTP-538U
OTP- 538U 是一个典型的TO-46系列热电堆传感器。该传感器包含了116组串联的热接点,形成了一个直径545μm 的感应区。涂黑的表面活性吸收热红外辐射,导致两输出端产生电压差。该传感器芯片采用了了一个独特的前表面微加工技术,使得尺寸更小,能更快速地响应环境温度变化的结果。红外窗口是一个带通滤波器,允许测量波长在5μm 至14μm 之间。与电阻相互比较热敏元件总是存在白色杂讯。对应不同频率他都有一个稳定的讯号,直到频率极限,并正比于入射辐射。
热电堆传感器的特色在于与温度参考电阻器在同一块基座上。温度参考电阻是由外壳至接地。特点是非接触式温度探测、电压输出,便于检测、零功耗元件。
1.3 LM324四运放
LM324是四运放集成电路,它采用14脚双列直插塑料封装。它的内部包含四组形式完全相同的运算放大器,除电源共用外,四组运放相互独立。
每一组运算放大器有5个引出脚,其中“+”、“-”为两个信号输入端,“V+”、“V-”为正、负电源端,“Vo”为输出端。两个信号输入端中,Vi-(-)为反相输入端,表示运放输出端Vo 的信号与该输入端的相位相反;Vi+(+)为同相输入端,表示运放输出端Vo 的信号与该输入端的相位相同。LM324的引脚排列见图1.2。
1.4 ADC0809
图1.2 ADC0809引脚图和内部结构
功能和特性:8路8位A /D 转换器,即分辨率8 位。具有转换起停控制端。转换时间是100μs 。单个+5V 的 电源供电。模拟输入电压范围0~+5V 。正常工作温度范围为-40~+85 摄氏度。低功耗,只有约15mW 。
内部结构:ADC0809 是CMOS 单片型逐次逼近式A /D 转换器,内部结构如图5 所示,它由8 路模拟开关、地址锁存与译码器、比较器、8位开关树型D /A 转换器、逐次逼近,寄存器、三态输出锁存器等其它一些电路组成。因此,ADC0809 可处理8路模拟量输入,且有三态输出能力,既可与各种微处理器相连,也可单独工作。输入输出与TTL 兼容。
ADC0809的工作过程如下:1、送通道地址,以选择要转换的模拟输入;2、锁存通道地址到内部地址锁存器;3、启动 A/D 变换;判断转换是否结束;4、读转换结果;5、A/D转换完成数据的输送;6、A/D 转换后得到的是数字量的模拟量,这些数据应传诵给单片机进行处理。
1.5 1602字符型LCD
1602字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD ,目前常用16*1,16*2,20*2和40*2行等的模块。
1602LCD 的基本参数及引脚功能
液晶显示模块是一个慢显示器件,所以在执行每条指令之前一定要确认模块的忙标志为低电平,表示不忙,否则此指令失效。要显示字符时要先输入显示字符地址,也就是告诉模块在哪里显示字符,图1.3是1602的内部显示地址。
图1.3 1602LCD内部显示地址
在对液晶模块的初始化中要先设置其显示模式,在液晶模块显示字符时光标是自动右移的,不需要人工干预。每次输入指令前都要判断液晶模块是否处于忙的状态,如果不是才可以输入。
1602液晶模块内部的字符发生存储器(CGROM )已经存储了160个不同的点阵字符图形,这些字符有:阿拉伯数字、英文字母的大小写、常用的符号、和日文假名等,每一个字符都有一个固定的代码。
第二章 系统硬件电路的设计
硬件系统可以分为:单片机控制模块,温度传感器模块,信号放大模块,ADC 转换模块,液晶显示模块,键盘输入模块,报警模块,电源模块。
该系统使用STC89C52单片机作为核心,由温度传感器采集环境温度和被测人员体温信号,通过放大和AD 转换后,送单片机处理。由键盘输入被测人员编号,液晶显示系统提示和数据输出。单片机进行数据判断,如果超标则送信号给报警模块,开始报警。系统由电源模块供电。
图2.1
系统硬件总体框架图
2.1 温度采集和放大电路
2.2 ADC转换电路
2.3 液晶显示电路
2.4 键盘控制电路
2.5 报警电路
考虑到体积和功耗的因素,本设计使用了PNP 三极管驱动蜂鸣器;用红色发光二极管作为发光报警。
2.6系统整体电路
第三章 系统软件系统的设计
3.1 程序流程图
上电后,系统先进行初始化,按下开始键后显示环境温度。单片机依次开始调用键盘扫描子程序、温度信号处理子程序,经过判断温是否正常和测量是否结束,来确定测量子程序是否循环运行。主程序流程图如图3.1所示。
图3.1 软件流程图
3.2 源程序
#include #include #include
unsigned int data bai,shi,ge;
unsigned long int idata temp,temp1,tp; unsigned char data dis[5];
unsigned char code table[]={ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39}; unsigned char code w[]={0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09}; unsigned char data Code5[]="NO:";
unsigned char data Code6[]="GET READY!"; unsigned char data Code7[]="AMBIENT TEMP:" ; unsigned char data Code8[]="INPUT DONE!";
unsigned char data Code9[]="PRESS TO RECALL" ; int i,j,k; k=0;
unsigned char idata a[5][6]; unsigned long int idata pp[7]; unsigned char m;
unsigned char xdata key; sbit ACS=P3^3; sbit ALE=P3^4; sbit START=P3^5; sbit OE=P3^6; sbit EOC=P3^7;
sbit LCDRS=P3^0; 数据指令控制 sbit LCDRW=P3^1; 读写控制
sbit LCDEN=P3^2; 液晶屏使能控制
延时函数,延时n*1ms void delay(unsigned char n) {
int i,j; for (i=0; i
for (j=0; j
延时函数,延时n*1ms void delay1(unsigned char n) {
int i,j; for (i=0; i
for (j=0; j
//void free() {
while(1) {
P1 = 0xf0; if(P1==0xf0) break; } }
//写命令
void Write_Cmd(unsigned char C) {
LCDEN=1; 使能端,由高电平跳变成低电平时,液晶屏模块执行命令
LCDRS=0; 指令寄存器选择
P0=C; delay(5); LCDEN=0; }
//写数据
void Write_Data(unsigned char D) {
LCDEN=1; 使能端,由高电平跳变成低电平时,液晶屏模块执行命令 LCDRS=1; 选择数据寄存器 P0=D; delay(5); LCDEN=0; }
//LCD初始化 void LCD_Init() {
LCDRS=0; 指令寄存器选择 Write_Cmd(0x01); 清屏
Write_Cmd(0x38); 功能设置8位双行显示5*7点阵 Write_Cmd(0x0F); 开关显示设置
Write_Cmd(0x06); 输入方式设置,光标从左向右移动,内容不移动 }
//void welcome() {
unsigned char Code1[]="WELCOME TO THE"; unsigned char Code2[]="TEMP SYSTEM!"; unsigned char m;
LCDRW=0; 写选择 LCD_Init(); P1 = 0xfe;
Write_Cmd(0x01);
Write_Cmd(0x80+0x01); 写入显示缓冲区起始地址为1行2列 for(m=0;m
Write_Data(Code1[m]); delay1(30); 滚动延时 }
Write_Cmd(0xc0+0x02); 写入显示缓冲区起始地址为2行3列 for(m=0;m
Write_Data(Code2[m]); delay1(30); }
delay1(1000); 静态显示 Write_Cmd(0x08); delay1(500); 闪烁延时 Write_Cmd(0x0f); delay1(500); 闪烁延时
Write_Cmd(0x08); 闪烁延时
delay1(500);
Write_Cmd(0x0f); }
//void start() {
P1 = 0xfe; while(1) {
if (P1 == 0xee) { delay(5); if (P1 == 0xee) {
free(); break; } } } }
//void ok() {
P1 = 0xfe; while(1) {
if (P1 == 0xbe) { delay(5); if (P1 == 0xbe) {
free(); break; } } } }
//void inputnumber() {
unsigned char Code3[]="INPUT A NUMBER!"; unsigned char Code4[]="NO:";
unsigned char m;
LCDRW=0;//写选择
Write_Cmd(0x01);
Write_Cmd(0x80+0x01); 写入显示缓冲区起始地址为1行2列
for(m=0;m
Write_Data(Code3[m]); delay(3); }
Write_Cmd(0xc0+0x01); 写入显示缓冲区起始地址为1行2列
for(m=0;m
Write_Data(Code4[m]); delay(3); } }
// unsigned char adc() {
ALE=0; START=0; OE=0; EOC=1;
ALE=1;_nop_();_nop_();ALE=0;
START=1;_nop_();_nop_();START=0; _nop_();_nop_();_nop_();_nop_(); while(EOC==0) ;
OE=1; temp1=P2; OE=0;
//temp1=128;
temp=temp1*19400/(49600-temp1*194);
if(temp
LCDRW=0; 写选择 Write_Cmd(0xc5);
Write_Data(table[w[bai]]); Write_Data(table[w[shi]]); Write_Data(0x2e);
Write_Data(table[w[ge]]); Write_Data(0x44); Write_Data(0x45); Write_Data(0x47); return tp; }
//unsigned char adc2() {
ALE=0; START=0; OE=0; EOC=1;
ALE=1;_nop_();_nop_();ALE=0;
START=1;_nop_();_nop_();START=0; _nop_();_nop_();_nop_();_nop_(); while(EOC==0)
;
OE=1; temp1=P2; OE=0;
tp=temp1*194;
pp[k]=tp; k++;
bai=tp/10000;
shi=tp%10000/1000; ge=tp%1000/100;
LCDRW=0; 写选择 Write_Cmd(0xc5);
Write_Data(table[w[bai]]); Write_Data(table[w[shi]]); Write_Data(0x2e);
Write_Data(table[w[ge]]); Write_Data(0x44); Write_Data(0x45); Write_Data(0x47); return tp; }
//unsigned char sckey() {
while(1) { P1=0xf0; if(P1!=0xf0) { delay(5); if(P1!=0xf0) {
P1=0xfe; if(P1!=0xbe) {
delay(5); if(P1!=0xbe) break; } } } }
P1 = 0xfe; if(P1!=0xfe) {
delay(5); if(P1!=0xfe) {
switch (P1) {
case 0xde : key = '0'; free(); break; case 0xee : key = '/'; free();
break;
} } }
P1 = 0xfd; if(P1!=0xfd) {
delay(5); if(P1!=0xfd) {
switch (P1) {
case 0xed : key = '1'; free(); break; case 0xdd : key = '2'; free(); break; case 0xbd : key = '3'; free(); break; } } }
P1 = 0xfb; if(P1!=0xfb) {
delay(5); if(P1!=0xfb) {
switch (P1) {
case 0xeb : key = '4'; free(); break; case 0xdb : key = '5'; free(); break; case 0xbb : key = '6'; free(); break; } } }
P1 = 0xf7; if(P1!=0xf7) {
delay(5); if(P1!=0xf7) {
switch (P1)
{
case 0xe7 : key = '7'; free(); break; case 0xd7 : key = '8'; free(); break; case 0xb7 : key = '9'; free(); break; } } }
return key; }
main() {
P1=0x80; 关报警 welcome(); start();
Write_Cmd(0x01); Write_Cmd(0x82); for(m=0;m
Write_Data(Code7[m]); delay(3); }
ACS=1; 环境温度 tp=adc(); ok();
for(i=0;i
inputnumber(); for(j=0;j
a[i][j] = sckey(); Write_Cmd(0xc4+j); Write_Data(a[i][j]); P1=0xfe; 确定按钮不显示 }while(P1==0xbe); }
LCDRW=0; 写选择 Write_Cmd(0x01);
Write_Cmd(0x80+0x03); for(m=0;m
Write_Data(Code5[m]); delay(3); }
for(j=0;j
Write_Cmd(0x86+j);
Write_Data(a[i][j]);
}
Write_Cmd(0xC0+0x03);
for(m=0;m
{
Write_Data(Code6[m]);
delay(3);
}
ok();
Write_Cmd(0x01);
Write_Cmd(0x80+0x03);
for(m=0;m
{
Write_Data(Code5[m]);
delay(3);
}
for(j=0;j
{
Write_Cmd(0x86+j);
Write_Data(a[i][j]);
}
ACS=0;
tp = adc2();
ok();
}
LCDRW=0;写选择
Write_Cmd(0x01);
Write_Cmd(0x82);
for(m=0;m
{
Write_Data(Code8[m]);
delay(3);
}
Write_Cmd(0xc0);
for(m=0;m
{
Write_Data(Code9[m]);
delay(3);
}
ok();
while(1)
{
for(i=0;i
{
Write_Cmd(0x01);
Write_Cmd(0x80+0x03);
for(m=0;m
{
Write_Data(Code5[m]);
delay(3);
}
for(j=0;j
非接触传感器的单片机温度检测系统 显示编号和温度 显示编号和温度
{
Write_Cmd(0x86+j);
Write_Data(a[i][j]);
}
tp = pp[i];
bai=tp/10000;
shi=tp%10000/1000;
ge=tp%1000/100;
LCDRW=0;//写选择
Write_Cmd(0xc5);
Write_Data(table[w[bai]]);
Write_Data(table[w[shi]]);
Write_Data(0x2e);
Write_Data(table[w[ge]]);
Write_Data(0x44);
Write_Data(0x45);
Write_Data(0x47);
ok();
}
}
}
非接触传感器的单片机温度检测系统
第四章 系统调试与性能
需要检测当前温度和记录历史温度,决定用四个画面分别用于显示当前的温度和历史温度。为了达到形象直观的目的,当前温度使用仪表和实时曲线同时显示,历史温度使用历史曲线的方式显示。当温度超出规定的范围,使用声光报警。实时温度检测部分如图4.1所示。
图4.1 实时温度界面
实时曲线显示当前温度,如图4.2所示。
图4.2 实时趋势曲线图
结束语
通过此次设计我的理论知识和实践得到了很大的提高,单片机课堂学习已经过了一段时间,刚开始设计时不知从何下手,对C 语言程序设计不太熟悉,proteus 和protel99se 等软件的使用也不太熟练。通过查阅相关的书籍、资料和老师、同学的指导、帮助,最终完成设计。本人在弱电方面知识水平比较有限,设计过程中碰到很多问题不能很快地找到有效方法解决,浪费很多时间走了很多弯路。欣慰的是,还是找到了比较适合的方式解决。
衷心感谢指导老师徐老师的悉心指导,万分感谢同学们的热心帮助。老师严明严谨的治学态度深深影响了我,同学的帮助帮我解决了很多难题,谢谢你们!
参考文献
[1] 郭天祥. 51单片机C 语言教程—入门、提高、开发、拓展全攻略. 北京: 电子工业出版社. 2008
[2] 李玉峰、倪虹霞. MCS-51系列单片机原理与接口技术. 第一版. 北京:人民邮电出版社. 2004
[3] 周兴华. 手把手教你学单片机. 第一版. 北京:北京航空航天大学出版社. 2005
[4] 曾一江. 单片微机原理与接口技术. 第一版. 北京:科学出版社. 2006
[5] 吕泉. 现代传感器原理及应用. 第一版. 北京:清华大学出版社. 2006.