温度采集.docx
《温度采集.docx》由会员分享,可在线阅读,更多相关《温度采集.docx(30页珍藏版)》请在冰豆网上搜索。
温度采集
基于单片机多路温度采集报警系统
绪论:
温度检测是现代检测技术的重要组成部分,在保证产品质量、节约能源和安全生产等方面起着关键的作用。
本次课程设计课程设计正是问了完成温度采集而设计的,可以说与人们的日常生活息息相关的,具有很大的现实意义。
任务要求
系统由5个模块组成:
主控制器、温度采集电路、温度显示电路、报警控制电路及键盘输入控制电路。
系统采用智能温度传感器DS18B20检测环境温度并进行简单的模数转换,单片机AT89C51执行程序对温度传感器传输的数据进行进一步的分析处理,转换成环境对应温度值,通过1602LCD显示。
由键盘输入控制选择某一采集电路,检测温度并显示,报警电路对设定的最高/最低极限温度进行监控报警。
1、原理图
(1)
、模块原理图
(2)、电路仿真图
2、模块电路分析
(1)、单片机最小系统
在智能化仪器仪表中,控制核心均为微处理器,而单片机以高性能、高速度、体积小、价格低廉、稳定可靠而得到广泛应用,是设计智能化仪器仪表的首选微控制器,单片机结合简单的接口电路即可构成单片机最小系统,它是智能化仪器仪表的基础,也是测控。
监控的重要组成部分。
它包括电平转换电路、时钟电路和复位电路。
采用STC89C52RC作为核心芯片。
电路原理如下:
1、如果P0不用,那J34上拉电阻也不需要,用到哪个IO就在哪个IO上加上拉电阻。
如果是一个P口的8个IO都要用,就统一用排阻(SIP9封装)。
2、有一个电源指示灯。
3、下载线只要把P3.0P3.1引出来接实验箱或下载线即可。
4、有一个晶振12M或11.0592M,两个小电容20p。
5、复位电路的手动复位按键(S54)可要,可不要。
单片机最小系统原理图
(2)、温度采集电路
用三个智能温度传感器DS18B20分别与AT89C51相连,用着三个温度传感器检测环境温度并进行简单的模数转换,送人单片机内。
(3)、上下限控制电路
用四个按钮控制。
其中两个按钮分别上限的加减,另外两个按钮分别为下限的加减。
当温度到达上限或下限时报警器报警,当报警器报警时可通过增加上限或者降低下限使报警器停止工作。
(4)、蜂鸣报警电路
将三极管和蜂鸣器相连,再将三极管与89c51相连,构成蜂鸣电路。
当显示电压达到或超过上限\下限电压时报警。
(五)、1602显示模块
(6)、实物图
3、元器件介绍
(1)、AT89C51
VCC:
供电电压。
GND:
接地。
P0口:
P0口为一个8位漏级开路双向I/O口,每脚可吸收8TTL门电流。
当P0口的管脚第一次写1时,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的低八位。
在FIASH编程时,P0口作为原码输入口,当FIASH进行校验时,P0输出原码,此时P0外部必须接上拉电阻。
P1口:
P1口是一个内部提供上拉电阻的8位双向I/O口,P1口缓冲器能接收输出4TTL门电流。
P1口管脚写入1后,被内部上拉为高,可用作输入,P1口被外部下拉为低电平时,将输出电流,这是由于内部上拉的缘故。
在FLASH编程和校验时,P1口作为低八位地址接收。
P2口:
P2口为一个内部上拉电阻的8位双向I/O口,P2口缓冲器可接收,输出4个TTL门电流,当P2口被写“1”时,其管脚被内部上拉电阻拉高,且作为输入。
并因此作为输入时,P2口的管脚被外部拉低,将输出电流。
这是由于内部上拉的缘故。
P2口当用于外部程序存储器或16位地址外部数据存储器进行存取时,P2口输出地址的高八位。
在给出地址“1”时,它利用内部上拉优势,当对外部八位地址数据存储器进行读写时,P2口输出其特殊功能寄存器的内容。
P2口在FLASH编程和校验时接收高八位地址信号和控制信号。
P3口:
P3口管脚是8个带内部上拉电阻的双向I/O口,可接收输出4个TTL门电流。
当P3口写入“1”后,它们被内部上拉为高电平,并用作输入。
作为输入,由于外部下拉为低电平,P3口将输出电流(ILL)这是由于上拉的缘故。
P3口也可作为AT89C51的一些特殊功能口,如下表所示:
口管脚备选功能
P3.0RXD(串行输入口)
P3.1TXD(串行输出口)
P3.2/INT0(外部中断0)
P3.3/INT1(外部中断1)
P3.4T0(计时器0外部输入)
P3.5T1(计时器1外部输入)
P3.6/WR(外部数据存储器写选通)
P3.7/RD(外部数据存储器读选通)
P3口同时为闪烁编程和编程校验接收一些控制信号。
RST:
复位输入。
当振荡器复位器件时,要保持RST脚两个机器周期的高电平时间。
ALE/PROG:
当访问外部存储器时,地址锁存允许的输出电平用于锁存地址的低位字节。
在FLASH编程期间,此引脚用于输入编程脉冲。
在平时,ALE端以不变的频率周期输出正脉冲信号,此频率为振荡器频率的1/6。
因此它可用作对外部输出的脉冲或用于定时目的。
然而要注意的是:
每当用作外部数据存储器时,将跳过一个ALE脉冲。
如想禁止ALE的输出可在SFR8EH地址上置0。
此时,ALE只有在执行MOVX,MOVC指令是ALE才起作用。
另外,该引脚被略微拉高。
如果微处理器在外部执行状态ALE禁止,置位无效。
/PSEN:
外部程序存储器的选通信号。
在由外部程序存储器取指期间,每个机器周期两次/PSEN有效。
但在访问外部数据存储器时,这两次有效的/PSEN信号将不出现。
/EA/VPP:
当/EA保持低电平时,则在此期间外部程序存储器(0000H-FFFFH),不管是否有内部程序存储器。
注意加密方式1时,/EA将内部锁定为RESET;当/EA端保持高电平时,此间内部程序存储器。
在FLASH编程期间,此引脚也用于施加12V编程电源(VPP)。
XTAL1:
反向振荡放大器的输入及内部时钟工作电路的输入。
XTAL2:
来自反向振荡器的输出。
AT89C51内部功能图:
(二)、LCD1602
1602字符型LCD通常有14条引脚线或16条引脚线的LCD,多出来的2条线是背光电源线VCC(15脚)和地线GND(16脚),其控制原理与14脚的LCD完全一样。
四、实验步骤:
(一)、原理图绘制
1、添加原理图元件库
2、摆放元件
3、连接电路,防止重叠、交叉
4、修改元件属性、元件的封装、元件命名、元件参数
(二)、新建元件封装
1、原理图元件:
从原理图元件库中调出的符号。
2、元件实物:
一般有特定的外形,引脚排列。
3、元件封装:
将原理图元件与元件实物联系在一起,是组成PCB板的基础。
焊盘的间距与实物引脚间距相同,内部标号与原理图标号一致,保证实际引脚与原理图引脚对应。
(三)、导入元件封装库及网络表
(四)、仿真电路,看电路是否成功。
(五)、焊接电路
1、用PCB板,将元件摆放好,逐个用焊锡焊接好。
2、用焊锡将需连接的引脚连接起来。
3、分别用焊锡连一条电源线路和一条接地线路,连接每个需接电路或接地的引脚。
4、检查电路。
五、程序:
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
sbitRS=P2^0;//lcd控制位
sbitRW=P2^1;//lcd读写
sbitE=P2^2;//lcd使能
sfrLCD=0x80;//定义lcd为P0口
sbitBF=P0^7;
sbitsound=P1^7;//警报
sbitk1=P3^0;//set
sbitk2=P3^1;//+
sbitk3=P3^2;//-
sbitk4=P3^3;//选择18B20标号
sbitk5=P3^4;//退出
sbitwarning=P3^6;
sbitgreenled=P3^7;//485收发控制
charmax[3];//门限
charmin[3];
uchartemp_number;//18b20标号
ucharchange_flag;//修改门限标志
ucharstop;//突出设置
ucharstr[6]={0,0,0,0,0,0};
ucharcodestr3_sht11[]="set";
ucharcodestr4_sht11[]="max:
min:
";
ucharcodestr7_sht11[]="NO.";//清除没不要的显示
voiddelay(uintz)
{
uintx,y;
for(x=z;x>0;x--)
for(y=110;y>0;y--);
}
voidserial_int()
{
TMOD=0X10;//t1工作在方式2
TH1=0x00;//2400BIT/S
TL1=0x00;
TR1=1;//打开计数器开始计数
ET1=1;
//EA=1;
//ES=1;
}
voidtimer_isr()interrupt3//中断0,用来让喇叭发出警报
{
TH1=0x00;//
TL1=0x00;
sound=~sound;
}
/****************************************/
////////////LCDmodule//////////
/***************************************/
voidlcd_cmd(ucharcmd)//LCD写命令
{
LCD=cmd;
RS=0;
RW=0;
E=0;
_nop_();
E=0;
while
(1)
{LCD=0xff;
RS=0;
RW=1;
E=0;
_nop_();
E=1;
if(BF==0)break;
}
}
voidlcd_dat(uchardat)//LCD写数据
{
LCD=dat;
RS=1;
RW=0;
E=1;
_nop_();
E=0;
while
(1)
{LCD=0xff;
RS=0;
RW=1;
E=0;
_nop_();
E=1;
if(BF==0)break;
dat=LCD;
}
}
voidinit_lcd(void)//lcd初始化
{
lcd_cmd(0x01);//清屏
lcd_cmd(0x3c);
lcd_cmd(0x0c);
}
voiddisp_str(ucharx,uchary,uchar*p)//显示各个温度值
{
if(x==0)
lcd_cmd(0x80+y);
else
lcd_cmd(0xc0+y);
while(*p)
lcd_dat(*p++);
}
voiddisplay_1602()//开机显示温度
{
uchari;
str[1]=':
';
for(i=0;i<3;i++)
{str[0]=0x31+i;
disp_str(i/2,(i%0x02)*9,str);
}
}
voidlcd_set(ucharnumber,charmax,charmin)//显示门限设置值
{
ucharx1,x2,x3,x4;
ucharflag_max,flag_min;
if(max<0)
{
flag_max=1;
max=-max;
}
else
flag_max=0;
if(min<0)
{
flag_min=1;
min=-min;
}
else
flag_min=0;
x1=max/10;
x2=max%10;
x3=min/10;
x4=min%10;
lcd_cmd(0xc4);
lcd_dat(number+0x30);
lcd_cmd(0xc8);
if(flag_max==1)
lcd_dat('-');
lcd_dat(x1+0x30);
lcd_dat(x2+0x30);
lcd_cmd(0xcd);
if(flag_min==1)
lcd_dat('-');
lcd_dat(x3+0x30);
lcd_dat(x4+0x30);
}
/****************************************/
////////////KEYmodule//////////
/****************************************/
voidkey1()//选择门限模式:
maxormin
{
if(k1==0)
{
stop=1;
change_flag++;
if(change_flag>2)
change_flag=0;
}
while(k1==0);
}
voidkey2()//+
{
if(k2==0)
{
if(change_flag==1)
max[temp_number]++;
if(change_flag==2)
min[temp_number]++;
}
while(k2==0);
}
voidkey3()//-
{
if(k3==0)
{
if(change_flag==1)
max[temp_number]--;
if(change_flag==2)
min[temp_number]--;
}
while(k3==0);
}
voidkey4()//选择18b20标号
{
if(k4==0)
{
temp_number++;
if(temp_number>3)
{
stop=0;
change_flag=0;
temp_number=0;
}
}
while(k4==0);
}
voidkey5()//退出
{
if(k5==0)
{
stop=0;
change_flag=0;
}
while(k5==0);
}
voidkey()//按钮
{
key2();
key1();
key3();
key4();
key5();
}
/****************************************/
//////////18B20module/////////
/****************************************/
sbitDQ=P1^0;
bdatauchardat;
sbitdat0=dat^0;
sbitdat7=dat^7;
/*ucharcodeid[4][8]={{0x28,0xe6,0xce,0x11,0x04,0x00,0x00,0x2c},//0x28,0xe6,0xce,0x11,0x04,0x00,0x00,0x2c
{0x28,0xa8,0xf4,0x11,0x04,0x00,0x00,0x73},//0x28,0xa8,0xf4,0x11,0x04,0x00,0x00,0x73
{0x28,0x35,0xd5,0x11,0x04,0x00,0x00,0xbd},//0x28,0x35,0xd5,0x11,0x04,0x00,0x00,0xbd
};*/
ucharcodeid[3][8]={{0x28,0x30,0xc5,0xb8,0x00,0x00,0x00,0x8e},
{0x28,0x31,0xc5,0xb8,0x00,0x00,0x00,0xb9},
{0x28,0x32,0xc5,0xb8,0x00,0x00,0x00,0xe0},
};
voiddelay15(ucharn)//延时
{do{
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
_nop_();
n--;
}while(n);
}
voidlate()//延时
{uchari;
for(i=0;i<200;i++)delay15(200);
}
bitreset(void)//18b20复位
{biterr;
DQ=0;
delay15(40);
DQ=1;
delay15(10);
err=DQ;
delay15(18);
return(err);
}
voidwrbyte(uchard)//18b20写
{uchari;
dat=d;
for(i=8;i>0;i--)
{DQ=0;
delay15
(1);
DQ=dat0;
dat=dat>>1;
delay15
(1);
DQ=1;
}
}
ucharrdbyte(void)//18b20读
{uchari;
dat=0;
for(i=8;i>0;i--)
{dat=dat>>1;
DQ=0;
_nop_();
DQ=1;
delay15
(2);
dat7=DQ;
delay15(4);
}
return(dat);
}
/*
voidreadid(ucharid[])//18b20读ID
{ucharn;
reset();
wrbyte(0x33);
for(n=0;n<=8;n++)
id[n]=rdbyte();
}
*/
voidgettemp(inttemp[])//获取18b20温度
{ucharm,n;
ucharh,l;
reset();
wrbyte(0xcc);
wrbyte(0x44);
late();
for(m=0;m<3;m++)
{reset();
wrbyte(0x55);
for(n=0;n<8;n++)
wrbyte(id[m][n]);
wrbyte(0xbe);
l=rdbyte();
h=rdbyte();
temp[m]=h*256+l;
}
}
externvoidinit_lcd(void);
externvoiddisp_str(ucharx,uchary,uchar*p);
externvoidgettemp(inttemp[]);
externvoidreadid(uchar*id);
uchardp[16]={0,0,1,1,2,3,3,4,5,5,6,6,7,8,8,9};
uchartable[]="warningNO.i";
main()
{
inttemp[3];
uchara=1,b=1;
ucharnn,num;
bitzf;
uchari;
warning=0;
greenled=1;
serial_int();//中断初始化
init_lcd();//LCD初始化
for(i=0;i<3;i++)//初始化门限
{
max[i]=30;
min[i]=-1;
}
while
(1)
{
key();
if((change_flag==0)&&(stop==0))//在正常工作状态
{
key();
if(a==1)//
{b=1;
a=0;
lcd_cmd(0x01);//显示清屏
display_1602();
}
for(i=0;i<3;i++)
gettemp(temp);
for(i=0;i<3;i++)
{zf=0;
if(temp[i]<0)
{zf=1;
temp[i]=-temp[i];
}
str[4]=dp[temp[i]&0x0f]+0x30;
temp[i]=temp[i]>>4;
str[0]=temp[i]/100+0x30;
temp[i]=temp[i]%100;
str[1]=temp[i]/10+0x30;
str[2]=temp[i]%10+0x30;
str[3]='.';
if(zf==1)
{if(str[1]=='0')
{str[0]='';
str[1]='-';
}
else
str[0]='-';
}
else
{if(str[0]=='0')
{if(str[1]=='0')
str[1]='';
str[0]='';
}
}
if(EA==0)
disp_str(i/2,(i%0x02)*9+2,str);
if(zf==1)//判断温度是否为负
temp[i]=-temp[i];
if(((temp[i]>max[i])||(temp[i]{
nn=0;
warning=1;
greenled=0;
nn=0;
EA=1;
table[11]=0x31+i;
lcd_cmd(0x01);//显示清屏
for(num=0;num<12;num++)
{
lcd_dat(table[num]);
delay(20);
}
}
else
{
nn++;//巡检
if(nn>8&&EA==1)//巡检2个轮回,没有超门限,解除警报
{
EA=0;
warning=0;
greenled=1;
lcd_cmd(0x01);//显示清屏
display_1602();
}
}
}
}
else//进入门限设置
{key();
if(b==1)
{
a=1;
b=0;
lcd_cmd(0x01);//显示清屏
lcd_cmd(0x80);//第一行lcd显示地址
for(i=0;i<16;i++)
{
lcd_dat(str4_sht11[i]);//显示table1中的字符
}
lcd_cmd(0xc0);//第一行lcd显示地址
for(i=0;i<16;i++)
{
lcd_dat(