基于单片机的无线温度计设计报告
基于单片机的无线测温系统的设计

引言:无线测温系统是一种基于单片机技术的智能温度监测系统。
它通过无线传输技术,能够远程监测和采集温度数据,具有高精度、实时性和便捷性等优点。
本文将详细介绍基于单片机的无线测温系统的设计。
概述:无线测温系统是近年来发展迅速的一种温度监测技术,它可以广泛应用于各种需要进行温度监测的场合,如工业生产、农业种植、建筑监测等。
基于单片机的无线测温系统充分利用了单片机的高集成度、低功耗和强大的数据处理能力,能够实现对温度的高精度监测和数据传输。
本文将从硬件设计、软件设计、通信模块选择、温度传感器选择和功耗优化五个方面详细介绍基于单片机的无线测温系统的设计。
正文内容:1.硬件设计1.1单片机选择1.2电源设计1.3温度传感器接口设计1.4数据存储设计1.5外部设备接口设计2.软件设计2.1系统架构设计2.2温度数据采集算法设计2.3数据处理算法设计2.4数据传输协议设计2.5用户界面设计3.通信模块选择3.1无线通信技术概述3.2通信距离和速率需求分析3.3无线通信模块选择准则3.4常用无线通信模块介绍3.5通信模块选择与集成4.温度传感器选择4.1温度传感器分类4.2温度传感器选型准则4.3常用温度传感器介绍4.4温度传感器接口设计4.5温度传感器校准方法5.功耗优化5.1功耗分析与需求5.2系统功耗优化策略5.3硬件设计功耗优化5.4软件设计功耗优化5.5基于睡眠模式的功耗优化总结:基于单片机的无线测温系统的设计主要涉及硬件设计、软件设计、通信模块选择、温度传感器选择和功耗优化等方面。
通过合理的硬件设计和通信模块选择,能够实现高精度的温度监测和远程数据传输。
同时,通过优化软件设计和功耗管理,能够降低系统的功耗,延长系统的使用寿命。
基于单片机的无线测温系统的设计在智能化温度监测领域具有广阔的应用前景。
毕业设计 单片机温度计

毕业设计单片机温度计毕业设计单片机温度计一、引言随着科技的发展,单片机在各个领域的应用越来越广泛。
其中,温度计作为一种常见的测量仪器,也逐渐得到了广泛的应用。
本文将介绍一种基于单片机的温度计的设计方案。
二、设计原理本设计方案采用DS18B20数字温度传感器作为温度检测元件,通过单片机进行数据采集和处理,并通过数码管显示当前的温度数值。
设计的主要原理如下:1. 温度传感器DS18B20是一种数字温度传感器,具有精确度高、体积小、接线简单等特点。
它采用单总线接口进行通信,可以直接与单片机相连。
2. 单片机本设计采用常用的51单片机作为控制核心,通过单总线协议与温度传感器进行通信。
单片机负责采集传感器的数据,并对温度数值进行处理。
3. 数码管显示为了方便用户观察温度数值,本设计采用了数码管进行显示。
通过单片机的IO 口控制数码管进行数值的显示。
三、硬件设计本设计的硬件部分主要包括传感器接口电路、单片机电路和数码管显示电路。
1. 传感器接口电路传感器接口电路主要负责将传感器的信号与单片机连接。
通过对传感器引脚的接法,实现数据的传输和通信。
2. 单片机电路单片机电路主要包括单片机的供电电路和与传感器的通信电路。
通过连接电源和接口电路,实现单片机对传感器的控制和数据采集。
3. 数码管显示电路数码管显示电路主要包括数码管的供电电路和控制电路。
通过连接电源和单片机的IO口,实现数码管的数值显示。
四、软件设计本设计的软件部分主要包括单片机的程序设计和数据处理。
1. 程序设计通过编写单片机的程序,实现与传感器的通信和数据采集。
程序中需要包括对传感器的初始化、数据读取和数据处理等功能。
2. 数据处理通过单片机对传感器采集到的温度数据进行处理,可以实现对温度数值的转换和计算。
同时,可以根据需要对数据进行滤波和校准,提高测量的准确度。
五、实验结果经过硬件和软件的设计,本设计方案成功实现了温度的测量和显示。
实验结果表明,该温度计具有较高的精确度和稳定性。
(完整版)基于单片机的无线温度远程采集监测报警器的毕业设计论文

武汉长江工商学院毕业论文(设计)学院:工学院专业:通信工程年级:2010级题目:基于单片机的无线温度采集监测报警器的设计学生:谢慧学号:指导教师:伍彩红职称:2014年5月8日武汉长江工商学院本科毕业论文(设计)原创性声明本人郑重声明:所呈交的论文是本人在导师的指导下独立进行研究所取得的研究成果。
除了文中特别加以标注引用的内容外,本论文不包含任何其他个人或集体已经发表或撰写的成果作品。
本人完全意识到本声明的法律后果由本人承担。
作者签名:年月日目录摘要 (1)关键词 (1)Abstract (1)Key wards (1)前言 (2)1 系统总体设计方案 (2)2 主要元器件介绍 (3)2.1 AT89S52单片机简介 (3)2.2 nRF24L01概述 (5)2.3 DS18B20温度传感器 (5)3 硬件系统设计 (5)3.1 硬件系统总体结构 (5)3.2 无线收发模块 (6)3.3 显示模块 (6)3.4 声光报警电路 (6)3.5 按键控制电路 (7)3.6 温度采集模块 (7)3.7 电源模块 (8)4 系统软件设计 (8)4.1 软件设计思路 (8)4.2 主程序流程图设计 (8)4.2.1 发送部分 (8)4.2.2 接收部分 (9)4.3 子程序设计 (10)4.3.1 温度监测模块软件 (10)4.3.2 无线发射模块软件设计 (10)4.3.3 无线接收模块软件设计 (11)4.3.4 显示模块软件设计 (11)5 硬件功能实现 (12)5.1 系统调试 (12)5.2 调试结果 (12)6 总结 (13)参考文献 (13)附录一 (14)附录二 (16)基于单片机的无线温度采集监测报警器的设计摘要:本文介绍了由单片机、温度传感器、报警器和NRF24L01组成的专用无线温测监测报警系统。
本系统以 STC89C52单片机为控制核心,利用温度传感器DS18B20完成温度的采集和数据的处理,nRF24L01实现环境温度的无线传输。
基于单片机上实现的数字温度计设计报告

摘要本系统以AT89S52为核心,选用符合测量温度范围要求的DS18B20单总线数字温度传感器,DS1302串行时钟芯片,RT1602液晶显示器实现液晶显示当前日期、时间、星期和温度。
当测量温度超过设定的温度上下限时,启动蜂鸣器和指示灯报警。
温度显示稳定,且温度测量误差≤±1℃,温度值小数部分保留两位有效数字。
增加了摄氏温度与华氏温度转换对比显示功能,设定了整点语音自动播报时间温度,手动实时播报时间温度功能。
AbstractBased on the microintrollers,AT89S52, the system is composed of single bus temperature sensor DS18B20, serial clock chip DS1302 and liquid crystal display rt1602,which can display current date, time, week and temperature. Beep and indicating led are run when the measuring temperature is out of the range of the setting temperature. The system can display temperature stably, and the measuring error is less than and equal to ±1℃. It remains the two Significant digit after the decimal point. The system extends the functions of conversion of Celsius Temperature And Fahrenheit temperature,Announcing on schedule temperature、real time with voice automatically and the Manual Announcing temperature、real time.一、方案选择与论证根据竞赛设计任务的总体要求,本系统可以划分为以下个基本模块,针对各个模块1的功能要求,分别有以下一些不同的设计方案:1、温度传感器模块方案一:采用热敏电阻,热敏电阻精度、重复性、可靠性较差,对于检测1摄氏度的信号是不适用的,也不能满足测量范围。
基于单片机的无线温控检测系统的设计

文档从互联网中收集,已重新修正排版,word格式支持编辑,如有帮助欢迎下载支持。
基于单片机的无线温度检测系统的设计摘要目前,中国的一些粮食储备工业检测系统仍然有许多不足之处,本文提出了无线传感器的设计方案,介绍了无线温度传感器的硬件结构和软件设计。
对于一些腐蚀性强或密封性高,温度测量与主机距离远的环境,有线温度测量实现起来就比较困难。
虽然随着技术的发展,温度变送器的出现解决了短距离温度的测量,但其仍然依赖于线缆。
而且随着距离的增加.信号衰减很快。
无法适用于远距离温度测量。
温度指标在许多工程程项目中是不可或缺的重要参数,针对这一要求提出的无线温度测量系统.采用数字式温度传感器DSl8B20作为测温节点。
89C52单片机作为下位机微处理器来控制温度值的采集,并通过无线收发模块NRF24L01进行传输,最后通过串口将数据传送到上位机显示芯片。
关键词:温度; 无线; 单片机Wireless temperature detecting system based on single chip microcomputerabstract At present, some of China's grain reserves industrial test system there are still many deficiencies, this paper presents a design scheme of wireless sensor, this paper introduces the hardware structure and software design of wireless temperature sensor.For some strong corrosive or high sealing, the temperature measurement and distance of the host environment, the cable temperature measurement is more difficult.Although with the development of technology, the emergence of temperature transmitter solves the short distance of temperature measurement, but it still depends on the cable.And with the increase of distance. Signal attenuation soon.Not suitable for long-distance temperature measurement.Temperature indicators in many engineering project is indispensable important parameters in the process, for the request of wireless temperature measuring system. Using digital temperature sensor DSl8B20 as temperature measurement node.Under the 89 c52 as a machine microprocessor to control the temperature of the acquisition, and transmitted through the wireless transceiver module NRF24L01, finally through a serial port to transfer data to PC display chip.Key words: temperature; wireless; single chip microcomputer目录第一章前言 0第二章无线温度检测系统的构成和工作原理 (1)2.1 无线温度检测系统的构成 (1)第三章硬件结构设计 (3)3.1 数字温度传感器DS18B20 (3)3.3 低功耗射频传输单元NRF24L01芯片 (5)3.4 LCD1602液晶显示芯片 (6)第四章系统软件设计 (7)4.1接收端的软件设计 (7)4.2 发射端的软件设计 (7)第五章系统工作原理及详细流程 (7)5.1 DS18B20工作详情 (7)5.2 AT89C52工作详情 (9)5.3 NRF24L01工作详情 (9)............................................. 错误!未定义书签。
基于单片机的智能温度计的设计

目录1设计背景 (1)1.1课题背景 (1)1.2设计内容 (1)2智能温度计系统简介 (2)2.1方案选择 (2)2.2系统设计原理 (4)2.3系统组成 (4)3.系统硬件设计 (6)3.1DS18B20温度传感器 (6)3.1.1DS18B20介绍 (6)3.1.2温度传感器工作原理 (7)3.1.3DS18B20相关介绍 (8)3.1.4DS18B20使用中的注意事项 (9)3.2液晶显示器(1602液晶显示器) (10)3.2.1液晶显示器的介绍 (10)3.2.2 1602LCD的特性 (11)3.2.3液晶模块简介 (12)3.2.3液晶显示部分与89C51的接口 (13)3.3 80C51单片机的介绍 (14)3.3.1 80C51单片机的主要特性 (15)3.3.2 80C51单片机管脚 (16)3.3.3 80C51单片机的中断系统 (18)3.3.4 80C51单片机的定时/计数器 (18)3.3.5 80C51单片机的最小系统 (19)3.4系统总体电路图 (20)4.软件设计简介 (22)4.1 C语言简介 (22)4.2 程序设计 (22)5.电路仿真 (25)5.1 Proteus软件介绍7 (25)5.2智能温度计Ptoteus仿真 (26)总结 (28)参考文献 (29)附录:源程序代码 (30)1设计背景温度控制广泛应用于人们的生产和生活中,人们使用温度计来采集温度,通过人工操作加热、通风和降温设备来控制温度,这样不但控制精度低、实时性差,而且操作人员的劳动强度大。
即使有些用户采用半导体二极管作温度传感器,但由于其互换性差,效果也不理想。
在某些行业中对温度的要求较高,由于工作环境温度不合理而引发的事故时有发生。
对工业生产可靠进行造成影响,甚至操作人员的安全。
为了避免这些缺点,需要在某些特定的环境里安装数字温度测量及控制设备。
本设计由于采用了新型单片机对温度进行测量,以其测量精度高,操作简单。
单片机课程设计报告-数字温度计

单片机课程设计报告-数字温度计单片机是一种集成了微处理器核心、存储器、外围接口和定时器等功能模块的微型计算机。
在现代电子科技领域中,单片机被广泛应用于各种嵌入式系统中。
本课程设计主要针对单片机的应用实践,通过设计一个数字温度计来锻炼学生的单片机编程能力,同时加深对数字温度计的原理及应用的理解。
二、设计目标本课程设计旨在使学生掌握以下内容:1. 掌握单片机的基本原理和编程方法;2. 了解数字温度计的原理和应用;3. 熟悉温度传感器的使用和数据处理方法;4. 能够利用单片机开发出一个简单的数字温度计。
三、设计内容本课程设计主要包括以下内容:1. 单片机原理和编程基础;2. 数字温度计的原理和应用介绍;3. 温度传感器的选型及使用方法;4. 单片机数字温度计的设计和实现。
四、设计步骤1. 单片机原理和编程基础学生首先将学习单片机的基本原理和编程方法,包括单片机的体系结构、存储器组成、I/O口的使用、定时器的应用等内容。
2. 数字温度计的原理和应用介绍学生将了解数字温度计的基本原理和应用场景,包括数字温度计的工作原理、常见的数字温度计种类、数字温度计的应用领域等。
3. 温度传感器的选型及使用方法学生将学习温度传感器的选型原则,了解各种温度传感器的特点及使用方法,包括模拟温度传感器和数字温度传感器。
4. 单片机数字温度计的设计和实现学生将利用所学的单片机编程知识和温度传感器的使用方法,设计并实现一个简单的数字温度计。
学生需要考虑温度测量精度、显示方式、数据处理方法等问题。
五、教学方法本课程设计采用理论教学与实践相结合的教学方式,通过理论课堂讲解和实际操作演示相结合,加深学生对单片机和数字温度计知识的理解和掌握。
同时,鼓励学生合作学习,共同解决实际问题,提高实战能力。
六、教学评估学生将根据设计的数字温度计的实际测量情况、数据处理方法以及最终的效果进行评估,教师将根据学生的设计方案和实际操作情况进行评分。
同时,学生对单片机编程的理解和掌握水平也将作为评估的重要内容。
基于单片机的数字温度计设计报告教材

课程设计报告引言随着电子技术的不断发展,我们能应用到的电子产品也越来越多。
而生活中我们用的很多电子产品都越来越轻巧,价格也越来越便宜.利用电子芯片实现的东西也越来越来越多,比如数字温度计。
当然,非电子产品的常用温度计也很便宜。
此次课设论文所介绍的是自己动手制作的一个高精度数字温度计。
本次课设不但丰富了课余生活,还从实践中学到并了很多新知识,并从中巩固了以前的知识。
用Protel 99软件来设计制作电路板——PCB(Printed circuit Bound)。
在PCB上,布置一系列的芯片、电阻、电容等元件,通过PCB上的导线相连,构成电路,一起实现一定的功能。
电路通过连接器或者插槽进行输入/输出,有时还有显示部分(如发光二极管LED、.数码显示器等)。
可以说,PCB是一块连接板,它的主要目的是为元件提供连接,为整个电路提供输入输出端口和显示,电气连接通性是PCB最重要的特性之一。
PCB在各种电子设备中有如下功能:(1)提供集成电路等各种电子元件固定、装配的机械支撑。
(2)实现集成电路等各种电子元件之间的布线和电气连接或电绝缘,提供所要的电气特性。
(3)为电动装配提供阻焊徒刑,为元器件插装、检查、维修提供识别符和图形。
做本课题的所用到的知识是我们学过的模拟电子电路以及数字逻辑电路等,当然还用到了刚刚学过不久的单片机知识。
本次课设是把理论和实践结合起来,这不但可以锻炼自己的动手能力,而且还可以加深对数字逻辑电路和模拟电子电路的学习和理解。
同时也激起了我学好单片机的斗志。
为了全面清晰的表达,本论文用图文并茂的方式,尽可能详细的地介绍此次设计的全过程。
1.设计务任和要求1.1、基本范围-20℃——100℃1.2、精度误差小于0.5℃1.3、LED 数码直读显示1.4、可以任意设定温度的上下限报警功能2. 系统总体方案及硬件设计2.1数字温度计设计方案论证2.1.1方案一由于本设计是测温电路,可以使用热敏电阻之类的器件利用其感温效应,在将随被测温度变化的电压或电流采集过来,进行A/D 转换后,就可以用单片机进行数据的处理,在显示电路上,就可以将被测温度显示出来,这种设计需要用到A/D 转换电路,其中还涉及到电阻与温度的对应值的计算,感温电路比较麻烦。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
五邑大学信息工程学院课程设计报告课程名称:无线温度检测器专业:电子信息工程班级:学号:姓名:指导教师:设计时间:2016年10月评定成绩:无线温度监测器一、设计任务与要求1.实时获取被测对象温度,温度测量范围:-10℃~+45℃;测量精度:±0.1℃。
2.无线传输实时获取的温度值,传输距离≥10m。
3.实时显示接收到的温度值。
4.基于单片机实现。
二、课题分析与方案选择在日常生活及工业生产过程中,经常要用到温度的检测及控制,温度是生产过程和科学实验中普遍而且重要的物理参数之一。
无线系统具有不借助外部网络、不受布线限制的优点。
本次课程设计把这两部分结合起来,用无线数据传输技术来实现温度传感器的温度数据采集。
方案一:传统的测温元件有热电偶和热电阻。
而热电偶和热电阻测出的一般都是电压,再转换成对应的温度,这些方法的缺点是硬件电路相对复杂,需要比较多的外部硬件支持。
方案二:采用DS18B20作为温度监测元件,并且基于STC89C52单片机设计温度测量及报警电路。
本次设计采用方案二,采用无线收发模块NRF24L01来实现无线传输功能,温度测量范围-55℃~+125℃,使用LCD液晶显示,并且能设置温度报警上下限。
三、单元电路分析与设计1.原理分析单片机STC89C52 具有低电压供电和体积小等特点,晶振采用12MHz。
复位电路采用上电加按钮复位。
晶振电路复位电路显示电路:显示电路采用LCD1602,滑动电阻R6用来调节背光亮度。
显示电路报警电路当单片机通电后,进入温度报警上下限调节,此时显示软件设置的温度报警上线,按s2对报警温度进行加一,按s3对报警温度进行减一。
当实际温度超过所设温度上下限时,单片机P3.0口会输出高电平,红色led灯会亮起。
温度传感器:DS18B20 温度传感器是美国DALLAS 半导体公司最新推出的一种改进型智能温度传感器,与传统的热敏电阻等测温元件相比,它能直接读出被测温度,并且可根据实际要求通过简单的编程实现9~12位的数字值读数方式。
DS18B20 的性能特点如下:1、独特的单线接口仅需要一个端口引脚进行通信;2、多个DS18B20 可以并联在惟一的三线上,实现多点组网功能3、无须外部器件;4、可通过数据线供电,电压范围为3.0~5.5V;5、零待机功耗;6、温度以9或12位数字;7、用户可定义报警设置;8、报警搜索命令识别并标志超过程序限定温度(温度报警条件)的器件;9、负电压特性,电源极性接反时,温度计不会因发热而烧毁,但不能正常工作;DS18B20采用寄生电源供电方式,此时DS18B20 的1 脚接地,2 脚作为信号线,3 脚接电源。
由于单线制只有一根线,因此发送接口必须是三态的。
温度传感器无线收发模块nrf24l01输出功率频道选择和协议的设置可以通过SPI 接口进行设置,单片机可通过IRQ引脚快判断是否完成数据接收和数据发送。
四、总原理图及元器件清单发送端:接收端:2.元件清单序号元器件名称型号主要参数数量备注1无线收发模块NRF24L0122智能温度传感器DS18B2013单片机STC89C5224显示器LCD160215电容22nf46排阻10K27晶振12MHZ28稳压器az1117t-3.3 29按键开关310LED111蜂鸣器112电阻10K2五、安装与调试1.调试过程描述一开始接收端单片机通电后显示屏背光亮,内容无显示,经检测电路后发现信号控制线断裂。
修复后显示屏能显示学号、字母信息,但是无法显示温度数字。
初步判断是程序出问题,导致无线模块没有正确接收信号。
之后更改程序,编程控制端口收发信号,最终调试成功。
2.实物照片六、性能测试与分析在本次设计中,利用单片机实现了温度测量,测量精度为 0.1℃,在发送端温度传感器的数据能实时发送到接收端,无线传输距离达到10m以上,符合设计要求。
七、结论与心得从确定题目,研究原理图,制作电路板,到焊接调试,当中出现不少问题,但是我迎难而上,把问题逐个解决,最终完成课程设计,我从中积累了很多解决问题的宝贵经验。
其中最大的问题是无线接收模块在接收温度信息时延迟比较大,后来通过查阅资料修改信道,问题得以解决。
另一个问题是当温度计一通上电后,LED灯就会一直亮。
在确定电路连接和原理图正确后依然不能解决,于是我跟同学讨论,发现是程序出错,使得单片机与LED相连的I/O口一直输出高电平,修改程序后温度计才正常工作!在排查问题过程中我的耐心得到了锻炼,并且与同学们的讨论更是让我受益匪浅!通过这次课程设计我进一步熟悉了单片机的内部结构和工作原理,了解到无线收发模块的使用方法,掌握了单片机应用系统设计的基本方法和步骤,让自己的理论水平和实践能力上升到一个新的台阶,同时我也认识到实践的重要性。
程序(程序本身没问题,只是排版乱了,大家下载回来注意修改一下双斜杠,双斜杠后面的内容会变成注释,不需要删减内容,只需要修正好回车键,都是行数的问题)发送端:#include <reg51.h>#include <intrins.h>//#include "api.h"#define uchar unsigned char#define TX_ADR_WIDTH 5 // 发射地址的字节个数#define TX_PLOAD_WIDTH 2 //发射字节uchar const TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x55,0x10,0x10,0x01}; uchar rx_buf[TX_PLOAD_WIDTH];uchar tx_buf[TX_PLOAD_WIDTH];uchar distance_data[2];uchar flag;// 标志sbit CE=P1^0; //发射高电平大于10MS 接收高电平sbit CSN=P1^1; //低电平ISP 使能sbit SCK=P1^2; //下降沿sbit MOSI=P1^3; //MCU 出sbit MISO=P1^4; //MCU 入sbit IRQ=P1^5; //中断uchar bdata sta;sbit RX_DR =sta^6; //接收数据准备就绪sbit TX_DS =sta^5; //已发送数据sbit MAX_RT =sta^4;sbit DQ=P3^0;unsigned char time; //设置全局变量,专门用于严格延时//*********************************************NRF24L01********* **************//***************************************NRF24L01 寄存器指令#define READ_REG 0x00 // 读寄存器指令#define WRITE_REG 0x20 // 写寄存器指令#define RD_RX_PLOAD 0x61 // 读取接收数据指令#define WR_TX_PLOAD 0xA0 // 写待发数据指令#define FLUSH_TX 0xE1 // 冲洗发送FIFO 指令#define FLUSH_RX 0xE2 // 冲洗接收FIFO 指令#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令#define NOP 0xFF // 保留//*************************************SPI(nRF24L01) 寄存器地址#define CONFIG 0x00 // 配置收发状态,CRC 校验模式以及收发状态响应方式#define EN_AA 0x01 // 自动应答功能设置#define EN_RXADDR 0x02 // 可用信道设置#define SETUP_AW 0x03 // 收发地址宽度设置#define SETUP_RETR 0x04 // 自动重发功能设置#define RF_CH 0x05 // 工作频率设置#define RF_SETUP 0x06 // 发射速率、功耗功能设置#define STATUS 0x07 // 状态寄存器#define OBSERVE_TX 0x08 // 发送监测功能#define CD 0x09 // 地址检测#define RX_ADDR_P0 0x0A // 频道0 接收数据地址#define RX_ADDR_P1 0x0B // 频道1 接收数据地址#define RX_ADDR_P2 0x0C // 频道2 接收数据地址#define RX_ADDR_P3 0x0D // 频道3 接收数据地址#define RX_ADDR_P4 0x0E // 频道4 接收数据地址#define RX_ADDR_P5 0x0F // 频道5 接收数据地址#define TX_ADDR 0x10 // 发送地址寄存器#define RX_PW_P0 0x11 // 接收频道0 接收数据长度#define RX_PW_P1 0x12 // 接收频道0 接收数据长度#define RX_PW_P2 0x13 // 接收频道0 接收数据长度#define RX_PW_P3 0x14 // 接收频道0 接收数据长度#define RX_PW_P4 0x15 // 接收频道0 接收数据长度#define RX_PW_P5 0x16 // 接收频道0 接收数据长度#define FIFO_STATUS 0x17 // FIFO 栈入栈出状态寄存器设置//*************************************************************** **************void init_io(void){CE=0;CSN=1;SCK=0;}void delay_ms(unsigned int x){unsigned int i,j;for(i=0;i<x;i++){j=108;while(j--);}uchar SPI_RW(uchar byte)// 发送指令,接受状态,返回值为状态值{uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++){MOSI = (byte&0x80);byte = (byte<<1);SCK = 1;byte|=MISO;SCK=0;}return(byte);}uchar SPI_RW_Reg(uchar reg, uchar value){uchar status;CSN = 0;status = SPI_RW(reg);SPI_RW(value);CSN = 1;return(status);uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0;SPI_RW(reg); // 写指令reg_val = SPI_RW(0); // 读reg 的内容CSN = 1;return(reg_val);}uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes) {uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)pBuf[byte_ctr] = SPI_RW(0);CSN = 1;return(status);}uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) {uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)SPI_RW(*pBuf++);CSN = 1;return(status);}void TX_Mode(void){CE=0;SPI_Write_Buf(WRITE_REG + TX_ADDR, TX_ADDRESS/* 接收模块的地址*/,TX_ADR_WIDTH/* 地址宽度5*/);SPI_Write_Buf(WRITE_REG + RX_ADDR_P0/* 通道0 接收数据地址*/, TX_ADDRESS,TX_ADR_WIDTH);SPI_Write_Buf(WR_TX_PLOAD,/* 写待发数据指令a0*/ tx_buf,TX_PLOAD_WIDTH/*20*/);SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //数据通道0 应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01); // 接收数据通道0 允许SPI_RW_Reg(WRITE_REG + SETUP_RETR, 0x1a);// 等待500+86us 自动重发10 次SPI_RW_Reg(WRITE_REG + RF_CH,40);SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //数据传输率1Mbps , 发射功率0dBmSPI_RW_Reg(WRITE_REG + CONFIG , 0x0e); //配置寄存器CE=1;}void checkflag(){ sta=SPI_Read(STA TUS);// 读状态寄存器// if(RX_DR)// {// SPI_Read_Buf(RD_RX_PLOAD/* 读取接收数据指令*/,rx_buf/* 数组[20]*/,TX_PLOAD_WIDTH/*20*/);// flag=1;// }if(MAX_RT){SPI_RW_Reg(FLUSH_TX/* 冲洗发送FIFO 指令*/,0);}SPI_RW_Reg(WRITE_REG+STATUS,sta);// 清除中断}//以下是DS18B20 的操作程序//*************************************************************** *********/void delay1ms(){unsigned char i,j;for(i=0;i<4;i++)for(j=0;j<33;j++);}/*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/void delaynms(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}/*****************************************************函数功能:将DS18B20 传感器初始化,读取应答信号出口参数:flag***************************************************/bit Init_DS18B20(void){bit flag; //储存DS18B20 是否存在的标志,flag=0 ,表示存在;flag=1 ,表示不存在DQ = 1; //先将数据线拉高for(time=0;time<2;time++) // 略微延时约6 微秒;DQ = 0; //再将数据线从高拉低,要求保持480~960usfor(time=0;time<200;time++) //略微延时约600 微秒; //以向DS18B20 发出一持续480~960us 的低电平复位脉冲DQ = 1; //释放数据线(将数据线拉高)for(time=0;time<10;time++); //延时约30us(释放总线后需等待15~60us 让DS18B20 输出存在脉冲)flag=DQ; //让单片机检测是否输出了存在脉冲(DQ=0 表示存在)for(time=0;time<200;time++) //延时足够长时间,等待存在脉冲输出完毕;return (flag); //返回检测成功标志}/*****************************************************函数功能:从DS18B20 读取一个字节数据出口参数:dat***************************************************/unsigned char ReadOneChar(void){unsigned char i=0;unsigned char dat; //储存读出的一个字节数据for (i=0;i<8;i++){DQ =1; // 先将数据线拉高_nop_(); //等待一个机器周期DQ = 0; //单片机从DS18B20 读书据时,将数据线从高拉低即启动读时序_nop_(); //等待一个机器周期DQ = 1; //将数据线" 人为" 拉高,为单片机检测DS18B20 的输出电平作准备for(time=0;time<2;time++); //延时约6us,使主机在15us 内采样dat>>=1;if(DQ==1)dat|=0x80; //如果读到的数据是1,则将1 存入datelsedat|=0x00;//如果读到的数据是0,则将0 存入dat//将单片机检测到的电平信号DQ 存入r[i]for(time=0;time<8;time++); //延时3us,两个读时序之间必须有大于1us 的恢复期return(dat); //返回读出的十六进制数据}/*****************************************************函数功能:向DS18B20 写入一个字节数据入口参数:dat***************************************************/ WriteOneChar(unsigned char dat){unsigned char i=0;for (i=0; i<8; i++){DQ =1; // 先将数据线拉高_nop_(); //等待一个机器周期DQ=0; //将数据线从高拉低时即启动写时序DQ=dat&0x01; //利用与运算取出要写的某位二进制数据,//并将其送到数据线上等待DS18B20 采样for(time=0;time<10;time++);//延时约30us,DS18B20 在拉低后的约15~60us 期间从数据线上采样DQ=1; //释放数据线for(time=0;time<1;time++);//延时3us,两个写时序间至少需要1us的恢复期dat>>=1; //将dat 中的各二进制位数据右移1 位for(time=0;time<4;time++); //稍作延时,给硬件一点反应时间}/*****************************************************函数功能:做好读温度的准备***************************************************/void ReadyReadTemp(void){Init_DS18B20(); //将DS18B20 初始化WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0x44); // 启动温度转换delaynms(150); // 转换一次需要延时一段时间Init_DS18B20(); //将DS18B20 初始化WriteOneChar(0xCC); // 跳过读序号列号的操作WriteOneChar(0xBE); // 读取温度寄存器,前两个分别是温度的低位和高位}void dwend(void){ uchar TL; //储存暂存器的温度低位uchar TH; //储存暂存器的温度高位TL=ReadOneChar(); //先读的是温度值低位TH=ReadOneChar(); //接着读的是温度值高位distance_data[0]=TH ; //测量结果的高8 位distance_data[1]=TL; //放入16 位的高8 位}void main(void){uchar xx;init_io();while(1){ReadyReadTemp() ;dwend();checkflag();for(xx=0;xx<2;xx++){tx_buf[xx]= distance_data[xx];// 发数据之前必须把要发送的数据装入它}TX_Mode(); //必须启动发送模块delay_ms(5);}}接收端:#include <reg51.h>#include <intrins.h>#define uchar unsigned charuchar code digit[11]={"0123456789-"}; //定义字符数组显示数字uchar code Str[]={"3113001731"}; //说明显示的是温度//unsigned char code Error[]={" DS18B20 ERROR"}; //说明没有检测到DS18B20//unsigned char code Error1[]={" PLEASE CHECK"}; //说明没有检测到DS18B20uchar code Temp[]={"wendu:"}; //说明显示的是温度uchar code Cent[]={"C"}; //温度单位uchar tm[2];uchar flg=0; //负温度标志和临时暂存变量uchar tltemp;#define TX_ADR_WIDTH 5#define TX_PLOAD_WIDTH 2uchar const TX_ADDRESS[TX_ADR_WIDTH]={0x34,0x55,0x10,0x10,0x01}; uchar rx_buf[TX_PLOAD_WIDTH];uchar tx_buf[TX_PLOAD_WIDTH];uchar flag;// 标志int cout;sbit CE=P1^0; //发射高电平大于10MS 接收高电平sbit CSN=P1^1; //低电平ISP 使能sbit SCK=P1^2; //下降沿sbit MOSI=P1^3; //MCU 出sbit MISO=P1^4; //MCU 入sbit IRQ=P1^5; //中断uchar bdata sta;sbit RX_DR =sta^6; //接收数据准备就绪sbit TX_DS =sta^5; //已发送数据sbit MAX_RT =sta^4;sbit RS=P2^5; //寄存器选择位,将RS 位定义为P2.0 引脚sbit RW=P2^6; //读写选择位,将RW 位定义为P2.1 引脚sbit E=P2^7; //使能信号位,将E 位定义为P2.2 引脚sbit BF=P0^7; //忙碌标志位,,将BF 位定义为P0.7 引脚//***************************************NRF24L01 寄存器指令#define READ_REG 0x00 // 读寄存器指令#define WRITE_REG 0x20 // 写寄存器指令#define RD_RX_PLOAD 0x61 // 读取接收数据指令#define WR_TX_PLOAD 0xA0 // 写待发数据指令#define FLUSH_TX 0xE1 // 冲洗发送FIFO 指令#define FLUSH_RX 0xE2 // 冲洗接收FIFO 指令#define REUSE_TX_PL 0xE3 // 定义重复装载数据指令#define NOP 0xFF // 保留//*************************************SPI(nRF24L01) 寄存器地址#define CONFIG 0x00 // 配置收发状态,CRC 校验模式以及收发状态响应方式#define EN_AA 0x01 // 自动应答功能设置#define EN_RXADDR 0x02 // 可用信道设置#define SETUP_AW 0x03 // 收发地址宽度设置#define SETUP_RETR 0x04 // 自动重发功能设置#define RF_CH 0x05 // 工作频率设置#define RF_SETUP 0x06 // 发射速率、功耗功能设置#define STATUS 0x07 // 状态寄存器#define OBSERVE_TX 0x08 // 发送监测功能#define CD 0x09 // 地址检测#define RX_ADDR_P0 0x0A // 频道0 接收数据地址#define RX_ADDR_P1 0x0B // 频道1 接收数据地址#define RX_ADDR_P2 0x0C // 频道2 接收数据地址#define RX_ADDR_P3 0x0D // 频道3 接收数据地址#define RX_ADDR_P4 0x0E // 频道4 接收数据地址#define RX_ADDR_P5 0x0F // 频道5 接收数据地址#define TX_ADDR 0x10 // 发送地址寄存器#define RX_PW_P0 0x11 // 接收频道0 接收数据长度#define RX_PW_P1 0x12 // 接收频道0 接收数据长度#define RX_PW_P2 0x13 // 接收频道0 接收数据长度#define RX_PW_P3 0x14 // 接收频道0 接收数据长度#define RX_PW_P4 0x15 // 接收频道0 接收数据长度#define RX_PW_P5 0x16 // 接收频道0 接收数据长度#define FIFO_STATUS 0x17 // FIFO 栈入栈出状态寄存器设置//*************************************************************** **************void delay1ms(){unsigned char i,j;for(i=0;i<4;i++)for(j=0;j<33;j++);}/*****************************************************函数功能:延时若干毫秒入口参数:n***************************************************/void delaynms(unsigned char n){unsigned char i;for(i=0;i<n;i++)delay1ms();}bit BusyTest(void){bit result;RS=0; //根据规定,RS 为低电平,RW 为高电平时,可以读状态RW=1;E=1; //E=1 ,才允许读写_nop_(); //空操作_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间result=BF; //将忙碌标志电平赋给resultE=0; //将E 恢复低电平return result;}/*****************************************************函数功能:将模式设置指令或显示地址写入液晶模块入口参数:dictatevoid WriteInstruction (unsigned char dictate){while(BusyTest()==1); //如果忙就等待RS=0; //根据规定,RS 和R/W 同时为低电平时,可以写入指令RW=0;E=0; //E 置低电平(根据表8-6,写指令时,E 为高脉冲,// 就是让E 从0 到1 发生正跳变,所以应先置"0"_nop_();_nop_(); //空操作两个机器周期,给硬件反应时间P0=dictate; //将数据送入P0 口,即写入指令或地址_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E 置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E 由高电平跳变成低电平时,液晶模块开始执行命令}函数功能:指定字符显示的实际地址入口参数:x***************************************************/void WriteAddress(unsigned char x){WriteInstruction(x|0x80); // 显示位置的确定方法规定为"80H+ 地址码x" }/*****************************************************函数功能:将数据(字符的标准ASCII 码)写入液晶模块入口参数:y(为字符常量)***************************************************/void WriteData(unsigned char y){while(BusyTest()==1);RS=1; //RS 为高电平,RW 为低电平时,可以写入数据RW=0;E=0; //E 置低电平(根据表8-6,写指令时,E 为高脉冲,// 就是让E 从0 到1 发生正跳变,所以应先置"0"P0=y; //将数据送入P0 口,即将数据写入液晶模块_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=1; //E 置高电平_nop_();_nop_();_nop_();_nop_(); //空操作四个机器周期,给硬件反应时间E=0; //当E 由高电平跳变成低电平时,液晶模块开始执行命令}/*****************************************************函数功能:对LCD 的显示模式进行初始化设置***************************************************/void LcdInitiate(void){delaynms(15); //延时15ms,首次写指令时应给LCD 一段较长的反应时间WriteInstruction(0x38); //显示模式设置:16×2 显示,5×7 点阵,8 位数据接口delaynms(5); //延时5ms ,给硬件一点反应时间WriteInstruction(0x38);delaynms(5); //延时5ms ,给硬件一点反应时间WriteInstruction(0x38); //连续三次,确保初始化成功delaynms(5); //延时5ms ,给硬件一点反应时间WriteInstruction(0x0c); //显示模式设置:显示开,无光标,光标不闪烁delaynms(5); //延时5ms ,给硬件一点反应时间WriteInstruction(0x06); //显示模式设置:光标右移,字符不移delaynms(5); //延时5ms ,给硬件一点反应时间WriteInstruction(0x01); //清屏幕指令,将以前的显示内容清除delaynms(5); //延时5ms ,给硬件一点反应时间}/*****************************************************函数功能:显示说明信息***************************************************/void display_explain(void){unsigned char i;WriteAddress(0x00); //写显示地址,将在第1 行第1 列开始显示i = 0; //从第一个字符开始显示while(Str[i] != '\0') //只要没有写到结束标志,就继续写{WriteData(Str[i]); //将字符常量写入LCDi++; //指向下一个字符delaynms(100); //延时100ms 较长时间,以看清关于显示的说明}}/*****************************************************函数功能:显示温度符号***************************************************/void display_symbol(void){unsigned char i;WriteAddress(0x40); //写显示地址,将在第2 行第1 列开始显示i = 0; //从第一个字符开始显示while(Temp[i] != '\0') //只要没有写到结束标志,就继续写{WriteData(Temp[i]); //将字符常量写入LCDi++; //指向下一个字符delaynms(50); //延时1ms 给硬件一点反应时间}}/*****************************************************函数功能:显示温度的小数点***************************************************/void display_dot(void){WriteAddress(0x49); //写显示地址,将在第2 行第10 列开始显示WriteData('.'); //将小数点的字符常量写入LCDdelaynms(50); //延时1ms 给硬件一点反应时间}/*****************************************************函数功能:显示温度的单位(Cent)***************************************************/void display_cent(void){unsigned char i;WriteAddress(0x4c); //写显示地址,将在第2 行第13 列开始显示i = 0; //从第一个字符开始显示while(Cent[i] != '\0') //只要没有写到结束标志,就继续写{WriteData(Cent[i]); //将字符常量写入LCDi++; //指向下一个字符delaynms(50); //延时1ms 给硬件一点反应时间}}/*****************************************************函数功能:显示温度的整数部分入口参数:x***************************************************/void display_temp1(uchar x){uchar j,k,l; //j,k,l 分别储存温度的百位、十位和个位j=x/100; //取百位k=(x%100)/10; //取十位l=x%10; //取个位WriteAddress(0x46); //写显示地址,将在第2 行第7 列开始显示if(flg==1) //负温度时显示“—”{WriteData(digit[10]); //将百位数字的字符常量写入LCD}else{WriteData(digit[j]); //将十位数字的字符常量写入LCD}WriteData(digit[k]); //将十位数字的字符常量写入LCD WriteData(digit[l]); //将个位数字的字符常量写入LCD delaynms(5); //延时1ms 给硬件一点反应时间}/*****************************************************函数功能:显示温度的小数数部分入口参数:x***************************************************/void display_temp2(uchar x){WriteAddress(0x4a); //写显示地址,将在第2 行第11 列开始显示WriteData(digit[x]); //将小数部分的第一位数字字符常量写入LCD delaynms(5); //延时1ms 给硬件一点反应时间}void init_io(void){CE=0;CSN=1;SCK=0;}void delay_ms(unsigned int x){unsigned int i,j;for(i=0;i<x;i++){j=108;while(j--);}}uchar SPI_RW(uchar byte){uchar bit_ctr;for(bit_ctr=0;bit_ctr<8;bit_ctr++){MOSI = (byte&0x80);byte = (byte<<1);SCK = 1;byte|=MISO;SCK=0;}return(byte);}uchar SPI_RW_Reg(uchar reg, uchar value) {uchar status;CSN = 0;status = SPI_RW(reg);SPI_RW(value);CSN = 1;return(status);}uchar SPI_Read(uchar reg){uchar reg_val;CSN = 0;SPI_RW(reg);reg_val = SPI_RW(0);CSN = 1;return(reg_val);}uchar SPI_Read_Buf(uchar reg, uchar *pBuf, uchar bytes) {uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0;byte_ctr<bytes;byte_ctr++)pBuf[byte_ctr] = SPI_RW(0);CSN = 1;return(status);}uchar SPI_Write_Buf(uchar reg, uchar *pBuf, uchar bytes) {uchar status,byte_ctr;CSN = 0;status = SPI_RW(reg);for(byte_ctr=0; byte_ctr<bytes; byte_ctr++)SPI_RW(*pBuf++);CSN = 1;return(status);}void RX_Mode(void){CE=0;SPI_Write_Buf(WRITE_REG + RX_ADDR_P0, TX_ADDRESS, TX_ADR_WIDTH);SPI_RW_Reg(WRITE_REG + EN_AA, 0x01); //数据通道0 应答允许SPI_RW_Reg(WRITE_REG + EN_RXADDR, 0x01);// 接收数据通道0 允许SPI_RW_Reg(WRITE_REG + RF_CH, 40);SPI_RW_Reg(WRITE_REG + RX_PW_P0, TX_PLOAD_WIDTH);// 接收频道0 接收数据长度设置SPI_RW_Reg(WRITE_REG + RF_SETUP, 0x07); //数据传输率1Mbps , 发射功率0dBmSPI_RW_Reg(WRITE_REG + CONFIG , 0x0f); //配置寄存器CE = 1;}void checkflag(){sta=SPI_Read(STATUS);if(RX_DR){SPI_Read_Buf(RD_RX_PLOAD,rx_buf,TX_PLOAD_WIDTH);flag=1;}if(MAX_RT){SPI_RW_Reg(FLUSH_TX,0);}SPI_RW_Reg(WRITE_REG+STATUS,sta);}void yejinchu(void){LcdInitiate(); //将液晶初始化delaynms(5); //延时5ms 给硬件一点反应时间display_explain();display_symbol(); //显示温度说明display_dot(); //显示温度的小数点display_cent(); //显示温度的单位}void xianshi(void){uchar TL; //储存暂存器的温度低位uchar TH; //储存暂存器的温度高位uchar TN; //储存温度的整数部分uchar TD; //储存温度的小数部分TH=tm[0] ;TL=tm[1];if((TH&0xf8)!=0x00)// 判断高五位得到温度正负标志{flg=1;TL=~TL; //取反TH=~TH; //取反tltemp=TL+1; // 低位加1TL=tltemp;if(tltemp>255) TH++; //如果低8 位大于255,向高8 位进1TN=TH*16+TL/16; //实际温度值=(TH*256+TL)/16, 即:TH*16+TL/16 //这样得出的是温度的整数部分,小数部分被丢弃了TD=(TL%16)*10/16; //计算温度的小数部分,将余数乘以10 再除以16 取整,}TN=TH*16+TL/16; //实际温度值=(TH*256+TL)/16, 即:TH*16+TL/16 //这样得出的是温度的整数部分,小数部分被丢弃了TD=(TL%16)*10/16; //计算温度的小数部分,将余数乘以10 再除以16 取整,//这样得到的是温度小数部分的第一位数字(保留1 位小数)display_temp1(TN); //显示温度的整数部分display_temp2(TD); //显示温度的小数部分delaynms(5);}void main(void){uchar xx;yejinchu();init_io();RX_Mode();while(1){checkflag();if(flag){flag=0;for(xx=0;xx<2;xx++){tm[xx]=rx_buf[xx];delay_ms(1);}xianshi();}}}八、参考文献[1] 康华光,陈大钦,张林.电子技术基础模拟部分(第五版).高等教育出版社.2006.103-108[2]余发山.单片机原理及应用技术.中国矿业大学出版社,2003.31-32[3] 51单片机学习网/TEST/XL1000/xl1000623.htm[4] 康华光,陈大钦,张林.电子技术基础数字部分(第五版).高等教育出版社.2006.103-108。