最新版基于单片机的生产车间环境测试仪的毕业设计论文.docx
《最新版基于单片机的生产车间环境测试仪的毕业设计论文.docx》由会员分享,可在线阅读,更多相关《最新版基于单片机的生产车间环境测试仪的毕业设计论文.docx(19页珍藏版)》请在冰豆网上搜索。
最新版基于单片机的生产车间环境测试仪的毕业设计论文
2014届本科生毕业设计分类号:
TP311.52
题目:
基于单片机的生产车间环境测试仪的设计
作者姓名:
陈遥
学号:
学院:
机械与电子工程学院
专业:
自动化
指导教师姓名:
张翠侠陈秀萍
指导教师职称:
讲师工程师
2014年5月9日
摘要
本设计是利用单片机实现温度、湿度等生产环境的测量与控制。
系统采用集温湿度传感器与AD转换器为一体的SHT11芯片,通过单片机处理进行显示,其它模块包括了实时时钟日期产生电路和超限报警处理电路,对所测量的值进行实时显示和报警处理。
本文介绍了基于ATMEL公司的AT89C51系列单片机的温湿度实时测量与控制系统和显示系统的设计,包括介绍了硬件结构原理,并分析了相应的软件的设计及其要点,包括测试精度高等众多的优点。
关键词:
AT89C51;SHT11;LCD;DS1302;温湿度控制
ABSTRACT
Thisdesignisthatusingsinglechipmicrocomputertorealizethetemperatureandenvironment.ThesystemadoptsSHT11chipwhichsettemperatureandcircuitandalarmcircuit,andtheyarerealtimedisplayandalarmprocessingthemeasuredvalue.ThispaperintroducesthedesignoftemperatureandtheAT89C51SeriesMCUofATMELcompany.Thepaperintroducestheandkeypointsofcorrespondingsoftware,includingmanyadvantagessuchastest.
Keywords:
AT89C51;SHT11;LCD;DS1302;Temperatureand公司推出的一款数字温湿度传感器芯片。
温湿度传
感器SHT11集温度传感器和湿度传感器于一体,因此采用SHT11进行温湿度实时
监测的系统具有精度高、成本低、体积小、接口简单等优点。
(2)SHT11的引脚功能
SHT11温湿度传感器采用SMD(LCC)表面贴片封装形式,接口非常简单,引脚
名称及排列顺序如图2所示。
图2SHT11引脚图
各引脚的功能如下:
>>脚1和4--信号地和电源,其工作电压范围是2.4~5.5V;
>>脚2和脚3--二线串行数字接口,其中DA-TA为数据线,SCK为时钟线;
>>脚5~8--未连接。
2.1.2单片机
89C51是一种带4k字节可编程可擦除只读存储器的低电压,高性能CMOS8位微处理器,俗称单片机。
89C2051是一种带2K字节可编程可擦除只读存储器的单片机。
单片机的可擦除只读存储器可以反复擦除100次。
该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。
由于将多功能8位CPU和闪烁存储器组合在单个芯片中,ATMEL的89C51是一种高效微控制器,89C2051是它的一种精简版本。
89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。
它的引脚如图3所示。
图3AT89C51引脚图
2.1.3DS1302
DS1302是DALLAS公司推出的涓流充电时钟芯片,内含有一个实时时钟日历和31字节静态RAM,通过简单的串行接口与单片机进行通信。
实时时钟日历电路提供秒分时日、日期月年的信息。
每月的天数和闰年的天数可自动调整,时钟操作可通过AMPM指示决定采用24或12小时格式。
DS1302与单片机之间能简单地采用同步串行的方式进行通信仅需用到三个口线:
RES复位、IO数据线、SCLK串行时钟。
时钟RAM的读写数据以一个字节或多达31个字节的字符组方式通信,DS1302工作时功耗很低,保持数据和时钟信息时功率小于1mW,引脚如图4所示。
图4DS1302引脚图
2.1.4LCD1604
(1)字符型液晶显示模块是一种专门用于显示字母、数字、符号等点阵式LCD,目前常用16*1,16*2,16*4和20*2行等的模块。
(2)引脚功能说明如表1所示。
表1引脚接口说明表
1604LCD采用标准16脚接口,各引脚接口说明如表
编号
符号
引脚说明
1
VSS
地
2
VDD
正极
3
V0
液晶显示偏压
4
RS
数据命令选择
5
RW
读写选择
6
E
读写信号
7
D0
数据
8
D1
数据
9
D2
数据
10
D3
数据
11
D4
数据
12
D5
数据
13
D6
数据
14
D7
数据
15、16
空脚
1604液晶模块的读写操作,屏幕和光标的操作都是通过指令编程来实现的。
2.2模块功能介绍
2.2.1复位电路部分
这种复位电路的工作原理是:
单片机的复位电路在刚接通电时,刚开始电容是没有电的,电容内的电阻很低,通电后,5V的电通过电阻给电容进行充电,电容两端的电会由0V慢慢的升到4V左右(此时间很短一般小于0.3秒),RC构成的微分电路在上电瞬间产生一个微分脉冲,其宽度大于两个机器周期,89C51将复位。
正因为这样,复位脚的电由低电位升到高电位,引起了内部电路的复位工作,RST端电压慢慢下降,降到一定电压值以后,即为低电平,单片机开始正常工作(这是单片机的上电复位,也叫初始化复位);当按下复位键时,电容两端放电,电容又回到0V了,于是又进行了一次复位工作(这是手动复位原理)。
图5手动复位及晶振电路
2.2.2传感器电路部分
此模块是整个电路设计的信号采集及初步处理的模块,由温湿度传感器芯片
SHT11构成,主要的功能结构在前面的芯片介绍中已有,这里不重新介绍。
图6SHT11传感器电路
2.2.3时钟电路部分
此模块是系统时间的实时显示而设计的,主要由芯片DS1302构成,其中引脚RST、CLK、IO分别接单片机P3.0、P3.1、P3.2口,属于控制引脚。
此模块是产生实时的系统时间和日历,能对某个确定环境的实时温湿度控制起到一定的作用。
芯片连接电路简单,时间日期准确。
图7实时时钟电路
2.2.4显示电路部分
此模块是由LCD1604芯片组成的日期时间和实时温湿度显示的电路部分。
LCD1604是一个四行每行16字的液晶显示屏,D0-D7接P0口,RS、RW、E接P3.5、P3.6、P3.7起控制作用。
图8LCD1604显示及其连接电路
2.2.5超限处理电路部分
此部分电路是由5个发光二极管和一个蜂鸣报警器构成,分别是D0、D1、D2、D4和D5,蜂鸣器接单片机的P1.0口,发光二极管与单片机的连接部分如图所示。
D0、D1、D2、D4、D5分别代表着发光、降温、加热、干燥和加湿,一旦传感器测定的温湿度超过设定的限额,就会产生不同的发光反应,起警示作用,同时蜂鸣报警器连续发出“滴”的声音。
图9超限处理警示电路部分
图10蜂鸣器电路
2.3整体电路图
图11整体电路图
3软件设计
软件设计是本次设计中不可缺少的环节,贯穿了整个毕业设计,是本次设计能够完成的最重要的环节之一。
软件部分经本人调试可以运行,能够正确显示结果。
具体模块由一个C(xc.C)主函数文件和8个h文件构成。
reg51..TheDesignforSteppingMotorofSCMControlSystem[J].Heilongjiang
ScienceandTechnologyInstitute.2005.
(1)
附录
参加课题情况:
参与了宿州学院一般科研项目(批准号2013yyb01):
《生产车间“碳足迹”监测与控制》
源程序:
main.()
{
SYSTEMTIMECurrentTime;定义时间日期结构体
SHT_dataa;定义温湿度测量处理结构体
Initial_DS1302();DS1302初始化*
LCD_Initial();LCD初始化
{GotoXY(0,0);LCD显示函数
Print("Date:
");
GotoXY(16,0);
Print("Temper:
");
GotoXY(0,1);
Print("Time:
");
GotoXY(16,1);
Print("Humidi:
");
while
(1)
{
convert_SHT(&aa,TEMP);温度转换
convert_SHT(&aa,HUMI);湿度转换
caculation_SHT(&aa);温度和湿度的补偿
float_convert(&aa);将浮点数转换成整型,各个位的数分别保存
doing_temp(&aa);检测温度是否超限
doing_(ACC);
}
voidWrite1302(unsignedcharucAddr,unsignedcharucDa)
{
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr);地址,命令
DS1302InputByte(ucDa);写1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
}
unsignedcharRead1302(unsignedcharucAddr)读取DS1302某地址的数据
{
unsignedcharucData;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(ucAddr|0x01);地址,命令
ucData=DS1302OutputByte();读1Byte数据
DS1302_CLK=1;
DS1302_RST=0;
return(ucData);
}
voidDS1302_SetProtect(bitflag)是否写保护
{
if(flag)
Write1302(0x8E,0x10);
else
Write1302(0x8E,0x00);
}
voidDS1302_SetTime(unsignedcharAddress,unsignedcharValue)设置时间函数
{
DS1302_SetProtect(0);
Write1302(Address,((Value10)<<4|(Value%10)));
}
voidDateToStr(SYSTEMTIME*Time)
{
Time->DateString[0]=Time->Year10+'0';
Time->DateString[1]=Time->Year%10+'0';
Time->DateString[2]='-';
Time->DateString[3]=Time->Month10+'0';
Time->DateString[4]=Time->Month%10+'0';
Time->DateString[5]='-';
Time->DateString[6]=Time->Day10+'0';
Time->DateString[7]=Time->Day%10+'0';
Time->DateString[8]='\0';
}
voidTimeToStr(SYSTEMTIME*Time)
{
Time->TimeString[0]=Time->Hour10+'0';
Time->TimeString[1]=Time->Hour%10+'0';
Time->TimeString[2]=':
';
Time->TimeString[3]=Time->Minute10+'0';
Time->TimeString[4]=Time->Minute%10+'0';
Time->TimeString[5]=':
';
Time->TimeString[6]=Time->Second10+'0';
Time->TimeString[7]=Time->Second%10+'0';
Time->DateString[8]='\0';
}
voidDS1302_GetTime(SYSTEMTIME*Time)
{
unsignedcharReadValue;
ReadValue=Read1302(DS1302_SECOND);
Time->Second=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MINUTE);
Time->Minute=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_HOUR);
Time->Hour=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_DAY);
Time->Day=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_MONTH);
Time->Month=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
ReadValue=Read1302(DS1302_YEAR);
Time->Year=((ReadValue&0x70)>>4)*10+(ReadValue&0x0F);
}
voidInitial_DS1302(void)
{
unsignedcharSecond=Read1302(DS1302_SECOND);
if(Second&0x80)
DS1302_SetTime(DS1302_SECOND,0);
}
voidBurstWrite1302(unsignedchar*pWClock)往DS1302写入时钟数据(多字节方式)
{
unsignedchari;
Write1302(0x8e,0x00);控制命令,WP=0,写操作?
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(0xbe);0xbe:
时钟多字节写命令
for(i=8;i>0;i--)8Byte=7Byte时钟数据+1Byte控制
{
DS1302InputByte(*pWClock);写1Byte数据
pWClock++;
}
DS1302_CLK=1;
DS1302_RST=0;
}
voidBurstRead1302(unsignedchar*pRClock)读取DS1302时钟数据(时钟多字节方式)
{
unsignedchari;
DS1302_RST=0;
DS1302_CLK=0;
DS1302_RST=1;
DS1302InputByte(0xbf);0xbf:
时钟多字节读命令
for(i=8;i>0;i--)
{
*pRClock=DS1302OutputByte();读1Byte数据
pRClock++;
}
DS1302_CLK=1;
DS1302_RST=0;
}
voidDS1302_TimeStop(bitflag)是否将时钟停止
{
unsignedcharData;
Data=Read1302(DS1302_SECOND);
DS1302_SetProtect(0);
if(flag)
Write1302(DS1302_SECOND,Data|0x80);
else
Write1302(DS1302_SECOND,Data&0x7F);
}
#endif
LCD1604.=P3^7;
sfrDBPort=0x80;P0=0x80,P1=0x90,P2=0xA0,P3=0xB0.数据端口
unsignedcharLCD_Wait(void)
{
LcdRs=0;
LcdRw=1;_nop_();
LcdEn=1;_nop_();
while(DBPort&0x80);
LcdEn=0;
returnDBPort;
}
#defineLCD_COMMAND0Command
#defineLCD_DATA1Data
#defineLCD_CLEAR_SCREEN0x01清屏
#defineLCD_HOMING0x02光标返回原点
voidLCD_Write(bitstyle,unsignedcharinput)
{
LcdEn=0;
LcdRs=style;
LcdRw=0;_nop_();
DBPort=input;_nop_();注意顺序
LcdEn=1;_nop_();注意顺序
LcdEn=0;_nop_();
LCD_Wait();
}
#defineLCD_SHOW0x04显示开
#defineLCD_HIDE0x00显示关
#defineLCD_CURSOR0x02显示光标
#defineLCD_NO_CURSOR0x00无光标
#defineLCD_FLASH0x01光标闪动
#defineLCD_NO_FLASH0x00光标不闪动
voidLCD_SetDisplay(unsignedcharDisplayMode)
{
LCD_Write(LCD_COMMAND,0x08|DisplayMode);
}
#defineLCD_AC_UP0x02
#defineLCD_AC_DOWN0x00default
#defineLCD_MOVE0x01画面可平移
#defineLCD_NO_MOVE0x00default
voidLCD_SetInput(unsignedcharInputMode)
{
LCD_Write(LCD_COMMAND,0x04|InputMode);
}
voidLCD_Initial()
{
LcdEn=0;
LCD_Write(LCD_COMMAND,0x38);8位数据端口,2行显示,5*7点阵
LCD_Write(LCD_COMMAND,0x38);
LCD_SetDisplay(LCD_SHOW|LCD_NO_CURSOR);开启显示,无光标
LCD_Write(LCD_COMMAND,LCD_CLEAR_SCREEN);清屏
LCD_SetInput(LCD_AC_UP|LCD_NO_MOVE);AC递增,画面不动
}
voidGotoXY(unsignedcharx,unsignedchary)x列,y行
{
if(y==0)
LCD_Write(LCD_COMMAND,0x80|x);
if(y==1)
LCD_Write(LCD_COMMAND,0x80|(x-0x40));
}
voidPrint(unsignedchar*str)
{
while(*str!
='\0')
{
LCD_Write(LCD_DATA,*str);
str++;
}
}
#endif
set_key.__l,setshi___l=20.00;
xianshi_temp=s->temperature;
if((xianshi_temp{cold=0;__l)
{cold=0;error;error=1,通讯有误
}
ucharread_byte(uchardat)
{
uchari,val=0;
DQ=1;
for(i=0x80;i>0;i=2)
{
SCK=1;
if(DQ)val=(val|i);
SCK=0;
}
DQ=dat;
SCK=1;
NOP();
NOP();
NOP();
SCK=0;
DQ=1;
returnval;
}
voidreset_SHT()
{
uchari;
DQ=1;
SCK=0;
for(i=0;i<9;i++)DATA保持高电平,SCK时钟出发9次复位
{
SCK=1;
NOP();
SCK=0;
}
init_SHT();
}
convert_SHT(SHT_dat*s,ucharmode)
{
uchari,ack=0;
ucharvalueM,valueL,checksum;
floatcom;
do{reset_SHT();
switch(mode){
caseTEMP:
ack=write_byte(0x03);break;
caseHUMI:
ack=write_byte(0x05);break;
default:
break;}
}while(ack==1);
for(i=0;i<65535;i++)等待测量结束
{
if(DQ==0)break;
}若长时间数据线DQ没拉低,则说明测量有错误
valueM=read_byte(0);数据的高字节
valueL=read_byte(0);数据的低字节
checksum=read_byte
(1);CRC校验码
com=(float)valueM*256+(float)v