为了正常的体验网站,请在浏览器设置里面开启Javascript功能!

自制温湿度计

2013-03-14 6页 pdf 1MB 63阅读

用户头像

is_199944

暂无简介

举报
自制温湿度计 48 www.ele169.com 制作项目 MAKE PROJECT 自制温湿度计 作者 / 李前江 在食品加工,工业生产,农业,养殖业等很多领域都 需要对温度湿度进行严格控制。本制作是用AM2301温湿 度传感器,基于单片机AT89S52和LCD1602字符型液晶 显示模块制作的具有体积小,成本低并能满足常规要求的 温湿度计。本制作主要用于室内温度和湿度的测量,也可 用于仓库和种植蔬菜的塑料大棚。冬季气温寒冷,天气干 燥。放一个温湿度计在房间,为加湿提供参考,也可让大 家知道天冷到什么程度。 AM2...
自制温湿度计
48 www.ele169.com 制作项目 MAKE PROJECT 自制温湿度计 作者 / 李前江 在食品加工,工业生产,农业,养殖业等很多领域都 需要对温度湿度进行严格控制。本制作是用AM2301温湿 度传感器,基于单片机AT89S52和LCD1602字符型液晶 显示模块制作的具有体积小,成本低并能满足常规要求的 温湿度计。本制作主要用于室内温度和湿度的测量,也可 用于仓库和种植蔬菜的塑料大棚。冬季气温寒冷,天气干 燥。放一个温湿度计在房间,为加湿提供参考,也可让大 家知道天冷到什么程度。 AM2301是一款含有已校准数字信号输出的温湿度复 合传感器。它应用专用的数字模块采集技术和温湿度传感 技术,确保产品具有极高的可靠性与卓越的长期稳定性。 小体积,低功耗,单总线接口使系统集成简单。信号传输 距离可达20m以上,能满足各类场合应用要求。 AM2301特性及引脚说明 AM2301湿度分辨率为0.1%RH,精度±3%最大误差 ±5%。温度分辨率为0.1℃,精度最大误差±1℃。采样 周期建议2s,连接线长度短于20m时建议用5k上拉电阻。 引脚分配如图1。 1. VCC:电源引脚,工作时接+5V 2. OUT:单总线接口用于与MCU通信 3. GND:电源地 492012.01 MCU单片机制作 图1 图2 T2/P1.01 T2EX/P1.12 P1.23 P1.34 P1.45 MOSI/P1.56 MISO/P1.67 SCK/P1.78 RESET9 RXD/P3.010 TXD/P3.111 INT0/P3.212 INT1/P3.313 TO/P3.414 T1/P3.515 WR/P3.616 RD/P3.717 XTAL218 XTAL119 GND20 P2.0/A8 21 P2.1/A9 22 P2.2/A10 23 P2.3/A11 24 P2.4/A12 25 P2.5/A13 26 P2.6/A14 27 P2.7/A15 28 PSEN 29 ALE/PROG 30 EA/VPP 31 P0.7/AD7 32 P0.6/AD6 33 P0.5/AD5 34 P0.4/AD4 35 P0.3/AD3 36 P0.2/AD2 37 P0.1/AD1 38 P0.0/AD0 39 VCC 40 U1 AT89S52 G N D 1 D Q 2 V C C 3 U2 AM2301 R1 5k VCC VCC R2 10k +C1 10μF VCC VCC Y1 12MHz C2 30p C3 30p VCC GND1 VCC2 VL3 RS4 R/W5 EN6 D07 D18 D29 D310 D411 D512 D613 D714 BLA15 BLK16 LCD1602R3 10k VCC P1.2 P1.3 P1.4 P1.2 P1.3 P1.4 空闲时总线为高电平,通讯开始时单片机拉低总线500μs后释 放总线,延时20~40μs后单片机机开始检测AM2301的响应信号。 AM2301的响应信号是一个80μs左右的低电平,随后AM2301在拉 高总线80μs左右代即将进入数据传送。时序如图4。 高电平后就是数据位,每1bit数据都是由一个低电平时隙和一个 高电平组成。低电平时隙就是一个50μs左右的低电平,它代表数据 位的起始,其后的高电平的长度决定数据位所代表的数值,较长的 高电平代表1,较短的高电平代表0。共40bit数据,当最后一Bit数据 传送完毕后,AM2301将再次拉低总线50μs左右,随后释放总线, 由上拉电阻拉高。数字信号1的表示方法如图5。数字信号0的表示方 法如图6。 搞清楚了AM2301时序,接着开始写驱动程序,程序代码如下: 4. NC(TEST):正常使用时悬空 注:AM2301上电之后,要等待1s 以越过不稳定 状态在此期间无需发送任何指令。传感器与单片机一 次通讯时间5ms左右,数据传输为40bit,高位前。 数据格式: 40bit数据=16bit湿度数据+16bit温度 数据+8bit校验和主机从AM2301读取的温湿度数据总 是前一次的测量值,如两次测量间隔时间很长,需连 续读两次以获得实时的温湿度。 单片机及LCD1602说明 单片机选用性价比较高的AT89S52具有8K字节 在系统可编程Flash存储器和32个可编程I/O,三个16 位定时器/计数器等。在此制作中充分满足要求且还 有富余,实际制作时可以选用合适的单片机以降低成 本。 显 示 部 分 选 用 L C D 1 6 0 2 字 符 型 液 晶 显 示 模 块,操作简便。此三者结合起来可组成一个显示 简洁大方的温湿计。 硬件电路设计 本温湿计电路简单,易于制作。硬件电路 如图2。 AM2301底层操作 单片机发送一次开始信号后,AM2301 从低功耗模式转换到高速模式,等待单片机 开始信号结束后,AM2301发送响应信号,送 出40bi t的数据,并触发一次信号采集。时 序如图3。 图3 图4 50 www.ele169.com 制作项目 MAKE PROJECT 图5 图6 首先定义接口和读回的数据存储空间声明 sbit DQ = P1^0; //传感器对应单片机引脚 unsigned char AM2301_Data[5]={0x00,0x00,0x00,0x00,0x00}; //用于接收40bit数据 /********************************************** *函数功能:微秒级延时 **********************************************/ void delay_10us(unsigned int t) { while(t--) { _nop_(); } } /********************************************** *函数功能:读取AM2301发送的单字节数据 **********************************************/ unsigned char Read_AM2301_Byte(void) { unsigned char i,dat,temp; for(i = 0; i < 8; i ++) { while(!DQ); //检测上次低电平是否结束 delay_10us(2); //延时跳过数据0的高电平 temp = 0; if(DQ) { temp = 1; } while(DQ); //等待高电平结束 dat <<= 1; //高位在前 dat |= temp; } return (dat); } /********************************************** *函数功能:读取AM2301完成一次检测发送的40bit数据 **********************************************/ void Read_AM2301(void) { unsigned char i; DQ = 0; //单片机拉低总线 delay_10us(40); //拉低总线时间至少500us DQ = 1; //单片机释放总线 delay_10us(2); //延时等待AM2301响应 if(DQ == 0) //如果AM2301响应,接着开始传送数据 { while(!DQ); //等待传感器80us低电平响应结束 while(DQ); //等待传感器80us高电平结束 for(i = 0; i < 5; i ++) //正式开始读取40bit数据 { AM2301_Data[i] = Read_AM2301_Byte(); } } } 512012.01 MCU单片机制作 LCD1602底层操作 传感器AM2301还是很好操作的,写好AM2301底层驱动后,紧接 着操作LCD1602液晶显示模块。LCD1602是字符型液晶,并且是并行 接口,操作起来很简单。其读操作时序如图7。 图7 图8 对LCD1602液晶操作之前需先检测是否处于忙状态。接口定义如 下: sbit RS = P1^4; //LCD的RS对应单片机引脚 sbit RW = P1^3; //LCD的RW对应单片机引脚 sbit EN = P1^2; //LCD的EN对应单片机引脚 /****************************************函数功能:忙检测 /**********************************************/ void LCD_Busy(void) { P2 = 0xff; RS = 0; //RS=0 RW=1 E=高电平 RW = 1; EN = 1; while((P2 & 0x80) == 1); //D7=0 表示LCD控制器空闲,则退出检测 EN = 0; } /********************************************* *函数功能:写命令或数据到液晶显示器 *********************************************/ void LCD_Write(bit x,unsigned char com) { LCD_Busy(); //忙检测 RS = x; //RS=0 RW=0 E=1,为写命令 RW = 0; //RS=1 RW=0 E=1,为写数据 P2 = com; EN = 1; _nop_(); EN = 0; } /********************************************* *函数功能:在LCD1602两行的任何位置显示需要的数 据 *********************************************/ void LCD_Show(unsigned char y,unsigned char x,unsigned char *value) { unsigned char add; switch (y) { case 1 : add = 0x80 + x; break; case 2 : add = 0xc0 + x; break; default : break; } LCD_Write(write_comm,add); while(*value != '\0') { LCD_Write(write_data,*value); value ++; } } /********************************************* *函数功能:自建一个字型,摄氏度左上角的小圆 *********************************************/ void Write_CGRAM(void) { 52 www.ele169.com 制作项目 MAKE PROJECT unsigned char i; unsigned char tmp = 0x40; //操作CGRAM的命令码 for(i = 0; i < 8; i ++) // 8 个字节生成 1 个字符点阵 { LCD_Write(write_comm,tmp + i); //写入CGRAM地址 LCD_Write(write_data,Pat[i]); //写入数据 } } 到此液晶底层操作完成,下一步就是主函数的编写。 主程序 在写主程序之前一般先画出流程图,本程序主要是从 AM2301读取数据,然后送LCD1602显示,流程简单所以 就不画流程图了。在写主函数之前还需对LCD1602进行 初始化和对从AM2301读回的数据进行处理。AM2301建 议打样周期为2s,本程序用定时器0精确定时,实现2s采 样一次。 所有程序代码如下: #include #include #define write_comm 0 //LCD写命令 #define write_data 1 //LCD写数据 unsigned char code Pat[8]={0X03,0X03,0x00,0x00,0x00,0x00,0x00,0x0 0}; //自建字形用 unsigned char AM2301_Data[5] = {0X00,0X00,0X00,0X00,0X00}; //用于接收40bit数据 unsigned char AM2301_Check; //校验和 unsigned int DATA; //数据处理用 unsigned char cont = 0; //定时器计数 /********************************************** *函数功能:延时函数 **********************************************/ void delay_ms(void) //延时3MS子程序,实际时间需实际调整 { unsigned char i,j; for(i = 0; i < 3; i ++) for(j = 0; j < 170; j ++); } /********************************************** *函数功能:液晶显示器初始化 **********************************************/ void LCD_INIT(void) { //1602的显示模式字为0x38 LCD_Write(write_comm,0x38); //显示模式设置第一次 delay_ms(); //延时3MS LCD_Write(write_comm,0x38); //显示模式设置第二次 delay_ms(); //延时3MS LCD_Write(write_comm,0x38); //显示模式设置第三次 delay_ms(); //延时3MS LCD_Write(write_comm,0x38); //显示模式设置第四次 delay_ms(); //延时3MS LCD_Write(write_comm,0x08); //显示关闭 LCD_Write(write_comm,0x01); //清屏 delay_ms(); //延时3MS LCD_Write(write_comm,0x06); //显示光标移动设置 LCD_Write(write_comm,0x0C); //显示开及光标设置 LCD_Show(1,4,"TEMP/RH%"); //第一行,第四个位置起显TEMP/RH% LCD_Show(2,0,"T:"); Write_CGRAM(); //在第二行,第六七个位置显示℃ LCD_Write(write_comm,0xc6); LCD_Write(write_data,0); //写入自建字形 LCD_Show(2,7,"C"); LCD_Show(2,9,"R:"); LCD_Show(2,15,"%"); } /********************************************** *函数功能:数据处理,送液晶显示 **********************************************/ void Data_Process(unsigned char add,unsigned int date) { unsigned char shi,ge,xiao; //声明变量十位,个位 ,小数位 shi = date / 100 % 10; //分离出十位 ge = date / 10 % 10; //分离出个位 xiao = date % 10; //分离出小数位 LCD_Write(write_comm,add); //显示坐标设置 LCD_Write(write_data,shi + 0x30); //显示十位 LCD_Write(write_comm,add+1); LCD_Write(write_data,ge + 0x30); //显示个位 LCD_Write(write_comm,add+2); LCD_Write(write_data,'.'); //显示小数点 532012.01 MCU单片机制作 LCD_Write(write_comm,add+3); LCD_Write(write_data,xiao + 0x30); //显示小数位 } /********************************************** *函数功能:显示函数 **********************************************/ void Display(void) { Read_AM2301(); //采样一次,读取数据 AM2301_Check = AM2301_Data[0] + AM2301_Data[1] + AM2301_ Data[2] + AM2301_Data[3];//校验和 if(AM2301_Check == AM2301_Data[4]) //如果校验成功 { DATA = ((AM2301_Data[2] * 256) + AM2301_Data[3]); //16bit温度数据整合 Data_Process(0xc2,DATA); //送数据处理函数处理 delay_ms(); //延时 DATA = ((AM2301_Data[0] * 256) + AM2301_Data[1]); //16bit湿度数据整合 Data_Process(0xcb,DATA); //送数据处理函数处理 } else //如果校验失败重新读取采样数据 { Read_AM2301(); } } /********************************************** *函数功能:主函数 **********************************************/ void main(void) { IE=0X82; //定时器0的一些配置 TMOD=0X01; TH0=(65536-50000)/256; TL0=(65536-50000)%256; TR0=1; LCD_INIT(); while(1) { if(cont==40) //中断40次,2S时间到 { cont=0; //清计数次数 Display(); //调用显示函数 } } } /********************************************** *函数功能:定时器0中断函数 **********************************************/ void Timer_0(void)interrupt 1 { TH0=(65536-50000)/256; //重新赋初值 TL0=(65536-50000)%256; cont++; //计数 } 制作过程 在绘制完原理图,写好程序并调试好后,将程序烧入 单片机中。就可以制作电路部分了。由于本电路简单元器 件不多,制作时可直接用洞洞板焊接。具体制作过程就不 一一列出了。 备注:制作时传感器,建议接上5k上拉电阻。使用场 合需注意,参见其数据手册,化学气体会对传感器产生干 扰,不建议在有化学气体的场合使用。液晶显示器在零度 以下无法正常工作,温度低的场合使用建议用数码管代替 液晶。在湿度高的场合需对电路部分进行隔离保护。 最终制作显示效果如9图所示。秋冬季节天气干燥, 注意保湿! 图9
/
本文档为【自制温湿度计】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。 本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。 网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。

历史搜索

    清空历史搜索