温控制器课设论文.docx
《温控制器课设论文.docx》由会员分享,可在线阅读,更多相关《温控制器课设论文.docx(28页珍藏版)》请在冰点文库上搜索。
温控制器课设论文
本科课设论文
(普通高等教育)
题目温度控制器的设计
学院工学院
专业名称自动化
班级*
学号*
姓名淡淡的
指导教师王东林
目录
题目温度控制器的设计1
(一)系统功能分析2
(二)系统硬件原理图设计2
(三)控制软件功能分析5
1)I2C总线5
2)1602显示6
3)键盘单元7
4)AD转换7
(四)程序模块流程图8
(五)运行结果9
结论9
附录11
元件清单11
程序清单11
(一)系统功能分析
通过温度传感器检测外界的温度,然后经放大接入A/D,和键盘设置的温度值进行比较,来调节控制器对加热器进行控制,使温度保持在设定温度附近,并通过LED显示温度值,如果出现温度异常,通过嗡鸣器进行报警。
以实现温度设置输入、温度显示、温度异常报警、加热执行器控制等功能。
(二)系统硬件原理图设计
单片机引脚图
AT89S51是一个低功耗,高性能CMOS8位单片机,片内含8kBytesISP(In-systemprogrammable)的可反复擦写1000次的Flash只读程序存储器,器件采用ATMEL公司的高密度、非易失性存储技术制造,兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISPFlash存储单元,功能强大的微型计算机的AT89S51可为许多嵌入式控制应用系统提供高性价比的解决方案。
AT89S51具有如下特点:
40个引脚,4kBytesFlash片内程序存储器,128bytes的随机存取数据存储器(RAM),32个外部双向输入/输出(I/O)口,5个中断优先级2层中断嵌套中断,2个16位可编程定时计数器,2个全双工串行通信口,看门狗(WDT)电路,片内时钟振荡器。
此外,AT89S51设计和配置了振荡频率可为0Hz并可通过软件设置省电模式。
空闲模式下,CPU暂停工作,而RAM定时计数器,串行口,外中断系统可继续工作,掉电模式冻结振荡器而保存RAM的数据,停止芯片其它功能直至外中断激活或硬件复位。
同时该芯片还具有PDIP、TQFP和PLCC等三种封装形式,以适应不同产品的需求。
由于系统控制方案简单,数据量也不大,考虑到电路的简单和成本等因素,因此在本设计中选用ATMEL公司的AT89S51单片机作为主控芯片。
主控模块采用单片机最小系统是由于AT89S51芯片内含有4kB的E2PROM,无需外扩存储器,电路简单可靠,其时钟频率为0~24MHz,并且价格低廉,批量价在10元以内。
可以看出AT89S51提供以下标准功能:
4K字节Flash闪速存储器,128字节内部RAM,32个I/O口线,看门狗(WDT),两个数据指针,两个16位定时器/计数器,一个5向量两级中断结构,一个全双工串行通信口,片内振荡器及时钟。
同时,AT89S51可降至0Hz的静态逻辑操作,并支持两种软件可选的节电工作模式。
空闲方式停止CPU的工作,但允许RAM,定时/计数器,串行通信口及中断系统继续工作。
掉电方式何在RAM中的内容,但振荡器停止工作并禁止其它所有部件工作直接到一个硬件复位。
P0口:
P0口是一组8位漏极开路型双向I/O口,也即地址/数据总线复用口,作为输出口用时,每位能驱动8个TTL逻辑门电路,对端口写“1”可作为高阻抗输入端口。
在访问外部数据存储器或程序存储器时,这组口线分时转换地址(低8位)和数据总线复用,在访问期间激活内部上拉电阻。
在Flash编程时,P0口接收指令字节,而在程序校验时,输出指令字节,校验时,要求外接上拉电阻。
P1口:
P1是一个带内部上拉电阻的8位双向I/O口,P1的输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口。
作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号校验期间,P1接收低8位地址。
P2口:
P2是一个带有内部上拉电阻的8位双向I/O口,P2的输出缓冲级可驱动4个TTL逻辑门电路。
对端口写“1”,通过内部的上拉电阻把端口拉到高电平,此时可作输入口,作输入口使用时,因为内部存在上拉电阻,某个引脚被外部信号拉低时会输出一个电流I。
在访问8位地址的外部数据存储器(如执行:
MOVX@Ri指令)时,P2口线上的内(也即特殊功能寄存器,在整个访问期间不改变。
Flash编程或校验时,P2也接收高位地址和其它控制信号。
)
P3口:
P3口是一组带有内部上拉电阻的8位双向I/O口。
P3口输出缓冲级可驱动(吸收或输出电流)4个TTL逻辑门电路。
对P3口写入“1”时,它们被内部上拉电阻拉高并可作为输入端口。
作输入端口时,被外部拉低的P3口将用上拉电阻输出电流I。
P3口除了作为一般的I/O口线外,更重要的用途是它的第二功能
RST:
复位输入。
当振荡工作时,RST引脚出现两个机器周期上高电平将使单片机复位。
WDT益出将使该引脚输出高电平,设置SFRAUXR的DISRTO位(地址8EH)可打开或关闭该功能。
DISRTO位缺省为RESET输出高电平打开状态。
ALE/PROG:
当访问外部程序存储器或数据存储器时,ALE(地址锁存允许)输出脉冲用于锁存地址的低8位字节。
即使不访问外部存储器,ALE仍以时钟振荡频率的1/6输出的正脉冲信号,因此它可对外输出时钟或用于定时目地,要注意的是:
第当访问外部数据存储器时将跳过一个ALE脉冲。
如有必要,可通过对特殊功能寄存器(SFR)区中的8EH单元的D0位置位,可禁止ALE操作。
该位禁位后,只有一条MOVX和MOVC指令ALE才会被激活。
此外,该引脚伎被微弱拉高,单片机执行外部程序时,应设置ALE无效。
PSEN:
程序储存允许(PSEN)输出是外部程序存储器的读选通信号,当AT89S51由外部程序存储器取指令(或数据)时,每个机器周期两次PSEN有效,即输出两个脉冲。
当访问外部数据存储器,高有两次有效的PSEN信号。
EA/VPP:
外部访问允许。
欲使CPU公访问外部程序存储器(地址0000H-FFFFH),EA端必须保持低电平(接地)。
需注意的是:
如果加密位LB1被编程,复位时内部会锁存EA端状态。
如EA端为高电平(接Vcc端),CPU则执行内部程序存储器中的指令。
Flash存储器编程时,该引脚加上+12V的编程电压Vpp。
XTAL1:
振荡器反相放大器及内部时钟发生器的输入端。
XTAL2:
振荡器反相放大器的输出端。
AT89S51单片机内部构造及功能:
特殊功能寄存器:
特殊功能寄存器的片内空间分存如下图3-2所示。
这些地址并没有全部占用,没有占用的地址不可使用,读这些地址将得到一个随意的数值。
而写这些地址单元将不能得到预期的结果。
中断寄存器:
各中断允许控制位于IE寄存器,5个中断源的中断优先级控制位于IP寄存器。
(三)控制软件功能分析
1)I2C总线
a)总线通讯
是同步通信的一种特殊形式,具有接口线少,控制方式简单,器件封装形式小,通信速率较高等优点。
SCL线是高电平时,SDA线从高电平向低电平切换,这个情况表示起始条件;
SCL线是高电平时,SDA线由低电平向高电平切换,这个情况表示停止条件。
起始和停止条件一般由主机产生,总线在起始条件后被认为处于忙的状态
在停止条件的某段时间后总线被认为再次处于空闲状态。
如果产生重复起始条件而不产生停止条件,总线会一直处于忙的状态,此时的起始条件(S)和重复起始条件(Sr)在功能上是一样的。
应用I2C总线通讯来处理cpu与键盘,lcd显示器,A/D转换器的通讯。
b)时钟同步
所有主机在SCL线上产生它们自己的时钟来传输I2C总线上的报文。
数据只在时钟的高电平周期有效,因此需要一个确定的时钟进行逐位仲裁。
时钟同步通过线与连接I2C接口到SCL线来执行。
这就是说SCL线的高到低切换会使器件开始数它们的低电平周期,而且一旦器件的时钟变低电平,它会使SCL线保持这种状态直到到达时钟的高电平。
但是如果另一个时钟仍处于低电平周期,这个时钟的低到高切换不会改变SCL线的状态。
因此SCL线被有最长低电平周期的器件保持低电平。
此时低电平周期短的器件会进入高电平的等待状态。
当所有有关的器件数完了它们的低电平周期后,时钟线被释放并变成高电平。
之后,器件时钟和SCL线的状态没有差别,而且所有器件会开始数它们的高电平周期。
首先完成高电平周期的器件会再次将SCL线拉低。
这样产生的同步SCL时钟的低电平周期由低电平时钟周期最长的器件决定,而高电平周期由高电平时钟周期最短的器件决定。
2)1602显示
想要在LCD1602屏幕的第一行第一列显示一个"A"字,就要向DDRAM的00H地址写入“A”字的代码就行了。
但具体的写入是要按LCD模块的指令格式来进行的,后面我会说到的。
那么一行可有40个地址呀?
是的,在1602中我们就用前16个就行了。
第二行也一样用前16个地址。
对应如下:
DDRAM地址与显示位置的对应关系
a)程序设计思路
检查LCD忙状态
lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据。
写指令数据到LCD
RS=L,RW=L,E=高脉冲,D0-D7=指令码。
写显示数据到LCD
RS=H,RW=L,E=高脉冲,D0-D7=数据。
设定显示位置
清屏子程序
3)键盘单元
单片机应用系统中除了复位按键有专门的复位电路,以及专一的复位功能外,其它的按键或键盘都是以开关状态来设置控制功能或输入数据。
键开关状态的可靠输入:
为了去抖动我采用软件方法,它是在检测到有键按下时,执行一个10ms的延时程序后,再确认该键电平是否仍保持闭合状态电平,如保持闭合状态电平则确认为真正键按下状态,从而消除了抖动影响
在这种行列式矩阵键盘非编码键盘的单片机系统中,键盘处理程序首先执行等待按键并确认有无按键按下的程序段。
当确认有按键按下后,下一步就要识别哪一个按键按下。
对键的识别通常有两种方法:
一种是常用的逐行扫描查询法;另一种是速度较快的线反转法。
K1、K2键作为温度最高限、最低限的设定功能键;K3、K4键作为温度值设定的增加和减小功能键。
K1键:
作为最高限温度的设定功能键。
按一次进入最高限温度设定状态,选择最高限温度值后,再按一次确认设定完成。
K2键:
作为最低限温度的设定功能键。
按一次进入最低限温度设定状态,选择最低限温度值后,再按一次确认设定完成。
K3键:
+1功能键,每一次将温度值加1,范围从1℃到99℃。
K4键:
-1功能键,每按一次将温度值减1,范围从99℃到1℃
4)AD转换
a)平均滤波
1ms采样一次,将N秒内所有数据相加除以N再做标度变换,转化为人们熟悉的摄氏度后在lcd显示屏显示出来
b)定时器初始化
TMOD=0x11;//方式1
TH0=0x3c;//50ms
定时器设置后,可以在lcd上实时显示时间
(四)程序模块流程图
大于或小于
其他
程序开始的时候先设置初始化,然后就控制数码管显示当前温度。
接着就判断给定温度按键是否被按下。
按下进入温度控制点1的程序。
程序控制设置按下超过10ms,此时键盘输入有效。
有按键按下的时候进入按键处理程序。
然后则进行模数转换将温度值传给lcd显示,并与设定值相比较,若大于或小于设定值则报警,若在设定范围内则显示normal。
(五)运行结果
顺利实现要求功能,通过AD转换可以将模拟信号转换为数字信号,标度变换后显示出0-99摄氏度范围的温度,在与规定范围值比较后作出报警或正常的响应。
结论
在工业生产和日常生活中,对温度控制系统的要求,主要是保证温度在一定温度范围内变化,稳定性好,不振荡,对系统的快速性要求不高。
在论文中简单分析了单片机温度控制系统设计过程及实现方法。
本系统的测温范围为0℃~100℃,温度检测系统根据用户设定的温度范围完成一定范围的温度控制。
参考文献
1曹巧媛主编.单片机原理及应用(第二版).北京:
电子工业出版社,2002
2全国大学生电子设计竞赛组委会编.第五届全国大学生电子设计竞赛获奖作品选编(2001),北京:
北京理工大学出版社,2003
3何力民编.单片机高级教程.北京:
北京航空大学出版社,2000
4金发庆等编.传感器技术与应用.北京机械工业出版社,2002
5王锦标,方崇智.过程计算机控制.北京:
清华大学出版社,1997;36~40
6邵惠鹤.工业过程高级控制.上海:
上海交通大学出版社,1997;58—62,78—101
附录
元件清单
ADC0809芯片1
1602lcd显示屏1
单片机开发板1
程序清单
1602:
#include
#include
#include<_1602.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitLCD_RS=P2^6;
sbitLCD_RW=P2^5;
sbitLCD_EN=P2^7;
/*******************************************************************/
/*
/*延时子程序
/*
/*******************************************************************/
voiddelay(intms)
{
inti;
while(ms--)
{
for(i=0;i<250;i++)
{
}
}
}
/*******************************************************************/
/*
/*检查LCD忙状态
/*lcd_busy为1时,忙,等待。
lcd-busy为0时,闲,可写指令与数据。
/*
/*******************************************************************/
bitlcd_busy()
{
bitresult;
LCD_RS=0;
LCD_RW=1;
LCD_EN=1;
_nop_();
_nop_();
_nop_();
_nop_();
result=(bit)(P0&0x80);
LCD_EN=0;
returnresult;
}
/*******************************************************************/
/*
/*写指令数据到LCD
/*RS=L,RW=L,E=高脉冲,D0-D7=指令码。
/*
/*******************************************************************/
voidlcd_wcmd(ucharcmd)
{
while(lcd_busy());
LCD_RS=0;
LCD_RW=0;
LCD_EN=0;
_nop_();
_nop_();
P0=cmd;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN=1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN=0;
}
/*******************************************************************/
/*
/*写显示数据到LCD
/*RS=H,RW=L,E=高脉冲,D0-D7=数据。
/*
/*******************************************************************/
voidlcd_wdat(uchardat)
{
while(lcd_busy());
LCD_RS=1;
LCD_RW=0;
LCD_EN=0;
P0=dat;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN=1;
_nop_();
_nop_();
_nop_();
_nop_();
LCD_EN=0;
}
/*******************************************************************/
/*
/*设定显示位置
/*
/*******************************************************************/
voidlcd_pos(ucharpos)
{
lcd_wcmd(pos|0x80);//数据指针=80+地址变量
}
/*******************************************************************/
/*
/*LCD初始化设定
/*
/*******************************************************************/
voidlcd_init()
{
delay(15);//等待LCD电源稳定
lcd_wcmd(0x38);//16*2显示,5*7点阵,8位数据
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x38);
delay(5);
lcd_wcmd(0x0c);//显示开,关光标
delay(5);
lcd_wcmd(0x06);//移动光标
delay(5);
lcd_wcmd(0x01);//清除LCD的显示内容
delay(5);
}
/*******************************************************************/
/*
/*清屏子程序
/*
/*******************************************************************/
voidlcd_clr()
{
lcd_wcmd(0x01);//清除LCD的显示内容
delay(5);
}
/*******************************************************************/
/*
/*闪动子程序
/*
/*******************************************************************/
voidflash()
{
delay(600);//控制停留时间
lcd_wcmd(0x08);//关闭显示
delay(200);//延时
lcd_wcmd(0x0c);//开显示
delay(200);
lcd_wcmd(0x08);//关闭显示
delay(200);//延时
lcd_wcmd(0x0c);//开显示
delay(200);
}
lcd_wstr(char*str)
{
uchari=0;
while(str[i]!
='\0')
{
lcd_wdat(str[i]);
i++;
}
}
D/AA/D:
#include
#include
#include<_1602.H>
#definePCF85910x90//PCF8591地址
#defineN7
unsignedcharAD_CHANNEL;
unsignedlongxdataLedOut[8];
unsignedlonga;
unsignedlongb;
inti;
intmiao;
intfen;
intshi;
charnum;
charn;
charmax=80;
charmin=10;
sbitK1=P1^0;
sbitK2=P1^1;
sbitK3=P1^2;
sbitK4=P1^3;
sbitK5=P1^4;
sbitK6=P1^6;
sbitbeep=P1^5;
charaa[4];
chartemp[]={"temp:
"};
chartime[]={"time:
"};
charnormal[]={"normal"};
charupwarn[]={"upwarn"};
chardownwarn[]={"downwarn"};
charnull[]={""};
charL[]={"L:
"};
charH[]={"H:
"};
charjishi[6];
bitISendByte(unsignedcharsla,unsignedcharc)
{
Start_I2c();//启动总线
SendByte(sla);//发送器件地址
if(ack==0)return(0);
SendByte(c);//发送数据
if(ack==0)return(0);
Stop_I2c();//结束总线
return
(1);
}
unsignedcharIRcvByte(unsignedcharsla)
{unsignedcharc;
Start_I2c();//启动总线
SendByte(sla+1);//发送器件地址
if(ack==0)return(0);
c=RcvByte();//读取数据0
Ack_I2c
(1);//发送非就答位
Stop_I2c();//结束总线
return(c);
}
intget_ad()//ad转换
{
ISendByte(PCF8591,0x41);
a=IRcvByte(PCF8591);
returna;
}
intfilter()//平均滤波
{
charcount;
intvalue_buf[N];
longsum=0;
for(count=0;count{
value_buf[count]=get_ad();
delay
(1);//1ms采样一次
}
for(count=0;coun