基于52单片机温湿度传感器课程设计报告含代码.docx
- 文档编号:6520746
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:54
- 大小:1.10MB
基于52单片机温湿度传感器课程设计报告含代码.docx
《基于52单片机温湿度传感器课程设计报告含代码.docx》由会员分享,可在线阅读,更多相关《基于52单片机温湿度传感器课程设计报告含代码.docx(54页珍藏版)》请在冰豆网上搜索。
基于52单片机温湿度传感器课程设计报告含代码
基于52单片机的温湿
度检测仪的设计
摘要
利用Atmel52系列单片机和数字温湿度传感器AM2301设计并制作一个简单的温湿度检测仪。
以单片机为核心,外围电路包括电源、时钟芯片、12864LCD、Max232芯片、AM2301传感器以及蜂鸣器报警电路等。
其中AM2301传感器是含有已校准数字信号输出的温湿度复合传感器,它包括一个电阻式感湿元件和一个NTC测温元件。
LCD显示包括万年历、温湿度以及报警设置,同时通过内部中断方式把温湿度的实时值通过VB编写的上位机程序接收并显示。
一、设计功能
(1)LCD分两个界面显示:
主界面和设置报警界面;
(2)主界面显示万年历和温湿度实时值;
(3)设置报警界面显示温湿度上下限及开/关报警;
(4)当温湿度低于设置的下限或高于设置的上限并且开报警后,蜂鸣器和led灯配合报警;
(5)有按键设置功能,以及关报警和回到主界面显示功能;
(6)能通过Max芯片和计算机通信,把温湿度数据显示在上位机界面上,实现远程监控。
二、设计所需元件清单
(1)9V电源
(2)杜邦线若干
(3)12864LCD1块
(4)80X52单片机1片
(5)排阻1排,电阻若干
(6)AM2301传感器1个
(7)32768Hz晶振1个,12MHz晶振1个
(8)蜂鸣器1个
(9)LM2940稳压元件1个
(10)DS1302时钟芯片1片
(11)船型开关1个,触点开关若干
(12)30pF电容若干,22uF电容若干
(13)LED灯2个,三极管,纽扣电池
三、具体设计
根据所要实现的功能,将系统模块化设计,总体模块结构图如下图所示:
以下就分别就各模块功能实现进行设计。
1.复位电路
这部分是单片机一般都需要的,当运行出错或者死机时,利用复位按键能重新启动系统。
RST
2.时钟电路
如上图所示。
其中时钟芯片DS1302的各引脚功能如下:
Vcc1:
主电源;Vcc2:
备份电源。
当Vcc2>Vcc1+0.2V时,由Vcc2
向DS1302供电,当Vcc2 SCLK: 串行时钟,输入,控制数据的输入与输出; I/O: 三线接口时的双向数据线; RST为复位引脚,在读、写数据期间,必须为高, X1X2为32867Hz晶振管脚,为芯片提供时钟脉冲。 3.报警电路 各I/O口在上电时为高电平,LED灯和蜂鸣器处于熄灭和不响状态。 其中LED灯通过一个1K的电阻限流,防止点亮时电流过大被烧坏。 蜂鸣器要用NPN型三极管驱动,当P2.5口输出高电平时,Q1饱和导通,蜂鸣器获得工作电流发出响声。 4.键盘扫描电路 这里用了5个按键。 其中按键1是调时按键,根据按的次数依次进入年、月、日、时、分、秒、星期调整,再按一次则退出。 按键2和3分别是加操作和减操作。 按键4是设置温湿度上下限值及报警开关;按键5是关报警。 5.12864LCD显示电路 ST7920系列12864是带中文字库的液晶显示器,它可以显示4行,每行16个字节,各行的地址依次为0x80~0x87、0x90~0x97、0x88~0x8F 0x98~0x9F。 注: RB0~RB7(为数据口)依次接P1各口,变阻器R2下端接地。 5.1接口说明: VSS为电源地;VDD为电源正端;V0为LCD驱动电压输入端; RS: 并行的指令/数据选择信号,串行的片选信号; RW: 并行的读写选择信号,串行的数据口; E: 并行的使能信号,串行的同步时钟; PSB: 并/串行接口选择,高电平时为并行; NC: 空脚; RST: 复位信号,低电平有效; BLA: 背光源正极; BLK: 背光源负极。 5.2、12864读写时序图如下: 读写操作时序 数据与命令时序 5.3、基本操作时序 (1)读状态: 输入: RS=L,RW=H,E=H输出: D0~D7=状态字 (2)写指令: 输入: RS=L,RW=L,D0~D7=指令码,E=高脉冲输出: 无 (3)读数据: 输入: RS=H,RW=H,E=H输出: D0~D7=数据 (4)写数据: 输入: RS=H,RW=L,D0~D7=数据,E=高脉冲输出: 无 5.4、初始化过程(复位过程)指令: (1)延时15毫秒 (2)写指令38H;显示模式设置 (3)写指令08H;显示关闭 (4)写指令01H;显示清屏 (5)写指令06H;显示光标移动设置 (6)写指令0CH;显示开及光标设置 6.与PC机通信模块 从上述电路可知,单片机要与计算机通信,必须通过MAX232(或其他)芯片。 这是因为计算机串口上的电平执行的是RS-232标准,它定义的高低电平和单片机的TTL逻辑电平不兼容。 而MAX232芯片加上几个电解电容,能完成电压的加倍和反相,实现TTL电平和RS-232电平的转换。 单片机的串行口TXD与MAX232的一组电平转换器的TTL输入端(管脚12)相连,经过MAX232转换后,RS-232标准输出端(管脚14)输出的信号进入计算机串口的RXD。 同样计算机串口的TXD与MAX232的RS-232标准输入端(管脚13)相连,经过电平转换后,由TTL输出端(管脚11)输出到单片机的RXD上。 7.AM2301温湿度检测电路 上图中DHT11和AM2301是一个系列的,他们的引脚和功能一样。 7.1AM2301温湿度传感器简介 DHT11的供电电压为3-5.5V。 传感器上电后,要等待1s以越过不稳定状态在此期间无需发送任何指令。 电源引脚(VDD,GND)之间可增加一个100nF的电容,用以去耦滤波。 DATA用于微处理器与DHT11之间的通讯和同步,采用单总线数据格式,一次通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于以后扩展,现读出为零.操作流程如下: 一次完整的数据传输40bit,高位先出。 数据格式: 8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据+8bit校验和用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。 1、总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。 DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后,读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可,总线由上拉电阻拉高。 2、总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0还是1.格式见下面图示.如果读取响应信号为高电平,则DHT11没有响应,请检查线路是否连接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。 四、各模块流程图 1、温度模块控制流程图: 2、湿度模块控制流程图 3、显示模块控制流程图 4、报警模块流程图 5、温湿度报警设置流程图 6、万年历设置流程图 7、与PC通信模块流程图 五、设计过程问题解决 本次设计过程很费周折,由于proteus里面缺少一些必要的元件如20引脚12864液晶显示模块和AM2301温湿传感器,故实验过程中是先设计好硬件电路,焊好电路以后才进行调试的,其间的艰难可想而知。 也因为这样,硬件电路的错误比较多,中间一直在修改硬件电路,造成电路板修修补补不美观。 实验过程中遇到的困难很多,尤其是实现界面切换和返回主界面的过程,要保持时钟仍在运行,同时光标也要随着界面一起移动。 否则就会显示出错。 此外开关报警的设置如何能够保持,这就要做到返回主界面以后要保存设置量,当报警时按下了关报警,要刷新设置界面。 而在本次设计过程中,我们调用了两次显示,一次写显示格式,一次刷新,只要有更改就刷新,对于那些不变的汉字我们不刷新,这样也使得显示得到简化。 此外,由于使用到单片机与计算机通信知识,通过查阅相关书籍,用VB编写了一个上位机显示界面,将12864上显示的温湿度数值通过串口控件显示。 下面将分步骤将实现过程中的问题和解决方案作说明: 1.刚开始烧了程序以后,发现LCD什么都不显示,后来发现是因为没有开背光,因为没开背光显示不明显,如果角度不对会发现什么都没显示。 而背光要通过可调电阻来调,在12864的BLA背光正极接一个可调电阻,电阻的两端是接地和电源(之间还有一个拨码开关)。 当打开开关时,背光关掉,可以省电;合上开关,调节电阻可以使12864显示亮度变化。 2.能够显示以后,发现显示界面一直在刷新,显示不稳定。 原因是每秒随着秒刷新初始化界面一次,解决的方案是不重新调用显示,而是只给显示秒的位置刷新,其他时间随秒变化。 温湿度值则是有了变化就刷新。 3.由于编写程序时,没有考虑到串口通信中传回PC的数据的十六进制与显示字符之间的数据处理关系,导致在串口助手软件中只显示了传回的最后一个十六进制数所对应的ASCⅡ的字符,找到问题的解决关键所在后,经过数的分位与字符显示后,成功的显示了传回的温度、湿度的数据,让我们距离成功只差一小步了。 接下来的任务就是显示在12864液晶上,根据之前单独在其上显示过液晶万年历的基础,知道只要将dht11检测的数据进行相应处理后并且与液晶万年历的显示集成一起送显示就行了。 理论虽简单,但实际在下载到芯片中检测现象时,我们发现分别单独显示两者的数据没有问题,但集成在一块显示不久就会花屏的现象,问题出在刷新汉字时,指针光标的位置修改错误所导致的。 之后经过重新写回指针后就达到了较为满意的效果。 在报警程序的设置上,主要解决蜂鸣器报警间隔和LED灯闪烁的时间匹配问题,让两者现象统一。 4.单片机与计算机通信。 上位机界面设计,利用VB编程,用MSComm控件能够实现单片机传送数据到计算机并显示。 PrivateSubMSComm1_OnComm() DimrecAsString;定义接收字符串 SelectCaseMSComm1.CommEvent;串口事件选择 CasecomeEvReceive;串口事件为接收 rec=MSComm1.Input;从接收缓冲区中读取数据 Text1.Text=rec;将接收到的字符串写入文本框 MSComm1.InBufferCount=0;设置接收缓冲区中等待计算机接受的字符数为0 EndSelect EndSub PrivateSubform_load() MSComm1.Settings="9600,N,8,1";波特率,奇偶校验,发送位数,停止位 MSComm1.CommPort=5;串口号 IfMSComm1.PortOpen=TrueThenMSComm1.PortOpen=False MSComm1.RThreshold=8;接收缓冲区字符为8时,串口控件设置串口事件为接收,并产生OnComm事件 MSComm1.SThreshold=2;发送缓冲区中字符小于2时,串口控件设置串口事件为发送,并产生OnComm事件 MSComm1.InputLen=0;返回一次从接收缓冲区读取所有字节 MSComm1.InputMode=comInputModeText;接收模式为文本 IfMSComm1.PortOpen=FalseThenMSComm1.PortOpen=True MSComm1.InBufferCount=0 Me.Caption="温湿度显示" EndSub PrivateSubForm_Resize();窗体背景图片设置 Image1.Top=0 Image1.Left=0 Image1.Stretch=True Image1.Height=Me.ScaleHeight Image1.Width=Me.ScaleWidth EndSub PrivateSubmnuQuit_Click() End EndSub 六、设计总结 本次设计是小组三人共同努力的成果,大家齐心协力克服了上述种种困难,才把实物做出来。 通过这次设计,我们学习到了如何把传感器联系单片机知识做成一个简单的检测系统,如何完成简单的通信任务,如何编写高效率的C代码。 当然我们的不足也有很多,比如硬件设计电路考虑不全面,造成后来不得不修改一些连线和元件使得电路板不够美观;还有程序不够模块化,有不少冗余,移植性和兼容性也不好,今后要更加注重这些方面的改进。 附录代码: /*****基于单片机的温湿度检测系统******/ #include #defineucharunsignedchar #defineuintunsignedint /***端口定义***/ sbitLCD_RS=P3^5;//寄存器选择输入 sbitLCD_RW=P3^6;//液晶读/写控制 sbitLCD_EN=P3^4;//液晶使能控制 sbitLCD_PSB=P3^7;//串/并方式控制 sbits5=P0^3;//关报警 sbits4=P0^4;//设置温湿度报警值及开关报警 sbits3=P0^5;//调时开/关 sbits2=P0^6;//加操作 sbits1=P0^7;//减操作 sbitled1=P2^0;//温度报警 sbitled2=P2^1;//湿度报警 sbitbuzzer=P2^5;//蜂鸣器 sbitAM2301=P2^6;//P2.6口为通讯口连接DHT11 typedefunsignedcharU8; typedefunsignedintU16; charsec,min,hour,week,day=1,month=1,year; bitflag,flag2,flag3=0,flag4=0,flag5=0,flag6=0; uchara; uchars1num,s4num; ucharcodedis1[]={"2011年12月02日"}; ucharcodedis2[]={"00时00分00秒"}; ucharcodedis3[]={"温度: 25.0日"}; ucharcodedis4[]={"湿度: 40.0"}; ucharcodedis5[]={"温度上限: "};//温湿度设置界面 ucharcodedis6[]={"温度下限: "}; ucharcodedis7[]={"湿度上限: "}; ucharcodedis8[]={"湿度下限: "}; ucharcodedisx[]={0xc8,0xd5,0xd2,0xbb,0xb6,0xfe,0xc8,0xfd,0xcb,0xc4,0xce,0xe5,0xc1,0xf9};//"日","一","二","三","四","五","六"(两个字节为一个汉字) //----------------定义区--------------------// U8Temp,RH1; U8U8FLAG; U8U8count,U8temp; U8datatab[8]={0x00,0x00,0x2e,0x00,0x00,0x00,0x2e,0x00};//存储温湿度数据 U8U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata;//温湿度的高低位及校验位 U8U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp; U8temp_H=30,temp_L=0,RH_H=50,RH_L=10; U8U8comdata; U8outdata[8];//定义发送的字节数 U8str[8]={“”}; U8count; U16U16temp1,U16temp2; /***延时1ms子函数***/ voiddelay(uintz) { uintx,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } /***延时子函数***/ voidDelay2(U16j) { U8i; for(;j>0;j--) for(i=0;i<27;i++); } /***延时10us子函数***/ voidDelay_10us(void) { U8i; i--; i--; i--; i--; i--; i--; } /***发送字符串子函数***/ voidSendData(U8*a) { outdata[0]=a[0]; outdata[1]=a[1]; outdata[2]=a[2]; outdata[3]=a[3]; outdata[4]=a[4]; outdata[5]=a[5]; outdata[6]=a[6]; outdata[7]=a[7]; count=0; SBUF=outdata[0]; } /***写指令子函数***/ /*RS=0,RW=0,E=0,D0-D7=指令码*/ voidwrite_com(ucharcom) { LCD_RS=0; LCD_RW=0; LCD_EN=0; P1=com; delay(5); LCD_EN=1; delay(5); LCD_EN=0; } /***写数据子函数***/ /*RS=1,RW=0,E=0,D0-D7=数据*/ voidwrite_dat(uchardat) { LCD_RS=1; LCD_RW=0; LCD_EN=0; P1=dat; delay(5); LCD_EN=1; delay(5); LCD_EN=0; } /***设定显示位置***/ voidlcd_pos(ucharX,ucharY) { ucharpos; if(X==0)X=0x80; elseif(X==1)X=0x90; elseif(X==2)X=0x88; elseif(X==3)X=0x98; pos=X+Y; write_com(pos); } /***LCD初始化设定***/ voidinit() { LCD_PSB=1;//并口方式 write_com(0x30);//基本指令操作 delay(5); write_com(0x0c);//显示开,关光标 delay(5); write_com(0x01);//清除LCD的显示内容 delay(5); TMOD=0x21; TH0=0x4c; TL0=0x00; ET0=1; EA=1; TR0=1; TH1=253;//初始化串口 TL1=253; TR1=1; SCON=0x50; ES=1; EA=1; TI=0; RI=0; SendData(str); Delay2 (1); } /***写年月日子函数***/ voidwrite_ymd(ucharadd,uchardat) { ucharshi,ge; shi=dat/10; ge=dat%10; write_com(0x80+add); write_dat(0x30+shi); write_dat(0x30+ge); } /***写时分秒子函数***/ voidwrite_hms(ucharadd,uchardat) { ucharshi,ge; shi=dat/10; ge=dat%10; write_com(0x90+add); write_dat(0x30+shi); write_dat(0x30+ge); } /******温湿度上下限设置更新***********/ voidwrite_lim1(ucharadd,uchardat) { ucharshi,ge; shi=dat/10; ge=dat%10; write_com(0x80+add); write_dat(0x30+shi); write_dat(0x30+ge); } voidwrite_lim2(ucharadd,uchardat) { ucharshi,ge; shi=dat/10; ge=dat%10; write_com(0x90+add); write_dat(0x30+shi); write_dat(0x30+ge); } voidwrite_lim3(ucharadd,uchardat) { ucharshi,ge; shi=dat/10; ge=dat%10; write_com(0x88+add); write_dat(0x30+shi); write_dat(0x30+ge); } voidwrite_lim4(ucharadd,uchardat) { ucharshi,ge; shi=dat/10; ge=dat%10; write_com(0x98+add); write_dat(0x30+shi); write_dat(0x30+ge); } /*温度显示子函数*/ voidwrite_tem(ucharadd) { write_com(0x88+add); write_dat(tab[4]); write_dat(tab[5]); write_dat(tab[6]); write_dat(tab[7]); } /*湿度显示子函数*/ voidwrite_hum(ucharadd) { write_com(0x98+add); write_dat(tab[0]); write_dat(tab[1]); write_dat(tab[2]); write_dat(tab[3]); } voidCOM(void) { U8i; for(i=0;i<8;i++) { U8FLAG=2; while((! AM2301)&&U8FLAG++); Delay_10us();
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 基于 52 单片机 温湿度 传感器 课程设计 报告 代码
![提示](https://static.bdocx.com/images/bang_tan.gif)