基于DSB温度计课程设计报告_第1页
基于DSB温度计课程设计报告_第2页
基于DSB温度计课程设计报告_第3页
基于DSB温度计课程设计报告_第4页
基于DSB温度计课程设计报告_第5页
已阅读5页,还剩24页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、洛 阳 理 工 学 院课 程 设 计 报 告 课程名称 单片机应用 设计题目 基于DS18B20和1602的温度计 专 业 计算机应用技术 班 级 Z120551 学 号 Z12055123 姓 名 李浩冰 完成日期 2014年6月12日 课 程 设 计 任 务 书设计题目: 基于DS18B20和1602的温度计 设计内容与要求:设计内容:采用STC89C51单片机,DS18B20数字温度采集器件,单总线驱动等电路设计制作一个点在温度计,能利用1602LCD液晶显示温度。设计要求:1)单片机系统扩展设计;、 2)温度采集设计; 3)显示功能设计; 指导教师:_ 年 月 日课 程 设 计 评 语

2、 成绩: 指导教师:_ 年 月 日洛 阳 理 工 学 院 课 程 设 计 报 告一、设计目的 在本设计中选用STC89C51型单片机作为主控制器件,采用DS18B20数字温度传感器作为测温元件,通过1602LCD液晶显示器实现温度显示。本设计的内容主要分为三部分,一是系统硬件设计,包括温度采集电路和显示电路;二是对系统软件部分的设计,应用C语言实现温度的采集与显示;三是通过1602LCD液晶显示与DS1302芯片显示其时间。通过DS18B20直接读取被测温度值,送入单片机进行数据处理,之后进行输出显示,最终完成了数字温度计的总体设计。其系统构成简单,信号采集效果好,数据处理速度快,便于实际检测

3、使用。二、设计指标2.1 设计要求(1)具有实时显示温度的功能,精度为1;(2)具备在液晶上显示年、月、日、星期、时、分、秒的功能; (3)具备年、月、日、星期、时、分、秒校准功能; (4)具有与实时时间同步的功能。 2.2 单片机芯片的选择采用STC89C51芯片作为硬件核心,内部具有4KB ROM 存储空间,能于3V的超低压工作,而且与MCS-51系列单片机完全兼容。2.3 显示模块的选择采用1602液晶显示屏,该液晶显示屏的显示功能强大,内置192种字符,可显示大量符号、数字,清晰可见,而且功率消耗小寿命长抗干扰能力强。所以在此设计中采用1602液晶显示屏。2.4 时钟的选择采用DS13

4、02时钟芯片实现时钟,DS1302芯片是一种高性能的时钟芯片,可自动对秒、分、时、日、周、月、年进行计数,而且精度高,位的RAM做为数据暂存区,工作电压2.5V5.5V范围内,2.5V时耗电小于300nA。2.5温度传感器的选择采用数字温度芯片DS18B20 测量温度,输出信号全数字化。便于单片机处理及控制,省去传统的测温方法的很多外围电路。且该芯片的物理化学性很稳定,它能用做工业测温元件,此元件线形较好。在0100 摄氏度时,最大线形偏差小于1 摄氏度。DS18B20 的最大特点之一采用了单总线的数据传输,由数字温度计DS18B20和微控制器AT89S51构成的温度测量装置,它直接输出温度的

5、数字信号,可直接与计算机连接。这样,测温系统的结构就比较简单,体积也不大。2.6电路设计最终方案决定 综上各方案所述,对此次设计的方案选定: 采用AT89C51作为主控制芯片,DS1302时钟芯片计时,DS18B20采集温度,LCD1602作为显示模块。三、总体框图设计 1602LCD 液晶显示器 单片机 STC89C51 DS1302 时钟芯片 DS18B20数字温度传感器 按键模块四、功能模块及原理说明1.单片机芯片模块:STC89C51RC是采用8051核的ISP(In System Programming)在系统可编程芯片,最高工作时钟频率为80MHz,片内含8K Bytes的可反复擦

6、写1000次的Flash只读程序存储器,器件兼容标准MCS-51指令系统及80C51引脚结构,芯片内集成了通用8位中央处理器和ISP Flash存储单元,具有在系统可编程(ISP)特性,配合PC端的控制程序即可将用户的程序代码下载进单片机内部,省去了购买通用编程器,而且速度更快。STC89C52RC系列单片机是单时钟/机器周期(1T)的兼容8051 内核单片机,是高速/ 低功耗的新一代8051 单片机,全新的流水线/精简指令集结构,内部集成MAX810 专用复位电路。STC89C51RC实物图如图一所示,引脚图如图二所示: 图一 图二 2. 显示模块: 1602液晶也叫1602字符型液晶,它是

7、一种专门用来显示字母、数字、符号等的点阵型液晶模块。它由若干个5X7或者5X11等点阵字符位组成,每个点阵字符位都可以显示一个字符,每位之间有一个点距的间隔,每行之间也有间隔,起到了字符间距和行间距的作用,1602LCD是指显示的内容为16X2,即可以显示两行,每行16个字符液晶模块(显示字符和数字)。1602LCD显示器实物图如图三: 图三 图四3.时钟芯片模块:DS1302 是美国DALLAS公司推出的一种高性能、低功耗、带RAM的实时时钟电路,它可以对年、月、日、周日、时、分、秒进行计时,具有闰年补偿功能,工作电压为2.5V5.5V。采用三线接口与CPU进行同步通信,并可采用突发方式一次

8、传送多个字节的时钟信号或RAM数据。DS1302内部有一个31×8的用于临时性存放数据的RAM寄存器。DS1302是DS1202的升级产品,与DS1202兼容,但增加了主电源/后备电源双电源引脚,同时提供了对后备电源进行涓细电流充电的能力。DS1302时钟芯片实物图如图四:4. 温度传感器模块:DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样,有LTM8877,LTM8874等等。主要根据应用场合的不同而改变其外观。封装后的DS18B20可用于电缆沟测温,高炉水循环测温,锅炉测温,机房测温,农业大棚测温,洁净室测

9、温,弹药库测温等各种非极限温度场合。耐磨耐碰,体积小,使用方便,封装形式多样,适用于各种狭小空间设备数字测温和控制领域。DS1802数字温度传感器DS18B20内部结构图如图五所示,实物管脚分布图如图六所示: 图五 图六 五、设计验证1.在仿真软件上选取以上元件,元件图如图七所示: 图七 图八2.在仿真软件上进行布局连线,如图八所示:3.程序设计:(1)温度传感器代码如下:DS18B20.h:#include<intrins.h>#include<reg51.h>void Display_char(unsigned char addr, unsigned char da

10、t);unsigned char code time="0123456789"sbit DQ=P27;static unsigned char LCD_Dis_sign;void delay_100ms()/延时函数100ms unsigned char a1,a2,a3; for(a3=1;a3>0;a3-) for(a2=232;a2>0;a2-) for(a1=214;a1>0;a1-) void delay_750us()unsigned char a1; for(a1=149;a1>0;a1-) _nop_(); _nop_(); _nop

11、_(); void delay_15us() unsigned char a1; for(a1=5;a1>0;a1-) void delay_45us() unsigned char a1; for(a1=20;a1>0;a1-) void delay_240us() unsigned char a1; for(a1=43;a1>0;a1-) _nop_(); _nop_(); _nop_(); /*DS18B20初始化函数*/void DS18B20_Init()DQ=1; /拉为高电平_nop_();DQ=0; /拉为低电平 delay_750us(); /延时750us

12、 DQ=1; /释放总线delay_15us(); /延时15us,如果DS18B20初始化成功,会把总线DQ拉低while(DQ); /等待总线被拉低delay_240us(); DQ=1; /拉高电平释放总线/*DS18B20写函数*/void Write_DS18B20(unsigned char command)unsigned char i,temp;for(i=0;i<8;i+)temp=command&0x01;/*作用?DQ=1;/拉为高电平_nop_();DQ=0;delay_15us();if(temp=1) /判断写0还是写1DQ=1;elseDQ=0;de

13、lay_45us(); /延时45usDQ=1;command >>= 1; DQ=1; /释放总线/*DS18B20读函数*/unsigned char Read_DS18B20()unsigned char i,temp;for(i=0;i<8;i+)temp >>= 1; /先右移一位,消耗一个for循环,如果不这样做,读出的数据会不正确DQ=0;_nop_();_nop_();DQ=1; /根据手册,需释放总线_nop_();_nop_();_nop_();_nop_();if(DQ) /判断总线读出的数据temp=temp|0x80; /temp与0x8

14、0或运算的作用?delay_45us(); return temp; /*DS18B20转换温度函数*/void DS18B20_Start_Conversion()DS18B20_Init(); /复位Write_DS18B20(0xcc); /跳过ROMWrite_DS18B20(0x44); /开始转换温度 对芯片写入0x44 /芯片接收转换指令后,把一些温度有关的模拟量转变成数字信号,再把此数值放入相应的RAM上delay_100ms(); /延时100ms,转换时间 这里如果太长,读出的会慢DS18B20_Init(); /复位Write_DS18B20(0xcc); /Write_

15、DS18B20(0xbe);/0xbe读取暂存器指令/*获得转换温度函数*/unsigned char Get_temperature()unsigned char temp1,temp2;DS18B20_Start_Conversion(); /温度开始转换并发出读取命令temp1=Read_DS18B20();temp2=Read_DS18B20(); /读取暂存器前两个字节DS18B20_Init(); /读取完前两个字节后,终止读取if(temp2&0xf8)=0xf8) /判断,如果读取的温度是负数LCD_Dis_sign=1; /液晶显示标志 温度为负数return (te

16、mp2<<8)|temp1)+1)*0.0625); /单片机二进制转十进制 /把Temp2的值左移8位,然后或Temp1,非运算,再加1 /得到的数再乘以0.0625,将值赋给TemperatureLCD_Dis_sign=0; /温度小于100度且为正return (temp2<<8)|temp1)*0.0625);/*液晶显示函数*/void LCD_Dis_temperature()unsigned int temp;temp=Get_temperature();/获得温度if(temp>=100) /如果温度大于等于100度,置液晶显示标志为3LCD_D

17、is_sign=3; /温度大于等于100度switch(LCD_Dis_sign)case 0: Display_char(0xcb,' '); /如果温度小于100度且为正,执行case 0Display_char(0xcc,timetemp/10); /十位Display_char(0xcd,timetemp%10); /个位Display_char(0xce,'C'); /温度符号break;case 1:Display_char(0xcb,'-');/如果温度为负数,液晶显示'-',执行case 1Display_cha

18、r(0xcc,timetemp/10);Display_char(0xcd,timetemp%10);Display_char(0xce,'C');break;case 3:Display_char(0xcb,timetemp/100);/如果温度大于等于100度,执行case 3Display_char(0xcc,time(temp%100)/10);Display_char(0xcd,time(temp%100)%10);Display_char(0xce,'C');break;(2) 时钟代码如下:DS1302.h:#include<reg51.h&

19、gt;#define uchar unsigned char#define uint unsigned int sbit CE=P37; sbit IO=P36; sbit SCLK=P35; #define W_SEC 0X80 #define R_SEC 0X81 /读写秒寄存器 #define W_MIN 0X82 #define R_MIN 0X83 /读写分寄存器 #define W_HOUR 0X84 #define R_HOUR 0X85 /读写时寄存器 #define W_DAY 0X86 #define R_DAY 0X87 /读写日寄存器 #define W_MON 0X8

20、8 #define R_MON 0X89 /读写月寄存器 #define W_WEEK 0X8A #define R_WEEK 0X8B /读写周寄存器 #define W_YEAR 0X8C #define R_YEAR 0X8D /读写年寄存器 #define W_PROTECT 0X8E /写控制寄存器(主要用来允许禁止写保护) /*DS1302写函数 函数原型:void Write_DS1302(uchar addr,uchar date) 函数参数:addr-地址 date-数据 函数返回值:无 函数意义:向某个地址处写入某个数据*/ void Write_DS1302(uchar

21、addr,char date) uchar i;CE=0;SCLK=0;CE=1;for(i=0;i<8;i+)SCLK=0;IO=(bit)(addr&0x01);SCLK=1;addr >>= 1;for(i=0;i<8;i+)SCLK=0;IO=(bit)(date&0x01);SCLK=1;date >>= 1;CE=0; /*DS1302读函数 函数原型:uchar Read_DS1302(uchar addr) 函数参数:addr-地址 函数返回值:读取到的数据 函数意义:在某个地址处读取数据*/ uchar Read_DS130

22、2(uchar addr) uchar temp,i;CE=0;SCLK=0;CE=1;for(i=0;i<8;i+)SCLK=0;IO=(bit)(addr&0x01);SCLK=1;addr >>= 1; /先写入地址for(i=0;i<8;i+)if(IO)temp=temp|0x80;SCLK=1;SCLK=0;temp >>= 1;CE=0;return (temp&0xf0)>>4)*10+(temp&0x0f);/十六进制转换成十进制 /*初始化DS1302函数函数原型:Init_DS1302()函数参数:无

23、函数返回值:无函数意义:对DS1302芯片各寄存器初始化*/*读秒寄存器函数原型:uchar Read_sec()函数参数:无函数返回值:读出秒的数据函数意义:读出当前秒的数据并返回*/uchar Read_sec()uchar val;val=Read_DS1302(R_SEC);return val;/*读分寄存器函数原型:uchar Read_min()函数参数:无函数返回值:读出FEN的数据函数意义:读出当前分的数据*/uchar Read_min()uchar val;val=Read_DS1302(R_MIN);return val;/*读时寄存器函数原型:uchar Read_h

24、our()函数参数:无函数返回值:读出hour的数据函数意义:读出当前hour的数据并返回*/uchar Read_hour()uchar val;val=Read_DS1302(R_HOUR);return val;/*读日寄存器函数原型:uchar Read_day()函数参数:无函数返回值:函数意义:读出当前日的数据并返回*/uchar Read_day()uchar val;val=Read_DS1302(R_DAY);return val;/*读月寄存器函数原型:uchar Read_mon()函数参数:无函数返回值:读出月寄存器数据函数意义:读出月寄存器的数据并返回*/uchar

25、Read_mon()uchar val;val=Read_DS1302(R_MON);return val;/*读周寄存器函数原型:uchar Read_week() 函数参数:无函数返回值:读出 函数意义:读出当前*/uchar Read_week()uchar val;val=Read_DS1302(R_WEEK);return val;/*读年寄存器函数原型:uchar Read_year()函数参数:无函数返回值:读出函数意义:读出*/uchar Read_year()uchar val;val=Read_DS1302(R_YEAR);return val;(3) 按键代码如下:key

26、.c:#include<reg51.h>sbit SET=P10;sbit ADD=P11;sbit SUB=P12;static unsigned char KEY;static char min,hour,mon,day,year,week;void ADD_Down();void SUB_Down();void Set_Key_down()if(SET=0)/如果设置键按下delay_15us();if(SET=0)while(!SET);KEY+;switch(KEY)case 1: Write_LCD1602_command(0xc4); Write_LCD1602_co

27、mmand(0x0F);/液晶光标在分位置闪烁min=Read_DS1302(R_MIN);break;case 2: Write_LCD1602_command(0xc1); hour=Read_DS1302(R_HOUR);/Write_LCD1602_command(0x0f);/液晶光标在时位置闪烁break; case 3: Write_LCD1602_command(0x89); day=Read_DS1302(R_DAY);/Write_LCD1602_command(0x0f);/液晶光标在日位置闪烁 break;case 4: Write_LCD1602_command(0x

28、86); mon=Read_DS1302(R_MON);/Write_LCD1602_command(0x0f);/液晶光标在月位置闪烁break; case 5: Write_LCD1602_command(0x83); year=Read_DS1302(R_YEAR); /Write_LCD1602_command(0x0f);/液晶光标在年位置闪烁break; case 6: Write_LCD1602_command(0x8c); week=Read_DS1302(R_WEEK);/Write_LCD1602_command(0x0f);/液晶光标在周位置闪烁break; defaul

29、t: KEY=0; Write_LCD1602_command(0x0c);/取消光标闪烁 Write_DS1302(W_PROTECT,0X80);/允许写保护 break;void ADD_Down()if(KEY!=0)if(ADD=0)delay_15us();if(ADD=0)while(!ADD);switch(KEY)case 1: min+;if(min=60)min=0;Write_DS1302(W_MIN,(min/10)<<4|(min%10);LCD_Dis_min(); Write_LCD1602_command(0xc4); break;case 2:h

30、our+;if(hour=24)hour=0; Write_DS1302(W_HOUR,(hour/10)<<4|(hour%10); LCD_Dis_hour(); Write_LCD1602_command(0xc1); break;case 3:day+;if(day=32)day=1; Write_DS1302(W_DAY,(day/10)<<4|(day%10); LCD_Dis_day(); Write_LCD1602_command(0x89); break;case 4:mon+;if(mon=13)mon=1; Write_DS1302(W_MON,(

31、mon/10)<<4|(mon%10); LCD_Dis_mon(); Write_LCD1602_command(0x86); break;case 5:year+;if(year=99)year=0; Write_DS1302(W_YEAR,(year/10)<<4|(year%10); LCD_Dis_year(); Write_LCD1602_command(0x83); break;case 6:week+;if(week=8)week=1; Write_DS1302(W_WEEK,(week/10)<<4|(week%10); LCD_Dis_w

32、eek(); Write_LCD1602_command(0x8c); break;void SUB_Down()if(KEY!=0)if(SUB=0)delay_15us();if(SUB=0)while(!SUB);switch(KEY)case 1: min-;if(min<0)min=59;Write_DS1302(W_MIN,(min/10)<<4|(min%10);LCD_Dis_min(); Write_LCD1602_command(0xc4); break;case 2:hour-;if(hour<0)hour=23; Write_DS1302(W_H

33、OUR,(hour/10)<<4|(hour%10); LCD_Dis_hour(); Write_LCD1602_command(0xc1); break;case 3:day-;if(day=0)day=31; Write_DS1302(W_DAY,(day/10)<<4|(day%10); LCD_Dis_day(); Write_LCD1602_command(0x89); break;case 4:mon-;if(mon=0)mon=12; Write_DS1302(W_MON,(mon/10)<<4|(mon%10); LCD_Dis_mon()

34、; Write_LCD1602_command(0x86); break;case 5:year-;if(year<0)year=99; Write_DS1302(W_YEAR,(year/10)<<4|(year%10); LCD_Dis_year(); Write_LCD1602_command(0x83); break;case 6:week-;if(week=0)week=7; Write_DS1302(W_WEEK,(week/10)<<4|(week%10); LCD_Dis_week(); Write_LCD1602_command(0x8c); b

35、reak; (4) 显示代码如下:LCD1602.h:/* P0-DB0DB7 P20-LCD_RS P21-LCD_RW P22-LCD_E*/#include<reg51.h>#define LCD_DB P0#define uchar unsigned char#define uint unsigned intsbit LCD_RS=P24;sbit LCD_RW=P25;sbit LCD_E=P26;/*定义申明函数*/unsigned char code table="Welcome LCD1602"uchar table1="MONTUEW

36、ESTHUFRISATSUN"/每三个字母是一个星期X的简写/*/*延时函数*/void delay_n10us(unsigned int n)unsigned int i,j;for(i=n;i>0;i-)for(j=100;j>0;j-);/*写指令函数*/void Write_LCD1602_command(unsigned char cmd)LCD_RS=0;LCD_RW=0;LCD_DB=cmd;delay_n10us(5);LCD_E=1;delay_n10us(15);LCD_E=0;/*写数据函数*/void Write_LCD1602_data(unsi

37、gned char dat)LCD_RS=1;LCD_RW=0;LCD_DB=dat;delay_n10us(5);LCD_E=1;delay_n10us(15);LCD_E=0;/*检测忙状态*/void CHECK_LCD1602_Busy()uchar state;LCD_RS=0; /RS为低电平0,RW为高电平时1,可以读液晶模块(忙或不忙)的状态 LCD_RW=1;LCD_E=1; /E=1,才允许读写 (满足了E=R/W=1,RS=0)delay_n10us(1);state=LCD_DB; /将忙碌标志电平赋给stateLCD_E=0; /将E恢复低电平while(state&

38、amp;0X80);delay_n10us(5);/*LCD开机显示函数*/void LCD1602_Init_display()uint i;Write_LCD1602_command(0x80);for(i=0;i<16;i+) Write_LCD1602_data(tablei);/*初始化函数*/void Init_LCD1602(void)Write_LCD1602_command(0x38); /设置16×2显示,5×7点阵,8位数据接口Write_LCD1602_command(0x01); /清屏设置Write_LCD1602_command(0x06

39、);/ 光标移动设置 N=1读或写一个字符后地址指针加1 S=0 整屏显示不移动Write_LCD1602_command(0x0c);/显示开及光标设置 C=0 光标不显示 B=0 光标不闪烁LCD1602_Init_display();/调用LCD1602_Init_display()函数在第一行显示 "welcome LCD1602"/*液晶某处显示某个字符函数*/void Display_char(unsigned char addr, unsigned char dat)Write_LCD1602_command(addr);Write_LCD1602_data(

40、dat);/*液晶显示时间日期分隔符与念头20*/void LCD_Dis_symbols()Display_char(0x80,'2');Display_char(0x81,'0');Display_char(0x84,'-');Display_char(0x87,'-');Display_char(0xc2,':');Display_char(0xc5,':');/*显示年函数*/void LCD_Dis_year()unsigned char temp,year1,year2;temp=Rea

41、d_year(); /读取年寄存器的值year1=temp/10;year2=temp%10;Display_char(0x82,timeyear1);Display_char(0x83,timeyear2);/*显示月函数*/void LCD_Dis_mon()unsigned char temp,mon1,mon2;temp=Read_mon(); /读取月寄存器的值mon1=temp/10;mon2=temp%10;Display_char(0x85,timemon1);Display_char(0x86,timemon2);/*显示日函数*/void LCD_Dis_day()unsi

42、gned char temp,day1,day2;temp=Read_day(); /读取日寄存器的值day1=temp/10;day2=temp%10;Display_char(0x88,timeday1);Display_char(0x89,timeday2);/*显示时函数*/void LCD_Dis_hour()unsigned char temp,hour1,hour2;temp=Read_hour(); /读取时寄存器的值hour1=temp/10;hour2=temp%10;Display_char(0xc0,timehour1);Display_char(0xc1,timehour2);/*显示分函数*/void LCD_Dis_min()unsigned char temp,min1,min2;temp=Read_min(); /读取分寄存器的值min1=temp/10;min2=temp%10;Display_char(0xc3,timemin1);Display_char(0xc4,timemin2

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论