《基于51单片机与DS18B20的数字温度计设计(共28页).doc》由会员分享,可在线阅读,更多相关《基于51单片机与DS18B20的数字温度计设计(共28页).doc(28页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、精选优质文档-倾情为你奉上四川师范大学课程设计报告基于单片机的DS18B20数字温度计设计学生姓名院系名称物理与电子工程学院专业名称电子信息工程班 级学 号指导教师完成时间基于单片机的DS18B20数字温度计设计学生姓名: 指导老师: 内容摘要:随着现代信息化技术的飞速发展和传统工业改造的逐步实现,能独立工作的温度检测系统已广泛应用于各种不同的领域。本文介绍了一个基于STC89C52单片机和数字温度传感器DS18B20的测温系统,并用LED数码管显示温度值,易于读数。系统电路简单、操作简便,能任意设定报警温度并可查询最近的10个温度值,系统具有可靠性高、成本低、功耗小等优点。关键词:单片机 数
2、字温度传感器 温度计目 录1 引言随着人们生活水平的不断提高,单片机控制无疑是人们追求的目标之一,它所给人带来的方便是不可否定的,各种数字系统的应用也使人们的生活更加舒适。数字化控制、智能控制为现代人的工作、生活、科研等方面带来方便。其中数字温度计就是一个典型的例子。数字温度计与传统的温度计相比,具有读数方便、测温范围广、测温精确、功能多样话等优点。其主要用于对测温要求准确度比较高的场所,或科研实验室使用,该设计使用STC89C52单片机作控制器,数字温度传感器DS18B20测量温度,单片机接受传感器输出,经处理用LED数码管实现温度值显示。2 设计要求2.1 基本要求实现实时温度显示,测温范
3、围0500C,误差50C以内。2.2 扩展功能温度报警,能任意设定温度范围实现声光报警;每隔10分钟记录一次温度数据,至少能查询过去10个时刻的温度情况。3 总体方案设计3.1 方案论证3.1.1 方案一由于本设计是测温电路,可以使用热敏电阻之类的器件,将随被测温度变化的电压或电流采样,进行A/D转换后就可以用单片机进行数据处理,实现温度显示。这种设计需要用到A/D转换电路,增大了电路的复杂性,而且要做到高精度也比较困难。3.1.2 方案二考虑到在单片机属于数字系统,容易想到数字温度传感器,可选用DS18B20数字温度传感器,此传感器为单总线数字温度传感器,起体积小、构成的系统结构简单,它可直
4、接将温度转化成串行数字信号给单片机处理,即可实现温度显示。另外DS18B20具有3引脚的小体积封装,测温范围为-55+125摄氏度,测温分辨率可达0.0625摄氏度,其测量范围与精度都能符合设计要求。以上两种方案相比较,第二种方案的电路、软件设计更简单,此方案设计的系统在功耗、测量精度、范围等方面都能很好地达到要求,故本设计采用方案二。3.2 总体设计框图本方案设计的系统由单片机系统、数字温度传感器、LED显示模块、按键控制模块、温度报警模块组成,其总体架构如下图1。单片机报警电路显示电路驱动电路测温电路按键输入电路时钟、复位电路图1 系统总体方框图4 硬件设计4.1 单片机系统1. 本设计采
5、用STC89C52单片机作为控制器,完成所有功能的控制,包括:l DS18B20数字温度传感器的初始化和读取温度值l LED数码管显示驱动与控制l 按键识别和响应控制l 温度设置和报警l 温度值的存储和读取2. 单片机系统电路原理图:图2 单片机系统原理图4.2 数字温度传感器模块4.2.1 DS18B20性能l 独特的单线接口仅需一个端口引脚进行通信l 简单的多点分布应用l 无需外部器件l 可通过数据线供电l 零待机功耗l 测温范围-55+125,以0.5递增l 可编程的分辨率为912位,对应的可分辨温度分别为0.5、0.25、0.125和0.0625l 温度数字量转换时间200ms,12位
6、分辨率时最多在750ms内把温度转换为数字l 应用包括温度控制、工业系统、消费品、温度计和任何热感测系统l 负压特性:电源极性接反时,传感器不会因发热而烧毁,但不能正常工作4.2.2 DS18B20外形及引脚说明图3 DS18B20外形及引脚l GND:地l DQ:单线运用的数据输入/输出引脚l VD:可选的电源引脚4.2.3 DS18B20接线原理图单总线通常要求接一个约4.7K左右的上拉电阻,这样,当总线空闲时,其状态为高电平。图4 DS18B20接线原理图4.2.4 DS18B20时序图主机使用时间隙来读写DS18B20的数据位和写命令字的位。1. 初始化时序如下图:图5 DS18B20
7、初始化时序2. DS18B20读写时序:图6 DS18B20读写时序4.2.5 数据处理高速暂存存储器由9个字节组成,其分配如表5所示。当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在 高速暂存存储器的第0和第1个字节。单片机可通过单线接口读到该数据,读取时低位在前,高位在后。图7 字节分配下表为12位转化后得到的12位数据,存储在18B20的两个8比特的RAM中,二进制中的前面5位是符号位,如果测得的温度大于0, 这5位为0,只要将测到的数值乘于0.0625即可得到实际温度;如果温度小于0,这5位为1,测到的数值需要取反加1再乘于0.0625即可得到实际 温度。 例如+125的
8、数字输出为07D0H,实际温度=07D0H*0.0625=2000*0.0625=125。例如-55的数字输出为FC90H,则应先将11位数据位取反加1得370H(符号位不变,也不作运算),实际温度=370H*0.0625=880*0.0625=55。可见其中低四位为小数位。图8 DS18B20温度数据表4.3 显示电路LED数码管显示采用动态扫描方式,能简化电路布线,节约单片机I/O端口。段码和位码由单片机P0送出,分别用74HC673N锁存。图9 数码管驱动显示电路4.4 声光报警电路当温度超过设定温度值时,实现声光报警,蜂鸣器鸣叫、8个发光二极管点亮。蜂鸣器由单片机P23口控制,用三极管
9、驱动,发光二极管接单片机P1口,由74HC673N锁存。图10 声光报警电路4.5 键盘输入电路四个键分别连接单片机P34、P35、P36、P37构成独立式键盘,分别实现加、减、报警温度设定功能键和温度查询功能键。图11 键盘输入电路5 软件设计5.1 主程序模块主程序需要调用3个子程序,分别为:l 实时温度显示子程序:驱动数码管把实时温度值送出在LED数码管显示l 查询记录温度值子程序:查询过去存储的温度值,最多可查询10个值l 温度设定、报警子程序:设定报警温度值,当温度超过该值时产生报警,即驱动蜂鸣器鸣叫、8个发光二极管发光主程序流程图:开始定时器初始化、启动显示实时温度温度设定、报警查
10、询记录温度值图12 主程序流程图5.2 读温度值模块读温度值模块需要调用4个子程序,分别为:l DS18B20初始化子程序:让单片机知道DS18B20在总线上且已准备好操作l DS18B20写字节子程序:对DS18B20发出命令l DS18B20读字节子程序:读取DS18B20存储器的数据l 延时子程序:对DS18B20操作时的时序控制1. 读温度值模块流程图:入口数据转换处理读取温度值高低位跳过读序列号DS18B20初始化延时启动温度转换跳过读序列号DS18B20初始化返回图13 读温度值子程序流程图 2. DS18B20初始化子程序流程图:入口DQ为低电平?延时1560msDQ拉高电平延时
11、480msDQ复位0稍延时DQ置高电平N返回Y图14 DS18B20初始化子程序流程图3. DS18B20写字节和读字节子程序流程图: 图15 DS18B20写字节子程序流程图图16 DS18B20读字节子程序流程图5.3 中断模块中断采用T0方式1,初始值定时为50ms。中断模块需调用两个子程序:l 读温度值子程序:定时读取温度值,实时更新温度值l 记录温度值子程序:定时记录温度值,供查询使用把这两个子程序放在中断的原因是,不会因为调整报警温度或查询历史温度值而停止更新温度值和记录温度值。中断模块流程图:1秒?计数值加1定时器重置初值中断入口读温度值Y中断返回记录温度值 N图17中断模块流程
12、图5.4 温度查询模块温度查询模块需要接受按键输入,进入查询界面后,按加减键分别查询上一个和下一个历史温度值,并驱动数码管显示需要查询的温度值。温度查询模块流程图如下:入口功能键按下? N确认按下?延时消抖 YN显示温度值与位次 Y加键按下?N确认按下?延时消抖 Y查询下一个值Y减键按下? NN查询上一个值确认按下?延时消抖 YY退出功能键按下? NN返回 Y图18 温度查询模块流程图5.5 温度设定、报警模块此模块跟温度查询模块类似,需要接受按键输入,进入模块界面后,按加减键分别上调和下调设定报警温度值,当实时温度值超过设定值时驱动蜂鸣器发声,并点亮8位发光二极管,实现声光报警。温度设定、报
13、警模块流程图如下:入口延时消抖减键按下?确认按下?延时消抖加键按下?显示设定温度值确认按下?延时消抖功能键按下?N YN YN Y上调设定值Y NN Y下调设定值确认按下?Y N声光报警温度超出设定值?Y N取消报警判断退出界面?N Y返回图19 温度设定、报警模块流程图5.6 数码管驱动模块本设计数码管通过锁存器接单片机P0口,采用动态扫描驱动7段LED数码管进行显示,需调用延时子程序以稳定显示。模块流程图如下:P0清零关位选送位码开位选P0置高关段选入口开段选延时关段选送段码返回图20 数码管驱动模块流程图6 源程序#include#define uchar unsigned char#d
14、efine uint unsigned int/*变量定义*/sbit DQ=P22;/ds18b20 端口sbit beep=P23;/蜂鸣器使能端sbit dula=P26;/数码管段选使能sbit wela=P27;/数码管位选使能sbit add=P35;/加键sbit sub=P34;/减键sbit alarm=P36;/设定报警功能键sbit record=P37;/查询温度记录功能键uchar code tabled=0x3f,0x06,0x5b,0x4f,0x66, 0x6d,0x7d,0x07,0x7f,0x6f, /09的七段数码管段码0x40,0x63,0x39;/- c
15、 的段码uchar code tablew=0xfe,0xfd,0xfb,0xf7, 0xef,0xdf,0xbf,0x7f;/18个数码管的位选码uchar recordtable10;/存储过去的十个温度值uchar temperature;/温度值uchar countsec,recordnum,count;/计数变量uint countmin;/计数变量uchar alanum=30;/报警温度值,初始值为30摄氏度uchar z=65;/消抖延时函数入口参数/*函数声明*/void delay1(uchar MS);/动态扫描延时子程序void delay(uchar i);/DS1
16、8B20工作延时子程序 void Init_DS18B20();/DS18B20初始化子程序void WriteOneChar(unsigned char dat);/向DS18B20写一字节数据uchar ReadOneChar(void);/向DS18B20读一字节数据void GetTemperature();/由DS18B20产生温度值void Display(uchar wei,uchar duan);/数码管驱动子程序void Alarm();/温度报警void Showtemperature(uchar tt);/温度显示void Keeprecord();/记录温度值void
17、Showrecord();/显示记录的温度值/*主函数*/void main()TMOD=0x01;/定时器初始化,定时器0方式1TH0=(65536-50000)/256;/50msTL0=(65536-50000)%256;EA=1;/开中断ET0=1;TR0=1;/启动定时器while(1)Showtemperature(temperature);/显示实时温度Alarm();/温度设定、报警Showrecord();/查询温度记录值/*动态扫描延时函数*/void delay1(uchar MS)int i,j;for(i=80;i0;i-)for(j=MS;j0;j-);/*DS18
18、B20工作延时函数*/void delay(uchar i) while(i-);/*DS18B20初始化函数*/void Init_DS18B20(void)unsigned char x=0;DQ = 1; /DQ复位delay(8); /稍做延时DQ = 0; /单片机将DQ拉低delay(80); /精确延时 大于 480usDQ = 1; /拉高总线delay(10);x=DQ; /稍做延时后 如果x=0则初始化成功 x=1则初始化失败delay(5);while(!x)x=DQ;/*读一个字节*/uchar ReadOneChar(void)unsigned char i=0;un
19、signed char dat = 0;for (i=8;i0;i-) DQ = 0; / 给脉冲信号 dat=1; DQ = 1; / 给脉冲信号 if(DQ) dat|=0x80; delay(5); return(dat);/*写一个字节*/void WriteOneChar(unsigned char dat) unsigned char i=0; for (i=8; i0; i-) DQ = 0; DQ = dat&0x01; delay(5); DQ = 1; dat=1; delay(5);/*产生温度值*/void GetTemperature()uchar tempL,tem
20、pH;/分别为数据低位和高位uint temp;Init_DS18B20();WriteOneChar(0xCC); / 跳过读序列号的操作WriteOneChar(0x44); / 启动温度转换delay(200);Init_DS18B20();WriteOneChar(0xCC); /跳过读序号列号的操作 WriteOneChar(0xBE); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度tempL=ReadOneChar();/读出温度低位LSBtempH=ReadOneChar();/读出温度高位MSBtemp=tempH*16+tempL/16;/tempL右移四位去掉小数
21、位temperature=temp&0xff;/测量050度,只取temp低八位/*数码管驱动函数*/void Display(uchar wei,uchar duan)dula=0;P0=0xff;wela=1;P0=tablewwei;wela=0;P0=0;dula=1;P0=tabledduan;dula=0;delay1(1);/*温度显示函数*/void Showtemperature(uchar tt)Display(2,tt/10);/显示温度数值Display(3,tt%10);Display(4,11);/显示摄氏度单位Display(5,12);/*温度值设定、报警函数*
22、/void Alarm()bit flag;if(alarm=0) delay1(80);/延时消抖if(alarm=0)flag=1;/第一次按键进入设置while(flag)if(add=0)delay1(z);/延时消抖if(add=0)alanum+;/add键按下,上调设定值if(alanum=51)alanum=0;/最大值为50摄氏度,循环显示if(sub=0)delay1(z);/延时消抖if(sub=0)alanum-;/sub键按下,下调设定值if(alanum=255)alanum=50;/最小值为0摄氏度,循环显示Showtemperature(alanum);Disp
23、lay(0,10);/选中数码管的其他空闲位Display(1,10);/区别于实时温度显示“-”Display(6,10);Display(7,10);if(alarm=0) delay1(80);/延时消抖if(alarm=0)flag=0;/第二次按键退出设置if(temperaturealanum)/此处设置报警可以保证调整设定值时即可及时报警beep=0;/温度大于设定值,声光报警P1=0;elsebeep=1;/温度不大于设定值即不报警P1=0xff;if(temperaturealanum)/此处设置报警即保证即使没有进入设置界面任然可以报警beep=0;/温度大于设定值,声光报
24、警P1=0;elsebeep=1;/温度不大于设定值即不报警P1=0xff;/*温度记录函数*/void Keeprecord()uchar i=9;if(countmin=1200)/1分钟 countmin=0;count+;if(count=10)/10分钟count=0;recordnum+;/记录一次加一,最大记录10个值if(recordnum=10)recordnum=10;dorecordtablei=recordtablei-1;while(-i);recordtable0=temperature;/最新值填入第一个位置/*查询记录的温度值*/void Showrecord(
25、)bit flag;uchar a;if(record=0) delay1(80);/延时消抖if(record=0)flag=1;/record第一次按键置位进入标志while(flag)/进入查询Display(0,recordtablea/10);/显示温度数值Display(1,recordtablea%10);Display(2,11);/显示摄氏度单位Display(3,12);Display(4,10);/数码管第6、7位选中,温度值与记录数之间用-间隔Display(5,10);Display(6,(a+1)/10);/显示第几个记录值Display(7,(a+1)%10);i
26、f(add=0)delay1(z);/延时消抖if(add=0)/add按下,查看下一个值if(recordnum=0)a=0;elsea+;if(a=recordnum)/循环显示a=0;if(sub=0)/sub按下,查看上一个值delay1(z);if(sub=0)if(recordnum=0)a=0;elsea-;if(a=255)/循环显示a=recordnum-1;if(record=0)delay1(80);if(record=0)/record第二次按下,退出查看flag=0;/*定时器中断0,用于温度检测时间间隔和记录数据时间间隔*/void timer0() interru
27、pt 1 TH0=(65536-50000)/256;TL0=(65536-50000)%256;/50mscountsec+;countmin+;if(countsec=20)/1scountsec=0;GetTemperature();/一秒钟更新一次温度值Keeprecord();/定时记录温度值7 总结此次课程设计中,难点在于DS18B20的使用,即对它的时序控制、初始化以及字节读写方法,任何一个环节出错或是时序控制不到位的话就不能得到正确的数据。一旦学会了正确的使用方法,就能感觉到它带来的便利是热电偶不能比拟的,以后再次使用的话就能很快上手了。软件设计中,把程序按功能分模块的话能提高
28、编程效率,把问题一一解决,同时画流程图能帮助理清思路,使问题简单化。定义变量时,尽量定义局部变量,在字符型变量能达到要求的情况下就不用定义成整形变量了,以节省内存空间。同时局部变量应避免与全局变量取同名,否则全局变量将被屏蔽或与局部变量相冲突而达不到设计的效果。另一方面,取变量名时也要讲究技巧,应尽量使其见名知意,同样地,写程序时加注释确是非常必要的,否则隔一段时间后,想再改进或做扩展的话就比较困难了,因为即使是自己写的程序也变得难读难懂了。在做键盘消抖时,延时的时间比较重要,一般为10ms左右,延时太短就会使按键太过灵敏,按一下就使数字跳变几次;而延时过长则可能使按键按下了却无响应,在外部定
29、义初始化一个延时函数的入口参量则能很方便地调整延时时间,以达到比较好的效果。另外,如果对按键进行释放判断的话就能解决长时间按键导致按键重复响应的问题。此设计中没有为温度的单位(摄氏度)准备专用的数码管来显示,若单独用一个数码管显示“C”来代替“”的话,看起来感觉很别扭。偶然想起如若用一个数码管的上半部显“0”,即a、b、f、g段点亮,来代替“”左上角的“度”的话,效果应该不错,便作了一试,发现这是确是一个很好的主意,便在此次设计中采用了这个办法来显示温度单位。另外此次设计也考虑了实时温度显示界面与报警温度设置界面的区别,即在进入报警温度设置界面时,让其余的数码管都显示出一横杠,即g段点亮,这样则不会让两个界面相互混淆。总的来说,自己从这次独立的课程设计中收获了一些知识与经验,一些从书本中学之不来的东西,不是说理论无用,而这恰恰是在理论的土壤中开出的花朵,是在理论的肩膀望见的更宽广的道路!成功来之不易,自主动手动脑实践,小小的成果亦能带来硕大的喜悦!参考文献:1. 徐玮. C51单片机高效入门(第2版). 北京:机械工业出版社,2010.2. 龙脉工作室,刘鲲,孙春亮(修订版). 北京:人们邮电出版社,2010.专心-专注-专业