• 306.32 KB
  • 15页

数字温度设计项目报告

  • 15页
  • 当前文档由用户上传发布,收益归属用户
  1. 1、本文档共5页,可阅读全部内容。
  2. 2、本文档内容版权归属内容提供方,所产生的收益全部归内容提供方所有。如果您对本文有版权争议,可选择认领,认领后既往收益都归您。
  3. 3、本文档由用户上传,本站不保证质量和数量令人满意,可能有诸多瑕疵,付费之前,请仔细先通过免费阅读内容等途径辨别内容交易风险。如存在严重挂羊头卖狗肉之情形,可联系本站下载客服投诉处理。
  4. 文档侵权举报电话:19940600175。
'数字温度计设计报告题目:数字温度计班级:2010级电子信息工程技术班指导老师:何乃味组员:梁家源20100504006林家平20100206033覃泽20100206008韦志丹20100206031 目录1、引言2、项目设计的任务3、项目设计的要求4、项目的硬件设计5、项目设计的软件流程6、项目设计的总结7、项目设计的主程序显示 一、引言社会的不断发展,人们生活水平的不断提高。一方面,单片机控制无疑是人们追求的目标之一,它所给人带来的方便也是不可否定的,其中数字温度计就是一个典型的例子,但人们对它的要求越来越高,要为现代人工作、科研、生活、提供更好的更方便的设施就需要从数单片机技术入手,一切向着数字化控制,智能化控制方向发展。传统的单片机温度控制器用热敏电阻测量温度,须包含模拟测量电路及A/D转换器,且占用单片机的口线多,必要时须增加I/O扩展接口芯片,电路器件多,降低了可靠性。而采用新型的单线数字温度传感器DS18B20测量温度则克服了上述缺点。DS18B20是美国DALLAS半导体公司近年推出的一种改进型智能温度传感器,与传统的热敏电阻相比,它能够直接读出被测温度,并可根据实际要求通过简单的编程实现9-12位的数字值读数方式,无需外加测量电路及A/D转换器,简化了电路;而且从DS18B20读出或写入信息仅需一根口线,大大降低了单片机的硬件资源占用。基于DS18B20的单片机温度控制器具有电路简单、可靠性高的优点。本设计所介绍的数字温度计与传统的温度计相比,具有读数方便,测温范围广,测温准确,其输出温度采用数字显示,主要用于对测温比较准确的场所,或科研实验室使用,该设计控制器使用单片机AT89c51,测温传感器使用DS18B20,用LCD1602液晶显示器实现温度显示,能准确达到以上要求。本数字式温度计对温度进行实时测量并显示(华氏与摄氏温度都可显示,通过一按键显示),用户可设定最高限报警温度值和最低限报警温度值,有一定的温度控制功能二、设计任务以单片机为核心器件,设计一个数字式温度计三、设计要求1.测量并显示温度值,温度测量误差≤±1℃。2.测量范围:0℃~100℃。3.用LCD显示当前测量的温度。4.可以通过按键设置上下限报警温度。5.当测量的温度超过设定的上、下限温度时,能启动蜂鸣器和指示灯报警。6.画出硬件电路图并说明电路的工作原理。7.画出程序设计流程图。8.编写和调试各模块源程序。9.完成整个项目源程序的综合调试。10.用DS18B20实时采集温度信号并显示11.能够通过切换按钮可以切换华氏度和摄氏度显示;四、设计的硬件图 实物图五、设计的软件流程(1)主程序主要是对系统进行初始化,包括复位、液晶显示、按键、温度传感器18b20、振荡器(下图)是主程序的流程图。主程序main():完成键盘扫描、温度值采集及转换、温度值的显示。当温度值高于设定最高限时或低于设定最低限时,驱动声光报警电路进行报警。  主程序流程图1、温度采集程序Get_Tmp():完成DS18B20的初始化并发出温度转换命令,经过指定时间后读取转换的温度值。2、温度数据处理程序data_process(uinttmp):将采集到的温度值转换成便于液晶显示的ASCII码值。 温度传感器18B20的介绍(下图)按键扫描程序KEYSCAN: 完成键盘的扫描并根据确定的键值执行相应的功能,主要完成最高温度、最低温度的设定LCD液晶显示Vss:+5V电源管脚(Vcc)VDD:地管脚(GND) Vo:液晶显示驱动电源(0V~5V)DB0~DB7:数据线,可以用8位连接,也可以只用高4位连接,节约单片机资源.A:背光控制正电源K:背光控制地RS:数据和指令选择控制端,RS=0:命令/状态;RS=1:数据R/W:读写控制线,R/W=0:写操作;R/W=1:读操作E:数据读写操作控制位,E线向LCD模块发送一个脉冲,LCD模块与单片机之间将进行一次数据交换六、项目总结通过本次项目设计可以让我们了解数字式温度计可以实现我们所规定功能。本系统以AT89C52单片机,温度传感器DS18B20和通用LCD1602显示模块为核心,实现了低功耗高精度便携式数字温度计的设计。DS18B20传感器精度高、互换性好;它直接将温度数据进行编码。从这次的课程设计中,我真真正正的意识到,一切从实践出发,所谓实践是检验真理的唯一真理。在以后的学习中,要理论联系实际,把我们所学的理论知识用到实际当中,学习单机片机更是如此,程序只有在经常的写与读的过程中才能提高,这就是我在这次课程设计中的最大收获。八、设计的主程序 #include#include#defineLCD_DATA_PORTP1//液晶数据接口在P1口#defineLCD_RSP1_2//液晶数据寄存器/指令寄存器端接P1.2#defineLCD_ENP1_3//液晶使能端接P1.3sbitDQ=P1^1;//DS18B20数据口接P1.1#defineucharunsignedchar#defineuintunsignedintucharData[5]={0,0,0,0,0};//液晶显示数据缓冲区ucharData2[3]={0,0,0};//液晶显示数据缓冲区ucharData3[3]={0,0,0};//液晶显示数据缓冲区uinttemp;//存放温度值variableoftemperaturechartemp_L=25,temp_H=30;//定义最低高报警温度值,sbitkey_set=P2^0;//sbitkey_up=P2^1;//加1键sbitkey_down=P2^2;//减1键/*************函数声明**************/voidLCD_write_char(ucharData_or_command,ucharcommand);/*************比较精确的延时函数**************/voiddelay(uchari){while(--i);}/**************n毫秒延时函数**********/voiddelay_nms(uintn){uchari=0;while(n--){for(i=0;i<120;i++);}}/*************液晶初始化函数***********/voidLCD_init(void){delay_nms(5);LCD_write_char(0x28,0);//选择4位显示模式LCD_write_char(0x0c,0);//显示屏开LCD_write_char(0x06,0);//显示地址自动加一LCD_write_char(0x01,0);//清除屏幕}/************液晶使能函数***************/voidLCD_en_write(void) {LCD_EN=0;delay(20);LCD_EN=1;delay(20);LCD_EN=0;}/*************写命令或写数据函数*************/voidLCD_write_data(ucharData_command){uchartemp;temp=Data_command;LCD_DATA_PORT&=0X0f;LCD_DATA_PORT|=temp&0xf0;//写高四位LCD_en_write();temp=temp<<4;LCD_DATA_PORT&=0x0f;LCD_DATA_PORT|=temp&0xf0;//写低四位LCD_en_write();}/************写命令和写数据函数*********///参数:command=1,写数据,command=0,写命令voidLCD_write_char(ucharData_or_command,ucharcommand){if(command==0){LCD_RS=0;//RS=0,选择指令寄存器LCD_write_data(Data_or_command);}else{LCD_RS=1;//RS=1,选择数据寄存器LCD_write_data(Data_or_command);}}/*****************设置显示地址函数*****************///参数:x为显示在第几列,y为显示在第几行voidLCD_set_xy(ucharx,uchary){ucharaddress;if(y==0)address=0x80+x;elseaddress=0xc0+x;LCD_write_char(address,0);}/*********************写字符串函数************///参数:X为显示在第几列,Y为显示在第几行,s为待显示字符串 voidLCD_write_string(ucharX,ucharY,uchar*s){LCD_set_xy(X,Y);//写地址while(*s)//写显示字符{LCD_write_char(*s,1);s++;}}/*****************DS18B20初始化*****/voidInit_Ds18b20(void){DQ=1;//DQ复位。delay(1);//稍做延时DQ=0;//单片机拉低总线delay(250);//精确延时,维持至少480usDQ=1;//释放总线,即拉高了总线delay(100);//延时有足够,确保能让DS18B20发出存在脉冲。}/*****************读取一个字节的数据*********///读数据时,数据以字节的最低有效位先从总线移出ucharRead_One_Byte(){uchari=0;uchardat=0;for(i=8;i>0;i--){DQ=0;//将总线拉低,要在1us之后释放总线//单片机要在此下降沿后的15us内读数据才会有效。_nop_();//至少维持了1us,表示读时序开始dat>>=1;//让从总线上读到的位数据,依次从高位移动到低位。DQ=1;//释放总线,此后DS18B20会控制总线,把数据传输到总线上delay(1);//延时7us,此处参照推荐的读时序图,尽量把控制器采样时间放到读时序后的15us内的最后部分if(DQ)//控制器进行采样{dat|=0x80;//若总线为1,即DQ为1,那就把dat的最高位置1;若为0,则不进行处理,保持为0}delay(10);//此延时不能少,确保读时序的长度60us。}return(dat);}/*****************写一个字节的数据**********/ voidWrite_One_Byte(uchardat){uchari=0;for(i=8;i>0;i--){DQ=0;//拉低总线_nop_();//至少维持了1us,表示写时序(包括写0时序或写1时序)开始DQ=dat&0x01;//从字节的最低位开始传输//指令dat的最低位赋予给总线,必须在拉低总线后的15us内,//因为15us后DS18B20会对总线采样。delay(10);//必须让写时序持续至少60usDQ=1;//写完后,必须释放总线,dat>>=1;delay(1);}}/*****************温度转换子函数******************/uintGet_Tmp()//获取温度getthetemperature{floattt;uchara,b;Init_Ds18b20();//初始化Write_One_Byte(0xcc);//忽略ROM指令Write_One_Byte(0x44);//温度转换指令Init_Ds18b20();//初始化Write_One_Byte(0xcc);//忽略ROM指令Write_One_Byte(0xbe);//读暂存器指令a=Read_One_Byte();//读取到的第一个字节为温度LSBb=Read_One_Byte();//读取到的第一个字节为温度MSBtemp=b;//先把高八位有效数据赋于temptemp<<=8;//把以上8位数据从temp低八位移到高八位temp=temp|a;//两字节合成一个整型变量tt=temp*0.0625;//得到真实十进制温度值//因为DS18B20可以精确到0.0625度//所以读回数据的最低位代表的是0.0625度temp=tt*10+0.5;//放大十倍//这样做的目的将小数点后第一位也转换为可显示数字//同时进行一个四舍五入操作。returntemp;//返回测得的温度值}/*******将转换得的温度值转换成ASCII码子函数******/voiddata_process(uinttmp){ Data[0]=tmp/100+0x30;//百位Data[1]=tmp%100/10+0x30;//十位Data[2]=".";Data[3]=tmp%10+0x30;//个位Data[4]=0xdf;Data[5]="C";Data[6]="";}voidset_alarm_display_L(){Data2[0]=temp_L/10+0x30;//十位Data2[1]=temp_L%10+0x30;//个位Data2[2]="";}voidset_alarm_display_H(){Data3[0]=temp_H/10+0x30;//十位Data3[1]=temp_H%10+0x30;//个位Data3[2]="";}voidbeep_on_short(){P1_0=0;delay_nms(25);P1_0=1;delay_nms(25);}voidbeep_on_long(){P1_0=0;delay_nms(100);P1_0=1;delay_nms(100);}voidalarm(){if((Data[0]==Data2[0])&&(Data[1]==Data2[1]))beep_on_long();elseif((Data[0]==Data3[0])&&(Data[1]==Data3[1]))beep_on_short();}voidLCD_display(){LCD_write_string(1,0,"NOWTemp=");LCD_write_string(10,0,Data);LCD_write_string(1,1,"T_L=");set_alarm_display_L();LCD_write_string(5,1,Data2);set_alarm_display_H();LCD_write_string(9,1,"T_H="); LCD_write_string(13,1,Data3);}/***********键盘扫描子函数********/voidkey_scan(){bitID=0;//设置温度标志位,为1进入设置时间,为0退出if(key_set==0)//设置键按下{delay_nms(10);//延时消除抖动if(key_set==0){while(key_set==0)//调用显示,等待按键放开{;}ID=!ID;//按键放开,标志位取反}}while(ID!=0)//标志位为1,进入温度调整{if(key_up==0)//加1键按下{delay_nms(10);//延时消除抖动if(key_up==0){while(key_up==0)//调用显示,等待按键放开{;}temp_L++;//加1调整if(temp_L>99)temp_L=0;}}elseif(key_down==0)//减1键按下{delay_nms(10);//延时消除抖动if(key_down==0){while(key_down==0)//调用显示,等待按键放开{;}temp_H++;//减1调整if(temp_H>99)temp_H=0;}}elseif(key_set==0)//设置键再次按下,退出温度调整 {delay_nms(10);if(key_set==0){while(key_set==0){;}ID=0;//ID=0,退出时温度调整}}LCD_display();}}/************主函数***********/voidmain(){LCD_init();while(1){data_process(Get_Tmp());LCD_display();alarm();key_scan();}}'