找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4229|回复: 4
收起左侧

我的单片机DS18B20智能温度表设计

[复制链接]
ID:409329 发表于 2018-10-14 10:09 | 显示全部楼层 |阅读模式

本论文的主要内容是详细叙述使用AT89C51型号单片机来进行智能数字温度计设计的思路与相关知识的理解。详细描述了利用数字温度传感器DS18B20开发测温系统的过程,重点对传感器在单片机下的硬件连接,软件编程以及各模块系统流程进行了详尽分析,对各部分的电路也一一进行了介绍,该系统可以方便的实现温度的采集和报警,并可以根据需要任意上下限报警温度,它使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合于我们日常生活和工、农业生产中的温度测量,也可以当做温度处理模块潜入其他系统中,作为其他主系统的辅助扩展。


在现在这样的信息化时代,信息技术随处可见,可以说是离不开我们的生活了,以后我们的生活就是在茶余饭后最多的话题就是我家的机器人性能怎么样,我家的智能遥控电视怎么样,我家的智能空调怎么了之类的话,本课题设计的智能数字温度计也将是以后我们生活中离不开的必需品。

在现在这样的信息化时代,智能化才是我们追求的更高点,智能机器人,智能电视,智能、智能…什么都是智能的,当然也包括本课题设计的智能温度计,传统的温度计都有很多的缺陷,比如说水银温度计,他利用的就是最原始的热胀冷缩原理,这种温度计的最大的缺点就是误差太大,而且读数也不方便等等各方面的缺点,与传统的这些相比,本课题中的智能数字温度计就先进了很多,本设计使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合于我们日常生活和工、农业生产中的温度测量,也可以当做温度处理模块潜入其他系统中,作为其他主系统的辅助扩展。DS18B20与STC89C51结合实现最简温度报警系统,该系统结构简单,抗干扰能力强,适合于恶劣环境下进行现场温度测量,有广泛的应用前景。

1.1设计目的

《传感器与测试技术》设计是机械设计制造及其自动化专业和机械电子工程专业的一个重要实践性教学环节。该设计是在学完《传感器与检测技术》之后进行,通过综合应用所学传感器知识,将内容和前修有机结合形成系统,完成传感器应用系统设计。

通过设计使我们能熟练查阅文献资料,巩固和加深对常用传感器的结构、原理、特性的认识和基本知识的理解,提高综合运用所学知识的能力。通过实际电路方案的分析比较论证,设计计算,元件选择,掌握传感器电路的分析方法和工程设计方法,达到提高学生分析问题和电路设计能力的教学目标,培养我们综合应用知识的能力,从而掌握智能检测(或仪表)系统设计的基本思想和方法,为后续的学习和工作奠定了基础。


1.2设计的任务和要求

针对某特定场合(如存储仓)在常压下对温度的要求,选用合适的测试方法设计温度智能仪表,要求具有存储、显示和报警功能,且温度检测精度为0.2℃。

要求:

1.理解在常压下对温度测量的基本原理和方法,分析建立设计需要的参数范围。

2.根据温度检测要求,设计满足给定任务要求的智能温度表总体方案。

3.选择合适的传感器、信号处理电路、执行器,进行详细设计。对测试模块、显示模块、报警模块等进行设计和系统集成。

4.说明所设计的温度一体化智能仪表工作原理和工作过程。

5.对设计结果进行必要的分析。

1.3设计的意义

我们已经进入了信息化的时代,智能化才是我们追求的更高点。传统的温度计都有很多的缺陷,比如说水银温度计,他利用的就是最原始的热胀冷缩原理,这种温度计的最大的缺点就是误差太大,而且读数也不方便等等各方面的缺点,与传统的这些相比,本设计较好地克服了这些缺点,本设计中的智能数字温度计选用AT89C51型号的单片机作为主要的控制程序,具有存储、显示和报警功能,且具有较高的温度检测精度。

1.4国内外现状及水平

国外对温度控制技术研究较早,始于20世纪70年代。先是采用模拟式的组合仪表,采集现场信息并进行指示、记录和控制。80年代末出现了分布式控制系统。目前正开发和研制计算机数据采集控制系统的多因子综合控制系统。现在世界各国的温度测控技术发展很快,一些国家在实现自动化的基础上正向着完全自动化、无人化的方向发展。

我国对于温度测控技术的研究较晚,始于20世纪80年代。我国工程技术人员在吸收发达国家温度测控技术的基础上,才掌握了温度室内微机控制技术,该技术仅限于对温度的单项环境因子的控制。我国温度测控设施计算机应用,在总体上正从消化吸收、简单应用阶段向实用化、综合性应用阶段过渡和发展。在技术上,以单片机控制的单参数单回路系统居多,尚无真正意义上的多参数综合控制系统,与发达国家相比,存在较大差距。我国温度测量控制现状还远远没有达到工厂化的程度,生产实际中仍然有许多问题困扰着我们,存在着装备配套能力差,产业化程度低,环境控制水平落后,软硬件资源不能共享和可靠性差等缺点。



  • 整体设计方案
2.1方案设计与论证
2.1.1方案一

由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化的电压或电流采集过来,进行A/D转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到A/D转换电路,感温电路比较麻烦;

图2-1-1利用热敏电阻测温度的框图
2.1.2方案二

采用AT89S52作为系统处理器对采集的温度信号进行处理,温度的范围是0~100度。温度传感器TC1047首先将温度信号转化成电压信号,再经过信号处理,最后送到TLC5510进行A/D转换,最后将结果通过数码管显示出来[1];

图2-1-2 利用温度传感器TC1047采集温度的框图
2.1.3方案三

采用数字温度传感器DS18B20采集温度,温度测量范围为-55~125℃,通过AT89S52处理信号,不需要进行A/D转换,其自身可将模拟信号转化成数字信号,然后再通过数码管输出结果。

图2-1-3采用数字温度传感器DS18B20采集温度

方案一虽经济但由于要用到A/D转换,所以电路比较复杂,不利于硬件连线,所以不采用此方案;方案二测量温度精度高、能耗低,电路比方案一简单,但成本价太高,所以不采用此方案;方案三中温度测量精度更高,无需进行A/D转换,且DS18B20芯片的管脚简单,无需外围硬件设备即可进行温度测量,与单片机交换信息仅需一根I/O口线,占用微处理器的端口较少,可以节省大量的引线和逻辑电路,完全符合本设计的要求,因此采用此方案。

2.2工作原理

本设计选用AT89C51作为整个控制系统的核心部分,通过DS18B20采集温度,通过三个按键:模式切换键、加键和减键。模式切换键可以切换正常显示,上限温度设定状态,下限温度设定状态,当实测温度高于设定的上限值,蜂鸣器报警和LED红灯闪烁报警,当实测温度高于设定的下限值,蜂鸣器报警和LED黄灯闪烁报警,系统可以方便的实现温度的采集和报警,并可以根据需要任意上下限报警温度,它使用起来相当方便,具有精度高、量程宽、灵敏度高、体积小、功耗低等优点,适合于我们日常生活和工、农业生产中的温度测量,也可以当做温度处理模块潜入其他系统中,作为其他主系统的辅助扩展。


  • 硬件电路设计
3.1单片机的选型简介

CPU是整个控制部分的核心。在考虑经济性和满足需求的前提下,本设计选用AT89C51作为整个控制系统的核心部分,它的内部含有可以进行系统的编程的存储器。Flash存储器功能比较强大,在对它进行编程时不仅可以在线操作,也可以使用一般的方法进行操作。编好的程序主要存储在芯片中,它的功能比较强大。所以,选用AT89C51作为本设计的控制中心。器件管脚图如图3-1:


图3-1  AT89C51管脚图

AT89C51简介:单片机的可擦除只读存储器可以反复擦除1000次。该器件采用ATMEL高密度非易失存储器制造技术制造,与工业标准的MCS-51指令集和输出管脚相兼容。由于将多功能8位CPU和闪速存储器组合在单个芯片中,ATMEL的AT89C51是一种高效微控制器,AT89C051是它的一种精简版本。AT89C51单片机为很多嵌入式控制系统提供了一种灵活性高且价廉的方案。外形及引脚排列如图所示。

3.2最小系统模块
在这次设计中,根据课题的需要采用的是ATMEL公司51系列单片机AT89C51芯片作为控制芯片。在实际运用中如果只用单片机芯片是没有办法达到所设计的目的,还要有相配套的电路,这样才能组成一个完整的控制系统达到设计的要求。在本次设计中主要采用AT89C51芯片和相配套的电路来组成所需要的模块进行研究,模块中一些具体的参数主要是选用P3口作1602的命令数据控制、时钟、读写控制、和使能控制接口,P2口作按键扫描接口,P2.3作DS18B20的总线接口。P2.5,P2.7作报警控制接口。其电路连接图3-2如下:

图3-2 数据处理及控制模块
3.3温度传感器设计
3.3.1温度传感器简介

DS18B20可以设定9~12位的分辨率,其精确度比较高。为了满足实际的工作需要也可以采用比较小的封闭方式和相对较宽的电压。设定的分辨率及报警温度存储在EPROM中,掉电后不会丢失。

温度传感器DS18B20引脚如图3-3所示

图3-3  DS18B20TO-92封装温度传感器

引脚功能说明:

VDD :可选电源脚,电源电压范围3~5.5V。

DQ :数据输入/输出脚。漏极开路,常态下高电平。

GND :为接地电源脚。

DS18B20的组成部分主要包括:光刻64位ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器这四部分,它们在其内部按照一定得结构进行排列。 

光刻64位ROM它的序列号排列是有一定规律的,一般情况下排在首位的是8位不同类型的产品标签,之后是DS18B20的序列48位序列号,排在最后的是前面所有序列号的校验码,我们通过总结可以知道64光刻ROM的作用是保证每个DS18B20都不一样,这样就可以满足总线连接多个DS18B20的要求。

DS18B20温度传感器主要包括的高速内存非常容易丢失,内存RAM主要有八个字节组成,这八个字节所包含的内容有很大的区别。其中第一个字节是是低八位,第二个字节是高八位,第三个和第四个字节是最高和最低位的的非易失性复制,第五个字节是结构寄存器的非易失性复制,第三,第四,第五个字节在每次上电复位时刷新内容。六,七,八个字节用于内部计算。第九个字节是冗余测试。E2RAM的主要作用是为了储存高温与低温触发TH、TL。 

通过DS18B20的通信协议,我们知道主机在对其进行控制时温度实现转换主要由三个步骤构成。分别是每次读写DS18B20时都要进行重新设置,完成设置之后需要发送一个指令,只有把相应的指令发送之后才能对其进行相关的操作。CPU在收到重新设置的要求之后需要先下拉后释放,经历一定的时间之后就可以完成对信号的复位。

3.3.2 温度传感器与单片机的连接 温度传感器在和单机片进行连接时所使用的接口型号是P2.0,这种接口在单机片中属于高位地址线。P2端口是一个带内部上拉电阻的8位双向I/O,另外它在输出缓冲时可以带动4个逻辑门电路。P2端口的工作不受外界干扰,即使在对程序进行编写和检查时,它也能够正常工作。图3-4所示就是DSl8820组成情况。

图3-4  DS18B20和单片机的接口连接
3.4LCD显示模块

在这种模块内部存放的字符是有不同的字符组成的,这些字符主要包括:英文字母、常用的数学符号和阿拉伯数字,不同的字符所具有的代码也不一样。就拿英文字母来说大写的A所代表的是41h,如果使用显示器进行发送时,模块上显示的是41h,但是在液晶显示器上看到的却是字母A。 

1602液晶模块的控制器主要有11条指令,数量众多的控制指令可以更好地完成对程序的控制,满足其工作需要。 

采用的LCD1602液晶模块是标准16针插座,接口电路如图3.6所示

图3.6  显示电路的连接图
3.5系统硬件的总体框图
系统硬件的总体框图如图3.7所示

图3.7  系统硬件的总体框图
第四章 软件设计
4.1 软件介绍
4.1.1
编程软件

Keil软件:单片机开发中离不开软件,我们写的汇编语言源程序要变为CPU可以执行的机器码有两种方法,一种是手工汇编,另一种是机器汇编,目前已极少使用手工汇编的方法了。机器汇编是通过汇编软件将源程序变为机器码,用于MCS-51单片机的汇编软件有早期的A51,随着单片机开发技术的不断发展,从普遍使用汇编语言到逐渐使用高级语言开发,单片机的开发软件也在不断发展,Keil软件是目前最流行开发MCS-51系列单片机的软件,这从近年来各仿真机厂商纷纷宣布全面支持Keil即可看出。Keil提供了包括C编译器、宏汇编、连接器、库管理和一个功能强大的仿真调试器等在内的完整开发方案,通过一个集成开发环境(uVision)将这些部份组合在一起。

4.1.2 绘图软件Proteus软件是英国Lab Center Electronics公司出版的EDA工具软件(该软件中国总代理为广州风标电子技术有限公司)。它不仅具有其它EDA工具软件的仿真功能,还能仿真单片机及外围器件。它是目前比较好的仿真单片机及外围器件的工具。虽然目前国内推广刚起步,但已受到单片机爱好者、从事单片机教学的教师、致力于单片机开发应用的科技工作者的青睐。Proteus可提供的仿真元器件资源:仿真数字和模拟、交流和直流等数千种元器件,有30多个元件库。.Proteus可提供的仿真仪表资源 :示波器、逻辑分析仪、虚拟终端、SPI调试器、I2C调试器、信号发生器、模式发生器、交直流电压表、交直流电流表。理论上同一种仪器可以在一个电路中随意的调用。除了现实存在的仪器外,Proteus还提供了一个图形显示功能,可以将线路上变化的信号,以图形的方式实时地显示出来,其作用与示波器相似,但功能更多。这些虚拟仪器仪表具有理想的参数指标,例如极高的输入阻抗、极低的输出阻抗。这些都尽可能减少了仪器对测量结果的影响。Proteus可提供的调试手段 Proteus提供了比较丰富的测试信号用于电路的测试。这些测试信号包括模拟信号和数字信号。
4.2程序设计DS18B20读取温度的流程图如下图4-1
图4-1DS18B20读取温度的流程图

温度数据处理流程图如下4-5:

图4-2  温度数据处理流程图

第五章 调试5.1开机温度测试
运行程序,数码管显示设定温度值。
图5.1开机温度测试

5.2设置温度测试
三个按键:模式切换键、加键和减键。模式切换键可以切换正常显示,上限温度设定状态,下限温度设定状态。通过加键和减键设定温度,通过切换键可以切换成正常状态。

图5.2设置温度测试

5.3 报警测试当实测温度高于设定的上限值,蜂鸣器报警和LED灯闪烁报警如图5.3所示。当实测温度高于设定的限值,蜂鸣器报警和LED灯闪烁报警,如图5.4所示

图5.3上限报警调试


图5.4设置温度测试

结 论

本文的主要内容是对单机片的组成要素进行了详细的介绍,重点知识主要包括AT89C51型号单片机与DS18B20型号数字温度传感器的主要结构和作用,数字温度计主要由DS18B20与AT89C51单片机、LCD1602构成,有超温报警功能。

通过本次设计使我们小组在专业知识方面有了很大的提高,同时也使我们认识到自身的不足之处。单机片设计的主要内容是硬件设施的挑选、电路的设计和程序的完成,硬件的选择有点麻烦,但是硬件是其他部分的关键,硬件选好了后面的部分就轻松的多,还有电路的设计,怎么样设计才能达到最佳的效果,还有程序的完成,这是一连串的过程,需要不断地思考,测试完善,这次设计也是我们对所学知识的一次综合应用,在发现问题,解决问题的这一过程中使我们受益匪浅。只有善于思考,不断地改进,以一个科学严谨认真的态度去对待,才能有所成果,C51单片机是现在最基础最简单的单片机,本设计结构简单,应用性较强,能够较好地实现相应的功能。以后我们会更加深入地学习与单片机、电子电路、C语言的相关知识,对相关的理论进行思考和摸索,更好地掌握这些知识。


  1. #include<reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char

  4. uchar smg_dm[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x63,0x39,0x00}; //共阴数码管0-9 O C 全灭              段码表
  5. uchar smg_dm1[]={0xbf,0x86,0xDB,0xCF,0xE6,0xED,0xFD,0x87,0xFF,0xEF,}; //0. 1. 2.----9.段码表
  6. uchar smg_wm[]={0Xef,0Xdf,0xbf,0x7f};      //位选

  7. uchar Display_buffer[4]={0,0,0,0};                //数码管显示缓存

  8. sbit LED=P3^7;  //高温度报警指示灯
  9. sbit LED1=P3^5;  //低温度报警指示灯
  10. sbit BEEP=P3^6;  //蜂鸣器

  11. sbit key1=P2^0;
  12. sbit key2=P2^1;
  13. sbit key3=P2^2;
  14. sbit DQ=P2^3;  //DS18B20 总线 精度1

  15. uint temp1; //上限温度
  16. uint temp2; //下限温度
  17. uchar keynum;
  18. uchar flagkey=0;
  19. uchar flag=0;
  20. uint num;
  21. uint temp;              //数码管温度显示变量
  22. void keyscan();              //按键扫描程序
  23. void smg_display_ds18b20();//数码管温度显示函数
  24. void display();                                //温度显示
  25. void display1();                            //按键设置温度显示
  26. void delay_ms(uint z);  //ms延时子程序
  27. void delay_us(uint t);              //延时子程序
  28. void init_ds18b20(void); //              ds18b20初始化
  29. void write_byte(uchar dat);                //写字节
  30. uchar read_byte(void);                    //读字节
  31. uint readtemperature(void);  //读数据

  32. void keyscan()
  33. {
  34.               if(key1==0)
  35.               {
  36.               delay_ms(10);
  37.               if(key1==0)
  38.               {
  39.                             keynum++;
  40.                             keynum=keynum%3;
  41.                             switch(keynum)
  42.                             {
  43.                                           case 0:flagkey=0;break;
  44.                                           case 1:flagkey=1;break;            
  45.                                           case 2:flagkey=2;break;
  46.                             }
  47.               }
  48.               while(!key1);
  49.               }
  50.               if(flagkey==1)                 //设置上限
  51.               {
  52.                             if(key2==0)
  53.                             {
  54.                                           delay_ms(10);
  55.                                           if(key2==0)
  56.                                           {
  57.                                           //flag1=1;
  58.                                           #if 1
  59.                                           temp1=temp1+10;
  60.                                                         if(temp1==100)
  61.                                                         {
  62.                                                                       temp1=0;
  63.                                                         }

  64.                                          
  65.                                           #endif
  66.                                           }
  67.                                           while(!key2);            
  68.                             }
  69.                             if(key3==0)
  70.                                           {
  71.                                                         delay_ms(10);
  72.                                                         if(key3==0)
  73.                                                         {
  74.                                                         // flag1=2;
  75.                                                         #if 1
  76.                                                         temp1=temp1-10;
  77.                                                                       if(temp1==0)
  78.                                                                       {
  79.                                                                                     temp1=100;
  80.                                                                       }

  81.                                                         #endif
  82.                                                         }
  83.                                                         while(!key3);            
  84.                                           }
  85.               //              display1();
  86.               }
  87.                             if(flagkey==2)              //设置下限
  88.                             {
  89.                                           if(key2==0)
  90.                             {
  91.                                           delay_ms(10);
  92.                                           if(key2==0)
  93.                                           {
  94.                                           //flag1=1;
  95.                                           #if 1

  96.                                           temp2=temp2+10;
  97.                                                         if(temp2==100)
  98.                                                         {
  99.                                                                       temp2=0;
  100.                                                         }
  101.                                          
  102.                                           #endif
  103.                                           }
  104.                                           while(!key2);            
  105.                             }
  106.                             if(key3==0)
  107.                                           {
  108.                                                         delay_ms(10);
  109.                                                         if(key3==0)
  110.                                                         {
  111.                                                         // flag1=2;
  112.                                                         #if 1
  113.                                                         temp2=temp2-10;
  114.                                                                       if(temp2==0)
  115.                                                                       {
  116.                                                                                     temp2=100;
  117.                                                                       }
  118.                                                         #endif
  119.                                                         }
  120.                                                         while(!key3);            
  121.                                           }
  122.                             }
  123.                             display1();

  124. }


  125. void main()//主程序
  126. {
  127.     TMOD=0X01;
  128.               TH0=(65536-50000)/256;
  129.               TL0=(65536-50000)%256;
  130.     EA=1;
  131.     ET0=1;
  132.               TR0=1;
  133.               temp1=345;              //上限温度
  134.               temp2=305;              //下限温度
  135.               while(1)
  136.                             {            
  137.                               keyscan();
  138.                             // if(flagkey==1)
  139.                             // {
  140.                                             if(temp>=temp1&&flagkey==0)  //250是实际的数值   //flagkey==0 设置状态蜂鸣器和LED都不起作用
  141.                                              {
  142.                                                           // LED=0;
  143.                                                            if(flag==1)
  144.                                                            {
  145.                                                                                        BEEP=0;//  开始报警
  146.                                                                                     LED=0;
  147.                                                                                     LED1=1;
  148.                                                                                     flag=0;              // 退出if语句
  149.                                                            }
  150.                                                            else
  151.                                                            {
  152.                                                                                        BEEP=1;              //关闭报警 实现以0.5S的时间间隔来报警 时间和自己设定
  153.                                                                                     LED=1;
  154.                                                                                     LED1=1;
  155.                                                            }               
  156.                                              }
  157.                                              else if(temp<=temp2&&flagkey==0)
  158.                                              {
  159.                                                            //  LED=0;
  160.                                                            if(flag==1)
  161.                                                            {
  162.                                                                                        BEEP=0;//  开始报警
  163.                                                                                     LED1=0;
  164.                                                                                     LED=1;
  165.                                                                                     flag=0;              // 退出if语句
  166.                                                            }
  167.                                                            else
  168.                                                            {
  169.                                                                                        BEEP=1;              //关闭报警 实现以0.5S的时间间隔来报警 时间和自己设定
  170.                                                                                     LED1=1;
  171.                                                                                     LED=1;
  172.                                                            }
  173.                                              }
  174.                                              else
  175.                                              {
  176.                                                            LED=1;
  177.                                                            LED1=1;
  178.                                                            BEEP=1;
  179.                                              }
  180.                             //  }
  181.                            

  182.                                if(flagkey==0) //上电 显示DS18B20测出的温度 有按键按下退出这个显示
  183.                                {
  184.                                             display();                            //温度显示
  185.                                }
  186.                             }
  187. }

  188. void time0() interrupt 1
  189. {
  190.       TH0=(65536-50000)/256;
  191.                 TL0=(65536-50000)%256;
  192.                 num++;            
  193.       if(num==10) //0.5S到
  194.                 {
  195.                   num=0;
  196.                             flag=1;              //进去蜂鸣器报警
  197.                 }
  198. }

  199. void display1()                //设置数码管显示
  200. {
  201.               #if 1
  202.               uchar i;
  203.               //Display_buffer[0]=12;  //也可以硬件不接
  204.               if(flagkey==1)
  205.               {
  206.               Display_buffer[0]=temp1/1000;
  207.               Display_buffer[1]=temp1%1000/100;
  208.               Display_buffer[2]=temp1%1000%100/10;
  209.               Display_buffer[3]=temp1%10;              //251 结果余1
  210.               }
  211.               if(flagkey==2)
  212.               {
  213.               Display_buffer[0]=temp2/1000;
  214.               Display_buffer[1]=temp2%1000/100;
  215.               Display_buffer[2]=temp2%1000%100/10;
  216.               Display_buffer[3]=temp2%10;              //251 结果余1
  217.               }
  218.               for(i=0;i<=3;i++)
  219.                             {            
  220.                               if(i==2)
  221.                               {
  222.                                                           P2=smg_wm[i];//选位码
  223.                                                         P1=smg_dm1[Display_buffer[i]];//选段码
  224.                                                         delay_ms(5);
  225.                                                         P1=0X00;//消影
  226.                               }
  227.                               else
  228.                               {            
  229.                                                         P2=smg_wm[i];//选位码
  230.                                                         P1=smg_dm[Display_buffer[i]];//选段码
  231.                                                         delay_ms(5);
  232.                                           P1=0X00;//消影
  233.                             }
  234.                   }
  235.               #endif
  236. }



  237. void display()  //
  238. {
  239.               temp=readtemperature();              //读出温度值
  240.               smg_display_ds18b20();               //数码管上显示            
  241. }
  242.                                          
  243. void smg_display_ds18b20()              //DS18B20的采样回来的数值 数码管显示的延时是1ms,延时时间长一点的显示会不正常
  244. {
  245.   #if 1
  246.               uchar i;
  247.               //Display_buffer[0]=12;  //也可以硬件不接
  248.               Display_buffer[0]=temp/1000;
  249.               Display_buffer[1]=temp%1000/100;
  250.               Display_buffer[2]=temp%1000%100/10;
  251.               Display_buffer[3]=temp%10;              //251 结果余1
  252.               for(i=0;i<=3;i++)
  253.                             {            
  254.                               if(i==2)
  255.                               {
  256.                                                           P2=smg_wm[i];//选位码
  257.                                                         P1=smg_dm1[Display_buffer[i]];//选段码
  258.                                                         delay_ms(5);
  259.                                                         P1=0X00;//消影
  260.                               }
  261.                               else
  262.                               {            
  263.                                                         P2=smg_wm[i];//选位码
  264.                                                         P1=smg_dm[Display_buffer[i]];//选段码
  265.                                                         delay_ms(5);
  266.                                               P1=0X00;//消影
  267.                             }
  268.                   }
  269.               #endif
  270. }

  271. ///////////////////////延时////////////////////////////////////
  272. void delay_ms(uint z)  //延时子程序
  273. {
  274.    uint x,y;
  275.    for(x=z;x>0;x--)
  276.                  for(y=110;y>0;y--);
  277. }

  278. void delay_us(uint t)
  279. {
  280.               while(t--);
  281. }



  282. /////////////////////DS18B20部分 根据18B20规格书的时序来进行读写操作//////////////////////////
  283. void init_ds18b20(void)   //根据18B20时序写
  284. {
  285.   uchar n;
  286.   DQ=1;
  287.   delay_us(8);
  288.   DQ=0;
  289.   delay_us(80);
  290.   DQ=1;
  291.   delay_us(8);
  292.   n=DQ;
  293.   delay_us(14);
  294. }
  295. ///////////////////////////////
  296. void write_byte(uchar dat)               //写字节
  297. {
  298.               uchar i;
  299.               for(i=0;i<8;i++)
  300.               {
  301.                             DQ=0;  
  302.                             DQ=dat&0x01;
  303.                             delay_us(8);  
  304.                             DQ=1;
  305.                             dat>>=1;
  306.               }
  307.               delay_us(8);
  308. }
  309. //////////////////////////////////
  310. uchar read_byte(void)               //读字节
  311. {
  312.               uchar i,value;
  313.               for(i=0;i<8;i++)
  314.               {
  315.                             DQ=0;
  316.                             value>>=1;
  317.                             DQ=1;
  318.                             if(DQ)  
  319.                             value|=0x80;  
  320.                             delay_us(4);
  321.               }
  322.               return value;
  323. }
  324. ////////////////////////////
  325. uint readtemperature(void)   //读温度                            //uchar 只有255
  326. {
  327.     uchar a,b;
  328.               uint val;
  329.               float f_val;
  330.               init_ds18b20();
  331.               write_byte(0xcc); //跳过ROM
  332.               write_byte(0x44); // 启动温度测量
  333.               delay_us(300); //适当延时
  334.               init_ds18b20();  //
  335.               write_byte(0xcc);
  336.               write_byte(0xbe);  //读取温度寄存器
  337.               a=read_byte();                             //连续读两个字节数据。读低8位
  338.               b=read_byte();                             //读高8位
  339. ///////////////////////////////////////////////////

  340. ///////////////////////////////////////////////////
  341.               #if 1 //精度为0.1
  342.     …………
  343. …………
  344. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

附录二 原理图


以上的Word格式文档51黑下载地址:

基于单片机的智能温度表设计.docx (530.87 KB, 下载次数: 71)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:548367 发表于 2019-12-31 12:05 | 显示全部楼层
真是太感谢这样的分享了  ,希望能下载一下
回复

使用道具 举报

ID:682512 发表于 2020-1-7 02:25 来自手机 | 显示全部楼层
你好,程序有汇编语言版本的嘛
回复

使用道具 举报

ID:867100 发表于 2020-12-25 10:37 来自手机 | 显示全部楼层
怎么实现不了
回复

使用道具 举报

ID:868660 发表于 2020-12-27 10:56 来自手机 | 显示全部楼层
可以呀,这个太牛了,要是楼主能传个仿真给我们学习一下就更好了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表