版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
摘要系统以AT89C51单片机为主控制器,设计并制作了一款红外遥控温度报警器,可实时显示温度值,还可以通过红外遥控修改温度报警上限和下限,温度显示在12864上,本设计的创新点是增加了用VC6.0开发的上位机,在计算机上显示出温度计和视频界面,构成友好的人机界面,具有很高的实用价值。关键词:AT89C51;红外遥控;温度报警;上位机AbstractAT89C51microcontroller-basedcontrolsystem,designedandproducedaninfraredremotetemperaturealarm,real-timedisplaytemperature,infraredremotecontrolcanalsobemodifiedthroughtheupperandlowertemperaturealarm,temperaturedisplayinthe12,864ontheinnovationofthisdesignistoincreasethedevelopmentofthehostcomputerusingVC6.0,athermometerinthecomputerandvideodisplayinterface,form-friendlyinterface,withhighpracticalvalueKeywords:AT89C51;infraredremotecontrol;temperaturealarm;PC
目录绪论 11系统的硬件组成与设计 11.1系统硬件组成 11.2模块介绍 11.2.1控制器模块 11.2.2显示模块 11.2.3温度采集模块 22硬件设计选择及功能介绍 22.1控制器部分 22.2温度采集部分 32.3报警电路 52.4红外遥控部分 62.5显示部分 62.6串口部分 73程序设计 84系统测试 175总结 186.参考文献 19附录 20绪论为了提高对传感器的认识和了解,尤其是对温度传感器对深入研究以及其用法与用途,基于实用、广泛和典型的原则而设计了本系统。本文利用单片机结合传感器技术而开发设计了这一温度检测系统,传感器理论与单片机实际应用有机结合。设计应用性强,课题主要任务是完成环境温度检测,利用单片机实现温度调节并通过计算机实施温度监控,设计后的系统具有操作方便,控制灵活等优点。1系统的硬件组成与设计1.1系统硬件组成本系统主要由控制器模块、红外遥控模块、温度报警模块、显示模块及串口模块等部分组成。如图1图11.2模块介绍1.2.1控制器模块采用ATMEL公司的AT89C51作为系统控制器。单片机算术运算功能强,软件编程灵活、自由度大,可用软件编程实现各种算法和逻辑控制,并且其功耗低、体积小、技术成熟和成本低等优点。由AT89C51作为控制核心,对温度的显示及调整进行控制。1.2.2显示模块采用12864液晶显示。其内置8192个16*16点汉字,和128个16*8点ASCII字符集,可以直观地显示出较多内容,利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面,使得显示内容丰富,易于人机交流,并且节约了I/O口资源。本设计中采用12864作为显示模块,可以同时显示温度及时间,不仅能达到设计要求,还具有明显的优越性。1.2.3温度采集模块采用数字温度传感器DS18B20。DS18B20为数字式温度传感器,无需其他外加电路,直接输出数字量。可直接与单片机通信,读取测温数据,电路简单。DS18B20能够直接读出被测温度并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。并且从DS18B20读出的信息或写入DS18B20的信息仅需要一根口线(单线接口)读写,因而使用DS18B20可使系统结构更趋简单,可靠性更高。他在测温精度、转换时间、传输距离、分辨率等方面带来了令人满意的效果。2硬件设计选择及功能介绍2.1控制器部分本设计采用AT89C51单片机为核心控制器件,通过单片编程控制红外遥控,温度芯片18B20,,从而实现红外遥控温度报警,原理图如图2.1所示。图2.1单片机最小系统电路图2.2温度采集部分系统温度检测是由数字温度传感器Ds18B20实现的。Ds18b20具有测温系统简单、测温精度高、连接方便、占用口线少等优点,特别适用于多点测温。硬件接口电路如图2.2所示。图2.2Ds18B20的硬件接口电路(1)DSI8B20的测温功能的实现其测温电路的实现是依靠单片机软件的编程上。当DSI8B20接收到温度转换命令后,开始启动转换。转换完成后的温度值就以16位带符号扩展的二进制补码形式存储在高速暂存存储器的0,1字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后,数据格式以0.0625℃/LSB形式表示。温度值格式如表所示,其中“S”为标志位,对应的温度计算:当符号位S=0时,直接将二进制位转换为十进制;当S=1时,先将补码变换为原码,再计算十进制值。DSI8B20完成温度转换后,就把测得的温度值与TH做比较,若T>TH或T<TL,则将该器件内的告警标志置位,并对主机发出的告警搜索命令做出响应。表DS18B20温度值格式表LSByteMSByteSSSSS(2)、DSl820工作过程中的协议初始化->RoM操作命令->存储器操作命令->处理数据①初始化单总线上的所有处理均从初始化开始②ROM操作命令总线主机检测到DSl820的存在便可以发出ROM操作命令之一这些命令如表所示表ROM操作命令表指令代码ReadROM(读ROM)33HMatchROM(匹配ROM)55HSkipROM(跳过ROM]CCHSearchROM(搜索ROM)F0HAlarmsearch(告警搜索)ECH③存储器操作命令如表所示表存储器操作命令表指令代码WriteScratchpad(写暂存存储器)
4EHReadScratchpad(读暂存存储器)BEHCopyScratchpad(复制暂存存储器)
48HConvertTemperature(温度变换)44HRecallEPROM(重新调出)B8HReadPowersupply(读电源)
B4H(3)温度转换算法及分析由于DS18B20转换后的代码并不是实际的温度值,所以要进行计算转换。温度高字节(MSByte)高5位是用来保存温度的正负(标志为S的bit11~bit15),高字节(MSByte)低3位和低字节来保存温度值(bit0~bit10)。其中低字节(LSByte)的低4位来保存温度的小数位(bit0~bit3)。由于本程序采用的是0.0625的精度,小数部分的值,可以用后四位代表的实际数值乘以0.0625,得到真正的数值,数值可能带几个小数位,所以采取小数舍入,保留一位小数即可。也就说,本系统的温度精确到了0.1度。算法核心:首先程序判断温度是否是零下,如果是,则DS18B20保存的是温度的补码值,需要对其低8位(LSByte)取反加一变成原码。处理过后把DS18B20的温度Copy到单片机的RAM中,里面已经是温度值的Hex码了,然后转换Hex码到BCD码,分别把小数位,个位,十位的BCD码存入RAM中。2.3报警电路555集成定时器是一种模拟和数字电路相混合等集成电路,它结构简单,使用灵活,用途十分广泛,可以组成多种波形发生器、多谢振荡器、定时延时电路、报警电路、检测电路、射频变换电路等。图2.3555定时器引脚图图2.4报警电路图2.4红外遥控部分遥控接收使用红外接收模块1838,该接收模块是一个三端元件,具有功耗低、抗干扰能力强、输入灵敏度高的特点。如图2.4所示,1838接AT89C2051的P3.2(外中断0).当1838V接收到遥控信号时.产生中断,处理遥控数据.处理完后返回。图2.41838硬件接口电路图2.5显示部分本设计采用12864液晶显示器,它是一种具有4位/8位并行、2线或3线串行多种接口方式,内部含有国标一级、二级简体中文字库的点阵图形液晶显示模块;其显示分辨率为128×64,内置8192个16*16点汉字,和128个16*8点ASCII字符集,利用该模块灵活的接口方式和简单、方便的操作指令,可构成全中文人机交互图形界面。可以显示8×4行16×16点阵的汉字,还可完成图形显示,低电压低功耗是其又一显著特点。由该模块构成的液晶显示方案与同类型的图形点阵液晶显示模块相比,不论硬件电路结构或显示程序都要简洁得多。通过单片机控制,同时显示出温度。图2.5显示控制电路图2.6串口部分用于上位机显示的串口电路图如图2.6所示图2.6串口接线图3程序设计程序:#include<reg52.h>#include<intrins.h>#ifndefuchar#defineucharunsignedchar#endif#ifndefuint#defineuintunsignedint#endifsbitIR_GET=P3^2;//红外接收数据输入端sbitBEEP=P3^5;//蜂鸣器驱动线/********************************************************/ucharRXDDATA[]={0x00,0x00,0x00,0x00};//存放接收到的四组红外编码bitircodeflag=0;volatilebitkong=1; //全局变量,用于数码管上的两杠进行闪烁volatileucharworkcode;//经过处理返回的纯数字红外编码ucharuart_num[17]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','-'};ucharxdataolddisptimes[14]={1,1,1,1,1,1,1,1,1,1,1,1,1,1};#include"uart.h"#include"ds1302.h"#include"ds18b20.h"#include"LCD12864P.C"/********************************************************函数声明专区********************************************************/voidDelayUS(uintnum);voiddelay100us(ucharx);voidbeep();ucharworkIRcode(uchar*pp) ;voidsendircode();voiddisplaytime();voidset1616pic(ucharx,uchary,ucharsign,uchartt);voidset1616num(ucharcurr,uchar*ptime);voidgudidisptemp(uchar*tempc);ucharchecktemp(uchar*pp);uchartime_compare();/********************************************************/voidmain(){ bitone_sign; bitonealarmflag=0; ucharrun_sign,tempdata,timenum,timelcdxy,we; uchari,curr_menu_id,checkflag; uchar*pmenu; ucharstimetopc; ucharoutflag; delayms(500); TMOD|=0X01; //选择定时器0工作在模式1,即16位定时器 TH0=(65536-49000)/256; //装49ms的初值 TL0=(65536-49000)%256; ET0=1; //开定时器0中断 EX0=1; //使能INT0外部中断 IT0=1;//外中断0下降沿触发 IR_GET=1;//I/O口初始化 UART_Init(); //初始化串口 EA=1; //开总中断 UART_Send_Str("$$初始化中\n"); UART_Send_Str("*"); //上位机的结束标识 init_12864(); init_1302(); Clean_12864_GDRAM();// settime_1302(inittime); gettime_1302(times); for(i=0;i<6;i++){olddisptimes[i]=disptimes[i]+65;//为了使下面出现比较不合,写入首次的所有图形}// write_12864_cmd(0x30);//非常重要!上面关显示是扩展指令,再写成基本指令// delayms(5);// photodisplay(Photo2);//显示图片Photo2--//delayms(2000); //显示图片2S Clean_12864_GDRAM(); UART_Send_Str("$$初始化完成\n"); UART_Send_Str("*"); //上位机的结束标识// TR0=1; //启动定时器0 while(1) {gettime_1302(times); worktime_1302(disptimes,times); EA=0; read_temp();//读出DS18B20温度数据 work_temp();//处理温度数据 EA=1; sendircode(); displaytime(); //显示非绘图的温度。 for(i=0;i<6;i++) olddisptimes[i]=disptimes[i]; set1616pic(4,4,1,2); //在第4列第4行反白的显示温度标记/******************************************************************///**************************************************///以下是发送温度到上位机显示。 stimetopc++; if(stimetopc/2==0) sendtempflag=1; //温度允许发送到上位机的标记置1。 if(stimetopc>10) {stimetopc=0; UART_Send_Byte('T'); for(i=0;i<14;i++) {UART_Send_Byte(uart_num[disptimes[i]]); UART_Send_Byte(uart_num[disptimes[++i]]);} UART_Send_Byte('*'); //上位机的结束标识}/**************************************************/ //进入菜单选择 if(workcode==12) {outflag=1; UART_Send_Str("$$进入菜单设置\n"); UART_Send_Str("*"); //上位机的结束标识 workcode=14;Clean_12864_GDRAM();//先清完所有显示,再把菜单项目显示出来供选择。 Clean_12864(); write_12864_cmd(0x80); for(i=0;i<12;i++) write_12864_data(initmenu[i]); write_12864_cmd(0x90); for(i=48;i<60;i++) write_12864_data(sonmenu1[i]); write_12864_cmd(0x88); for(i=48;i<60;i++) write_12864_data(sonmenu2[i]); write_12864_cmd(0x98); for(i=48;i<60;i++) write_12864_data(sonmenu3[i]); setrowbkcolor(2,1); //初始是第二行反白 curr_menu_id=2; while(outflag==1)//选择父菜单 {if(workcode==16) {workcode=14; if(curr_menu_id<4)//向上选择菜单 {setrowbkcolor(curr_menu_id,0); curr_menu_id++; setrowbkcolor(curr_menu_id,1);}} if(workcode==15)//向下选择菜单 {workcode=14; if(curr_menu_id>2) {setrowbkcolor(curr_menu_id,0); curr_menu_id--; setrowbkcolor(curr_menu_id,1);}} if(workcode==13) //选择之后进入 {outflag=0; workcode=14;}} outflag=1; switch(curr_menu_id)//由选择父的菜单进行调用相应子菜单进行调整 {case2:pmenu=sonmenu1; UART_Send_Str("$$进入调整时间\n"); UART_Send_Str("*"); //上位机的结束标识 break; case3:pmenu=sonmenu2; UART_Send_Str("$$进入报警温度\n"); UART_Send_Str("*"); //上位机的结束标识 break;Clean_12864_GDRAM();//先清完所有显示再把相应的内容显示出来 Clean_12864(); write_12864_cmd(0x80); for(i=48;i<60;i++) write_12864_data(pmenu[i]); setrowbkcolor(1,1); //第一行为父菜单名称,反白处理。 write_12864_cmd(0x30); write_12864_cmd(0x90); for(i=0;i<16;i++) write_12864_data(pmenu[i]); write_12864_cmd(0x88); for(i=16;i<31;i++) write_12864_data(pmenu[i]); write_12864_cmd(0x98); for(i=32;i<48;i++) write_12864_data(pmenu[i]); if(curr_menu_id==2) {write_1302(0x8e,0x00);//关写保护,可以写 write_1302(0x80,0x80); //让1302停震 gettime_1302(times); worktime_1302(disptimes,times);} one_sign=1; run_sign=1; while(outflag==1) //设置菜单{/**************************************************/// 选择的是报警温度菜单项 if(curr_menu_id==3) {TR0=1; switch(run_sign)if(one_sign==1){one_sign=0; gudidisptemp(alarm_temp);} write_12864_cmd(timelcdxy); if(kong){write_12864_data(alarm_temp[timenum]/10+0x30); write_12864_data('0'+alarm_temp[timenum]%10);/} else {write_12864_data(''); write_12864_data('');} if(workcode==11) {workcode=14; tempdata++; one_sign=1;} if(workcode==10) {workcode=14; tempdata--; one_sign=1;} alarm_temp[timenum]=tempdata; //再把设置好的报警值存起来 if(workcode==13){if(run_sign==2)//说明已经全部设置完成,可以退出了。 { outflag=0; //退出标记 TR0=0; //关闭定时器0 Clean_12864_GDRAM(); Clean_12864(); UART_Send_Str("$$设置完成\n"); UART_Send_Str("*"); //上位机的结束标识 for(i=0;i<6;i++){olddisptimes[i]=disptimes[i]+65;//为了使下面出现比较不合,写入首次的所有图形}}else{workcode=14; run_sign++; write_12864_cmd(timelcdxy); write_12864_data(alarm_temp[timenum]/10+0x30);}}//if(workcode==13)在此完了 }//报警温度菜单项设置完成 /**************************************************//**************************************************//******************************************************************checkflag=checktemp(alarm_temp); //检查报警标志 if(alarmflag&&(checkflag==1)) {UART_Send_Str("$$低温警报:温度超下限值!\n"); UART_Send_Str("*"); //上位机的结束标识} if(alarmflag&&(checkflag==2)) { UART_Send_Str("$$高温警报:温度超上限值!\n"); UART_Send_Str("*"); //上位机的结束} if(alarmflag&&checkflag) {alarmbeep();}checkflag=time_compare(); //检查报警标志 if(alarmflag&&checkflag) {UART_Send_Str("*"); //上位机的结束标识} if(alarmflag&&(checkflag==1)) {alarmbeep();}}}/******************************************************************us级延时函数//蜂鸣器使用/******************************************************************voidDelayUS(uintnum){while(--num);} /************************************************************ 约0.1ms延时函数 (11.0592MHZ)*************************************************************/voiddelay100us(ucharx){unsignedchari;while(x--){for(i=0;i<10;i++);}}/******************************************************************蜂鸣器响一声/******************************************************************voidbeep(){uchary;for(y=0;y<50;y++){DelayUS(50);BEEP=0; //有源蜂鸣器给电就响}BEEP=1;//关闭蜂鸣器 DelayUS(90)} /************************************************************ 温度报警检查函数 超过限制值就返回1,温度正常则返回0;*************************************************************/ucharchecktemp(uchar*pp){ucharaa;aa=temp_check[1]*10+temp_check[0];//先取出当前温度值if(pp[1]<=aa)//比较,成立则超过上限return2; //返回1if(pp[0]>=aa)//比较,成立则超过下限return1; //返回1return0;//返回0}/************************************************************** 红外编码数据处理函数函数 ***************************************************************/ucharworkIRcode(uchar*pp) {ucharresult; beep(); switch(pp[2]) {case0x00:result=0;break;//0 case0x01:result=1;break;//1 case0x02:result=2;break;//2 case0x03:result=3;break;//3 case0x04:result=4;break;//4 case0x05:result=5;break;//5 case0x06:result=6;break;//6 case0x07:result=7;break;//7 case0x08:result=8;break;//8 case0x09:result=9;break;//9 case0x0F:result=10;break;//- case0x0E:result=11;break;//+ case0x13:result=12;break;//菜单 case0x48:result=13;break;//OK case0x0A:result=15;break;//上 case0x0B:result=16;break;//下 case0x1a:result=17;break;//丽音 default:result=14;break;//别的键按下返回14}returnresult;}/**********************************************************///以下显示温度在第4行 write_12864_cmd(0x9c); //温度显示的坐标 write_12864_data(''); //补上空格 write_12864_data(tempdisdata[3]); //显示温度的最高位:百位 write_12864_data(tempdisdata[2]); //显示温度的十位write_12864_data(tempdisdata[1]); //显示温度的个位 write_12864_data('.'); //显示小数点 write_12864_data(tempdisdata[0]); //显示温度值小数位 write_12864_data(0xa1);//温度的符号“C” write_12864_data(0xe6);///**********************************************************/}voidgudidisptemp(uchar*tempc){write_12864_cmd(0x94); // 液晶坐标定位 write_12864_data('0'+((tempc[1]&0xf0)>>4));write_12864_data('0'+(tempc[1]&0x0f));//写入上限值 write_12864_cmd(0x8c); // 液晶坐标定位 write_12864_data('0'+((tempc[0]&0xf0)>>4));write_12864_data('0'+(tempc[0]&0x0f));//写入下限值}voidgudidispclock(uchar*clock){write_12864_cmd(0x8a); // 液晶坐标定位 write_12864_data('0'+clock[0]/10); write_12864_cmd(0x8c); // 液晶坐标定位}/************************************************************ 外部中断0服务函数*************************************************************/voidintt_0()interrupt0//下降沿触发:接收不到红外时OUT高电平,接收到红外时OUT低电平。{ucharfour,one,num=0; EX0=0;//关中断0使能,防止处理过程中再接收红外信号 delayms(2); //稍延时2ms,防干扰 if(IR_GET)//再检测红外接收脚(9ms的前导低电平),为高电平说明是干扰 {EX0=1; //使能中断0 return; //退出中断程序} while(!IR_GET);//等IR变为高电平,跳过9ms的前导低电平信号。 while(IR_GET);//等IR变为低电平,跳过4.5ms的前导高电平信号。 for(four=0;four<4;four++)//四组数据 {for(one=0;one<8;one++)//每组数据8位 {while(!IR_GET);//
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025-2026学年大班跳绳说课稿说课稿
- 香料合成工岗中班组协作考核试卷含答案
- 燃气用户安装检修工岗位职业规划考核试卷含答案
- 翻车机工岗前环保竞赛考核试卷含答案
- 音响调音员基础技能竞赛考核试卷含答案
- 压电石英片烧银焊线工安全管理水平考核试卷含答案
- 2025-2026学年传统节日阅读说课稿
- 2025-2026学年三年级下册英语第三单元说课稿
- 2026年文化会展服务行业趋势洞察报告及未来五至十年可持续发展与长期价值评估
- 2026年建筑陶瓷制品制造行业市场运行态势报告及未来五至十年第二曲线与持续增长
- 【新教材】2026秋人教PEP版六年级上册英语全册教案(含教学计划)
- 项目复盘总结报告撰写模板
- 客户满意度调查分析报告范本
- 长江存储在线测评题库
- 2025年UOM无人机理论培训合格证题库及答案
- 2026年河北单招语文应用文写作专项通知书信倡议书经典题
- 安徽省大联考2025-2026学年高一上学期十月调研考试英语试题(解析版)
- 《长征》读书分享演讲
- 履约能力及交货进度保证措施
- 突发低血压与休克常规处理
- 广西地区2019-2024年中考满分作文164篇
评论
0/150
提交评论