红外恒温控制器的设计与制作Word下载.docx
《红外恒温控制器的设计与制作Word下载.docx》由会员分享,可在线阅读,更多相关《红外恒温控制器的设计与制作Word下载.docx(70页珍藏版)》请在冰豆网上搜索。
AT89C51是一种低功耗,高性能的片内含有4KB快闪可编程/擦除只读存储器(FPEROM—FlashProgrammableandErasableReadOnlyMemory)的8位COMS微控制器,使用高密度,非易失存储技术制造,并且与80C51引脚和指令系统完全兼容。
芯片上的FPEROM允许在线编程或采用通用的非易失存储编程器对存储器重复编程。
AT89C51(以下简称89C51)将具有多种功能的8位CPU与FPEROM结合在一个芯片上,为很多嵌入式控制应用提供了非常灵活而又便宜的方案,其性能价格比远高于8751。
由于片内带EPROM的87C51价格偏高,而片内带FPEROM的89C51价格低且与INTEL80C51兼容,这就显示出了89C51的优越性。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器。
89C51有40个引脚,有32个输入端口(I/O),2个读/写端口,程序存储器可以擦出。
2.1.2AT89C51单片机信号引脚介绍
输入输出口线:
P0.1-P0.7P0口8位三态I/O口
P1.0-P1.7P1口8位双向I/O口
P2.0-P2.7P2口8位双向I/O口
P3.0-P3.7P3口8位双向I/O口
主电源引脚(2根)
VCC:
电源输入,接+5V电源
GND:
接地线
外接晶振引脚(2根)
XTAL1:
片内晶振电路的输入端
XTAL2:
片内晶振电路的输出端
控制引脚(4根)
RST/VPP:
复位引脚,引脚上出现2个机器周期的高电平将使单片机复位。
ALE/PROG:
地址所存允许信号。
PSEN:
外部存储器读选通讯信号。
EA/VPP:
程序存储器的内外部选通,接低电平从外部程序存储器读指令,如果接高电平则从内部程序存储器读指令
2.1.3AT89C51单片机时钟和复位电路
1、时钟电路:
单片机内部有一个高增益反向放大器,输入端引脚为XTAL1,输出端引脚为XTAL2。
而在芯片外部XTAL1和XTAL2之间跨接晶体振荡器和微调电容,从而构成一个稳定的自激振荡器。
晶体振荡频率高,则系统的时钟频率也高,单片机运行速度也就快,但反过来运行速度快对存储器的速度要求就高,对印制电路板的要求也高,所以,这里使用振荡频率为6MHZ的石英晶体。
振荡电路产生的振荡脉冲并不直接使用,而是经分频后再为系统所用,震荡脉冲经过二分频后才作为系统的时钟信号。
在设计电路板时,振荡器和电容应尽量靠近单片机,以避免干扰。
需要注意的是:
设计电路板时,振荡器和电容应尽量安装得与单片机靠近一些,这样可以减少寄生电容的存在,可以更好的保障振荡器稳定、可靠的工作,电路图如图2所示。
图2
复位电路:
单片机的复位电路分上电复位和按键复位两种方式。
(a)上电复位:
上电复位是利用电容从电来实现的,即上电瞬间RST/Vpd端的电位与Vcc相同,随着从电电流的减少,RST/Vpd的电位下降,最后被牵制在0V。
复位时要保证加在RST引脚上的高电平持续两个机器周期,才能使单片机有效复位。
在应用系统中,为了保证复位电路可靠地工作,常在R、C电路先接施密特电路,然后再接入单片机复位端。
这样,当系统有多个复位端时,能保证可靠地同步复位,且具有抗干扰作用。
(b)按键复位:
按键复位是在调试程序或者程序运行不正常时手动复位使程序重新运行,程序运行出错或操作错误使系统处于死锁状态时,为了摆脱困境,也需按复位键以重新启动。
RST引脚是复位信号的输入端,复位信号是高电平有效。
按键复位又分按键脉冲复位(图3)和按键电平复位。
电平复位将复位端通过电阻与Vcc相连,按键脉冲复位是利用RC分电路产生正脉冲来达到复位的。
图3
2.2电源电路:
2.3温度传感器
PT100是一个温度传感器,是一种稳定性和线性都比较好的铂丝热电阻传感器,可以工作在-200℃至650℃的范围.PT100温度感测器是一种以白金(Pt)作成的电阻式温度检测器,属于正电阻系数,其电阻和温度变化的关系式如下:
R=Ro(1+αT) 其中α=0.00392,Ro为100Ω(在0℃的电阻值),T为摄氏温度<
br>
因此白金作成的电阻式温度检测器,又称为PT100。
1:
Vo=2.55mA×
100(1+0.00392T)=0.255+T/1000。
温度测量转换部分是整个系统的数据来源,直接影响系统的可靠性。
本设计用的温度测量方法是:
用PT100将测量的温度转换成模拟电信号,再经过A/D转换器把模拟信号转换成数字信号,最后由单片机再对采集的数字信号进行处理。
PT100温度测量电路,温度传感器PT100是一种稳定性和线性都比较好的铂丝热电阻传感器,可以工作在-200至650的范围,本电路选择其工作在0-100范围。
整个电路分为两部分,一是传感器前置放大电路,一是单片机A/D转换和显示,控制,软件非线性校正等部分。
前置放大部分原理图如下:
工作原理:
传感器的接入非常简单,从系统的+5V供电端仅仅通过一个阻值可变的滑动电阻就连接到PT100了,这种接法通常会引起严重的非线性问题,但是由于有个单片机的软件进行校正,也就简化了传感器的接入方式。
按照PT100的参数我们得出在0到100℃的区间内,电阻值为100至138.51欧姆,我们按照其串联分压的接法,使用公式:
Vcc/(PT100+?
)*PT100=输出电压(mv)可以计算出其在整百摄氏度时的输出电压,见下面的表格1:
温度℃
PT100阻值欧姆
传感两端电压mv
100.00
124.38
1
100.39
124.8
50
119.40
147.79
100
138.51
170.64
2.4键盘和显示电路
模块电路如图4.键盘采用行列式和外部中断相结合的方法,各按键的功能定义如下表格2.其中设置键与单片机的INT0脚相连,S0-S9、YES、NO用四行三列接单片机P0口,REST键为硬件复位键,与R、C构成复位电路。
表格2按键功能
按键
键名
功能
REST
复位键
使系统复位
SET
设置键
使系统产生中断,进入设置状态
S0-S9
数字键
设置用户需要的温度
YES
确认键
用户设定目标温度后进行确认
NO
清除键
用户设定温度错误或误按了YES键后使用
图4键盘接口电路
2.5程序设计
软件程序设计如下:
#include<
reg51.h>
#include<
absacc.h>
intrins.h>
ziranshu.h>
voidmain()
{
C_port=0x03;
//8155初始化
time0init();
//定时器0初始化
lcdinit();
//液晶显示初始化
while
(1)
{
Key_scan();
dischange();
compare();
display();
}
}
voidtime0init()
TMOD=0x11;
TH0=-50000/256;
TL0=-50000%256;
TH1=-50000/256;
TL1=-50000%256;
EA=1;
ET0=1;
ET1=1;
TR1=0;
TR0=1;
voidlcdinit()
wrcommand(0x01);
wrcommand(0x38);
wrcommand(0x06);
wrcommand(0x0c);
voidwrcommand(uchardat)
delay(200);
rs=0;
rw=0;
en=1;
Port_A=dat;
en=0;
voidwrdata(uchardat)
rs=1;
voiddelay(uintdat)
while(dat--);
}
voidmdelay(ucharx)
uchari;
for(;
x>
0;
x--)
for(i=0;
i<
125;
i++);
}
voiddischange()
if(play==2)
{
mode=U_Sec/7+1;
if(mode==9)
mode=8;
AD_value=read1543(mode-1);
if(play==6)
voidcompare()
ucharcount0;
uintvalue0;
count0=mode;
value1=(uint)(((100.0*AD_value)/1024)*10);
value0=(value1+9)/10;
switch(count0)
case1:
if(value0>
temp_updata1||value0<
temp_downdata1)
play=6;
TR1=1;
}
if(value0<
=temp_updata1&
&
value0>
=temp_downdata1)
{
if(play==6)
{
play=2;
TR1=0;
}
break;
case2:
temp_updata2||value0<
temp_downdata2)
=temp_updata2&
=temp_downdata2)
case3:
temp_updata3||value0<
temp_downdata3)
=temp_updata3&
=temp_downdata3)
case4:
temp_updata4||value0<
temp_downdata4)
=temp_updata4&
=temp_downdata4)
case5:
temp_updata5||value0<
temp_downdata5)
=temp_updata5&
=temp_downdata5)
case6:
temp_updata6||value0<
temp_downdata6)
=temp_updata6&
=temp_downdata6)
case7:
temp_updata7||value0<
temp_downdata7)
=temp_updata7&
=temp_downdata7)
case8:
temp_updata8||value0<
temp_downdata8)
=temp_updata8&
=temp_downdata8)
//default:
play=2;
//break;
voiddisplay()
if(play==1)//显示姓名和学号
lcd_string(name,1);
lcd_string(number,2);
if(play==2)//自动显示温度值
change(mode,AD_value);
lcd_string(time,1);
lcd_string(count,2);
}//手动显示温度值
if(play==3)
ucharmode1;
uintAD_value1=1024;
mode1=keyvalue;
AD_value1=read1543(mode1-1);
change(mode1,AD_value1);
if(play==4)//温度上下限显示
ucharcc=1,dd=20,ee=50;
cc=temp_play;
if(cc==1)
dd=temp_downdata1;
ee=temp_updata1;
if(cc==2)
dd=temp_downdata2;
ee=temp_updata2;
if(cc==3)
dd=temp_downdata3;
ee=temp_updata3;
if(cc==4)
dd=temp_downdata4;
ee=temp_updata4;
if(cc==5)
dd=temp_downdata5;
ee=temp_updata5;
if(cc==6)
dd=temp_downdata6;
ee=temp_updata6;
if(cc==7)
dd=temp_downdata7;
ee=temp_updata7;
if(cc==8)
dd=temp_downdata8;
ee=temp_updata8;
temp_change(cc,dd,ee);
lcd_string(temp_name,1);
if(play==5)//时间设定显示
time_change();
lcd_string(time_name,1);
ucharaaaaa,bbbbb,ccccc;
uintddddd;
//alarm_mode=mode;
//alarm_value=value0;
ccccc=mode;
ddddd=value1;
if(ccccc==1)
aaaaa=temp_downdata1;
bbbbb=temp_updata1;
if(ccccc==2)
aaaaa=temp_downdata2;
bbbbb=temp_updata2;
if(ccccc==3)
aaaaa=temp_downdata3;
bbbbb=temp_updata3;
if(ccccc==4)
aaaaa=temp_downdata4;
bbbbb=temp_updata4;
if(ccccc==5)
aaaaa=temp_downdata5;
bbbbb=temp_updata5;
if(ccccc==6)
aaaaa=temp_downdata6;
bbbbb=temp_updata6;
if(ccccc==7)
aaaaa=temp_downdata7;
bbbbb=temp_updata7;
if(ccccc==8)
aaaaa=temp_downdata8;
bbbbb=temp_updata8;
alarm_change(aaaaa,bbbbb,ccccc,ddddd);
lcd_string(time,1);
voidchange(ucharnum,uintvalue)
uintaddata;
addata=((100.0*value)/1024)*10;
count[0]='
m'
;
count[1]='
o'
count[2]='
d'
count[3]='
e'
count[4]='
'
count[5]=num+0x30;
count[6]='
count[7]='
count[8]='
count[9]=0x30;
count[10]=(addata%1000)/100+0x30;
count[11]=(addata%100)/10+0x30;
count[12]='
.'
count[13]=addata%10+0x30;
count[14]=0xdf;
count[15]='
C'
time[0]='
z'
time[1]='
i'
time[2]='
time[3]='
time[4]='
n'
time[5]='
g'
time[6]='
time[7]='
s'
h'
u'
time[8]=U_Hour/10+0x30;
time[9]=U_Hour%10+0x30;
time[10]='
:
'
time[11]=U_Min/10+0x30;
time[12]=U_Min%10+0x30;
time[13]='
time[14]=U_Sec/10+0x30;
time[15]=U_Sec%10+0x30;
voidtemp_change(ucharccc,ucharddd,uchareee)
if(flash==1)
count[