02- 模块化编程-004 DB18B20温度数码显示

1、DB18B20采样与显示电路


2、DB18B20简介

  • DS18B20是一款高精度的单总线数字温度传感器,适用于多种温度测量场合。
  • 温度范围:-55℃至125℃
  • 精度:可编程设定9至12位分辨率,对应温度分辨率0.5℃、0.25℃、0.125℃、0.0625℃
  • 通信:单总线协议,通过一根通信线完成数据传输
  • 供电:支持2.5V至5.5V电压供电,也可通过寄生电源供电
  • 内部结构:64位ROM和9字节暂存器,支持多点组网

 编程难点:严格的时序要求,需要精确控制起始和采样时间

3、软件代码

DS18B20.c

/********************************************************************** 模块名称: DS18B20.c* 模块描述: DS18B20温度传感器驱动程序实现* 创建人: bianjingyuan* 创建日期: 2024年11月4日* 编译环境: Windows XP + MPLAB IDE 8.83 + Picc 9.60* 版本号: 1.0* 修改记录: 无*********************************************************************/#include "DS18B20.h"      // 包含DS18B20的头文件// 定义数据类型
#define uint unsigned int    // uint 类型定义为无符号整型
#define uchar unsigned char  // uchar 类型定义为无符号字符型// 定义汇编指令
#define nop asm("NOP")      // 定义空操作指令// 定义DS18B20通信端口
#define DQ RD0              // 选择与DS18B20通信的端口为 RD0// 定义获取高字节和低字节的宏
#define highbyte(value) ((value) >> 8)      // 获取无符号整型的高字节
#define lowbyte(value) ((value) & 0xFF)     // 获取无符号整型的低字节// DQ引脚的高低电平设置宏
#define DQ_HIGH() TRISD0 = 1  // 将 DQ 端口设置为输入(高电平)
#define DQ_LOW()  DQ = 0; TRISD0 = 0 // 将 DQ 端口设置为输出并拉低(低电平)// 全局变量
uchar temp_h; // 存储温度整数部分(范围从 0 到 255)
uchar temp_l; // 存储温度小数部分(范围从 0 到 99)/********************************************************************** 函 数 名: Init_DS18B20* 功能描述: 初始化DS18B20传感器* 调用函数: delayus()* 全局变量: 无* 输 入: 无* 返 回: 无***********************************************************************/
void Init_DS18B20(void)
{unsigned char ucPresence = 1; // 用于检查DS18B20的存在信号while (ucPresence) // 如果没有收到应答信号则持续尝试{DQ_LOW();  // 将总线拉到低电平以初始化传感器delayus(200);  // 延时503us以确保传输稳定delayus(200);delayus(200);DQ_HIGH();  // 释放总线,等到上拉电阻将总线拉高delayus(90);  // 等待从机的应答信号if (DQ == 1)  // 如果没有接收到低电平应答信号ucPresence = 1;elseucPresence = 0;  // 接收到应答信号delayus(250);delayus(250);  // 额外等待一段时间以确保时序完整}
}/********************************************************************** 函 数 名: Read_One_Char* 功能描述: 读取DS18B20的一个字节* 调用函数: delayus()* 全局变量: 无* 输 入: 无* 返 回: unsigned char 读取到的字节***********************************************************************/
unsigned char Read_One_Char(void)
{unsigned char ucI, ucValue = 0;static bit bJ;for (ucI = 8; ucI > 0; ucI--)  // 循环读取8位数据{ucValue >>= 1;  // 将已读取的数据右移一位DQ_LOW();  // 拉低电平以开始数据读取delayus(5);  // 延时6us以确保信号有效DQ_HIGH();  // 拉高电平以释放总线delayus(3);  // 等待数据的稳定bJ = DQ;  // 读取当前数据位if (bJ) ucValue |= 0x80;  // 如果是高电平,将当前数据位置1delayus(80);  // 延时63us以确保一个完整的读周期}return ucValue;
}/********************************************************************** 函 数 名: Write_One_Char* 功能描述: 写一个字节至DS18B20* 调用函数: delayus()* 全局变量: 无* 输 入: unsigned char ucVal - 要写入的字节值* 返 回: 无***********************************************************************/
void Write_One_Char(unsigned char ucVal)
{unsigned char ucI, ucTemp;for (ucI = 8; ucI > 0; ucI--)  // 循环写入8位数据{ucTemp = ucVal & 0x01;  // 获取要写入字节的最低位DQ_LOW(); delayus(4);  // 拉低电平以标记写入时间隙if (ucTemp == 1)  DQ_HIGH();  // 如果是1,拉高电平delayus(75);  // 延时63us完成写入DQ_HIGH(); delayus(1);  // 等待总线恢复稳定ucVal >>= 1;  // 处理下一个数据位}
}/********************************************************************** 函 数 名: Read_Temperature* 功能描述: 读取DS18B20温度,并显示到数码管XXX.XX格式* 调用函数: Init_DS18B20(), Write_One_Char(), Read_One_Char(), highbyte(), send()* 全局变量: 无* 输 入: 无* 返 回: 无***********************************************************************/
void Read_Temperature(void)
{unsigned char ucA = 0, ucB = 0;  // 用于存储温度的临时变量unsigned int uiT = 0;DQ_HIGH();  // 准备开始通信Init_DS18B20();  // 初始化DS18B20Write_One_Char(0xCC);  // 跳过ROM命令Write_One_Char(0x44);  // 启动温度转换Init_DS18B20();  // 再次初始化以准备数据读取Write_One_Char(0xCC);  // 跳过ROM命令Write_One_Char(0xBE);  // 读取温度寄存器DQ_HIGH();ucA = Read_One_Char();  // 读取温度低字节ucB = Read_One_Char();  // 读取温度高字节uiT = ucB;  // 将高字节转移到整型变量中uiT <<= 8;uiT |= ucA;  // 将低字节加入到整型变量中// 计算整数部分和小数部分temp_h = (uiT >> 4); // 整数部分temp_l = (100 * (ucA & 0x0F)) >> 4; // 小数部分 (0-99 之间)
}

main.c

//***************************************************************************/
//*  文件名:demo-DS18B20.c
//*  文件描述:PIC16f887,20MHZ,单总线DS18B20温度传感器取样数字显示程序
//*	    此文件用于器件的驱动程序仿真
//*  创建人:bianjingyuan  2024年11月4日
//*  编译环境: Windows XP + MPLAB IDE 8.83 + Picc 9.60
//*  版本号:1.0
//*  修改记录:无
//***************************************************************************/
//   硬件资源分配表:
//	  pic16f887工作频率 20MHZ  外部晶体振荡
//***************************************************************************/
//	  max7219的引脚定义如下:
// 		din  		RE0		//RE0-RE2为887引脚输出
// 		clk_1  		RE2=1
// 		clk_0  		RE2=0
// 		load_1  	RE1=1
//	 	load_0  	RE1=0
//***************************************************************************/
//	DS1820的空闲状态是高电平,如果总线停留在低电平超过480μs,所有器件都将被复位。
//	单线总线系统包括一个总线控制器和一个或多个从机。DS1820是从机。
//	单线总线需要一个约5KΩ的上拉电阻。DS1820间的任何通讯都需要以初始化序列开始
//***************************************************************************/
//	DS1820的引脚定义如下:
//	DQ		RD0		//定义通信端口
//***************************************************************************/#include 	"pic.h"					//包含单片机内部资源预定义// 数据类型定义
#define 	uchar 	unsigned char
#define 	uint  	unsigned int
#define 	ulong 	unsigned long
#define 	nop		asm("NOP")
#define 	sleep  	asm("sleep")
#define 	DQ		RD0				//定义DS1820通信端口// *************************以下声明本模块中所调用的函数类型 *****************/
// 发送一字节数据到MAX7219,指定地址和数据
extern void send(uchar address, uchar data);
// 初始化MAX7219器件
extern void Max7219_Init(void);
// 初始化DS18B20传感器
extern void Init_DS18B20(void);
// 从DS18B20读取一个字节的数据
extern uchar Read_One_Char(void);
// 向DS18B20写入一个字节的数据
extern void Write_One_Char(uchar data);
// 读取DS18B20传感器的温度
extern void Read_Temperature(void);
// 延时指定的微秒数,a为延时长度
void delayus(uchar a);
// 延时指定的毫秒数,a为延时长度
void delay_ms(uchar a);
// 延时约1秒钟
void delay_1s(void);
// 初始化系统参数和配置
void Initial_System(void);
// 设置I/O端口状态
void Set_Port_IO(void);extern uchar temp_h; // 存储整数部分
extern uchar temp_l; // 存储小数部分// ****************************887芯片配置位*************************************/
__CONFIG (0x20F2);			// 20MHZ外部晶振// *****************************定义全局变量***********************************/// ***************************主程序*******************************************/
void main()
{di();Initial_System();Set_Port_IO();Max7219_Init();
redo:Read_Temperature();send(0x01, 15);send(0x02, 15);send(0x03, (temp_h / 10));  // 显示第二位温度数据send(0x04, (temp_h % 10) + 128);  // 最后一位显示小数点send(0x05, temp_l / 10);  // 显示小数部分send(0x06, temp_l % 10);send(0x07, 15);send(0x08, 15);delay_1s();goto redo;
}/**************************以下为函数和子程序********************************/ 
//* 名称:   delayus(uchar a)	
//* 说明:   对应20M的工作频率,a取值1-250
//* 功能:   a大于0,延时约(a*0.8+2) us
//* 调用:   无
//* 输入:   无
//* 返回值: 无
//***************************************************************************/
void delayus(uchar a)
{uchar i;for(i = a; i > 0; i--){nop;}
}//***************************************************************************/
//* 名称:   delay_ms(uchar a)	
//* 说明:   对应8M的工作频率
//* 功能:   a延时约a ms,a取值范围从1-127
//* 调用:   无
//* 输入:   无
//* 返回值: 无
//***************************************************************************/
void delay_ms(uchar a)			
{uchar i;a = a << 1;while(a--)for(i = 142; i > 0; i--)		{ nop; nop; nop; nop; }
}//***************************************************************************/
//* 名称:   delay_1s()	
//* 说明:   对应20M的工作频率
//* 功能:   软件延时1s
//* 调用:   无
//* 输入:   无
//* 返回值: 无
//**************************************************************************/
void delay_1s(void)		// 延迟1S
{ulong d = 185300;	// 对应20M的工作频率while(--d);
}//***************************************************************************/
//* 名称:   initial_system()	
//* 说明:   887芯片初始化
//* 功能:   系统初始化子程序
//* 调用:   无
//* 输入:   无
//* 返回值: 无
//**************************************************************************/
void Initial_System(void)		
{OPTION = 0b01010000;	// 1us = TMROINTCON = 0b00000000;	// 开外围模块中断ANSEL = 0;			// 设定没有通道做AD,这样才能使用E口做显示驱动ANSELH = 0b00000000;	
}//***************************************************************************/
//* 名称:   set_port_io()	
//* 说明:   887芯片端口I/O定义
//* 功能:   端口I/O定义
//* 调用:   无
//* 输入:   无
//* 返回值: 无
//**************************************************************************/
void Set_Port_IO(void)		
{TRISA = 0;PORTA = 0;TRISD = 0;			PORTD = 0;TRISE = 0; 	// 显示驱动PORTE = 0;
}


4、代码解析

        该程序实现了对DS18B20温度传感器的驱动和数据读取。主要功能包括:

  1. 初始化DS18B20传感器,确保其处于可以通信的状态。
  2. 读取DS18B20传感器的温度数据,并将其转换为二进制格式。
  3. 将读取的温度数据进行处理,分解为整数部分和小数部分,并准备好显示。
  4. 提供写入功能,用于向DS18B20传感器发送命令。

        这些功能广泛应用于需要实时温度检测和采集的设备或系统中。


5、硬件资源分配表

序号引脚类别方向功能定义功能内容相关的寄存器及配置
1RD0数字IO双向DQDS18B20数据总线TRISD0配置
  1. 初始化DS18B20传感器,确保其能够进行温度检测。
  2. 启动温度转换并读取温度寄存器中的数据。
  3. 将读取的温度数据转换为可显示的格式(整数和小数部分)。
  4. 提供基础的写入和读取字节的功能,与DS18B20传感器进行命令和数据交互。

 

6、软件流程图


7、仿真运行结果

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/2164.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

[241102] Fedora Linux 41 正式发布 | Wasmer 5.0 发布

目录 Fedora Linux 41 正式发布Wasmer 5.0 发布 Fedora Linux 41 正式发布 主要更新&#xff1a; DNF 5: 更快、更小、依赖更少&#xff0c;统一了容器、服务器、桌面和设备的包管理体验。桌面更新&#xff1a; Fedora Workstation 41 基于 GNOME 47&#xff0c;默认终端改为…

C++继承

文章目录 一、继承的概念和定义1、继承的概念2、继承的定义3、继承基类成员访问方式的变化 二、基类和派生类之间的转换三、继承中的作用域1、隐藏规则 四、派生类的默认成员函数1、常见默认成员函数2、实现一个不能被继承的类 五、继承与友元六、继承与静态成员变量七、多继承…

嵌入式linux系统中串口驱动框架分析

大家好,今天主要给大家分享一下,如何使用linux系统中的串口实现。 第一:串口基本简介 串口是很常见的一个外设,在Linux下通常通过串口和其他设备或传感器进行通信。根据电平的不同,串口可以分为TTL和RS232。不管是什么样的电平接口,驱动程序是一样的。 第二:Linux下UAR…

秋日盛景,北京马拉松万人齐跑,秀域人工智能理疗获好评无数

在金秋送爽的北京&#xff0c;一场全民瞩目的体育盛事——北京马拉松顺利开跑&#xff0c;再次点燃了这座城市的运动激情。各地跑者齐聚双奥之城&#xff0c;共同奔赴在秋日美景之中。      回首往昔&#xff0c;1981年9月27日&#xff0c;首届北京马拉松赛的举办&#xff…

Java-I/O框架09:InputStreamReader、OutputStreamWriter使用

视频链接&#xff1a;16.24 转换流的使用_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1Tz4y1X7H7?spm_id_from333.788.videopod.episodes&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5&p24 1.InputStreamReader使用 package com.yundait.Demo05;import java…

JavaScript语法基础(JS使用方式, 输出方式, 变量,数据类型,运算符,程序控制语句)

目录 JS概念 一.JS使用方式 &#xff08;1&#xff09;行内式 &#xff08;2&#xff09;内嵌式 &#xff08;3&#xff09;外链式 二.JS输出方式 三.基本语法 1.变量 &#xff08;1&#xff09;变量的命名 &#xff08;2&#xff09;变量的声明 &#xff08;3&#xf…

NPOI 操作详解(操作Excel)

目录 1. 安装 NPOI 2. 使用 NPOI 创建新 Excel 文件 3. 设置列宽和行高 1. 设置列宽 2. 设置行高 3. 同时设置列宽和行高 4. 设置统一的行高 5. 设置统一的列宽 6. 应用统一的行高和列宽 4. 合并单元格 5. 设置单元格样式&#xff08;字体、边框、背景色等&#xf…

codigger体验过程记录

一、codigger的介绍 codigger是一款分布式操作系统&#xff0c;主要是便于进行个人移动化办公、在线协同办公、开发和娱乐的私人应用。 收到codigger开发者朋友的邀请&#xff0c;于是进行了这款产品的升级体验&#xff0c;接下来就简单介绍一下自己的体验过程吧。 二、登录系…

使用labelme中的AI模型提升数据标注速度

1、打开labelme 2、选择AI模型 选择之后&#xff0c;会自动进行模型下载&#xff0c;推荐开梯子&#xff0c;否则可能下载失败&#xff0c;最小的EfficientSam 在30M左右 3、右键选择AI多边形&#xff08;分割&#xff09;或AI蒙版&#xff08;目标检测&#xff09;&#xf…

全双工通信协议WebSocket——使用WebSocket实现智能学习助手/聊天室功能

一.什么是WebSocket&#xff1f; WebSocket是基于TCP的一种新的网络协议。它实现了浏览器与服务器的全双工通信——浏览器和服务器只需要完成一次握手&#xff0c;两者之间就可以创建持久性的连接&#xff0c;并进行双向数据传输 HTTP 协议是一种无状态的、无连接的、单向的应用…

音乐网站新篇章:SpringBoot Web实现

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常…

【初阶数据结构篇】链式结构二叉树(二叉链)的实现(感受递归暴力美学)

文章目录 须知 &#x1f4ac; 欢迎讨论&#xff1a;如果你在学习过程中有任何问题或想法&#xff0c;欢迎在评论区留言&#xff0c;我们一起交流学习。你的支持是我继续创作的动力&#xff01; &#x1f44d; 点赞、收藏与分享&#xff1a;觉得这篇文章对你有帮助吗&#xff1…

el-talble selection行 初始默认勾选

导言 el-talble selection 行&#xff08;选择列&#xff09;用于显示复选框&#xff0c;让用户可以选择或取消选择某些表格行&#xff0c;常用于批量操作场景。 刚刚试了下&#xff0c;想加深印象记录一下当学习碎片。参考的是表格多选并根据每行值初始化选中状态&#xff08;…

RabbitMQ交换机类型

RabbitMQ交换机类型 1、RabbitMQ工作模型2、RabbitMQ交换机类型2.1、Fanout Exchange&#xff08;扇形&#xff09;2.1.1、介绍2.1.2、示例2.1.2.1、生产者2.1.2.2、消费者2.1.2.3、测试 2.2、Direct Exchange&#xff08;直连&#xff09;2.2.1、介绍2.2.2、示例2.2.2.1、生产…

数据结构---排序(上)

一.直接插入排序 思想&#xff1a;将一个个未排序的数字插入到已经排好顺序的数组中。 例如&#xff1a; 思路&#xff1a;先将前两个数字排序&#xff0c;然后将后面数字与前面数字比较排序。 操作&#xff1a; 1.引入变量 i 遍历数组[1&#xff0c;array.lenth] 2.用临时…

ai翻唱部分步骤

模型部署 我是用的RVC进行的训练&#xff0c;也可以使用so-vits-svc。 通过百度网盘分享的文件&#xff1a;RVC-beta 链接&#xff1a;https://pan.baidu.com/s/1c99jR2fLChoqUFqf9gLUzg 提取码&#xff1a;4090 以Nvida显卡为例&#xff0c;分别下载“RVC1006Nvidia”和…

C++的stack和Queue

1.简单实现stack 构建一个模板&#xff0c;俩个参数&#xff0c;这里第一个一般是数据的类型&#xff0c;第二个是由什么来实现栈&#xff0c;在主函数里传了int和vector<int>&#xff0c;第二个不传参也可以&#xff0c;因为是缺省参数&#xff0c;默认为vector&#x…

默认路由:实现内网所有网段流量走一条默认路由访问外网

默认路由 Tip&#xff1a;默认路由一般指出口网关设备的出口路由。实现所有网段流量都走一条路由。 实验模拟&#xff1a;公司内部pc 通过出口网关 访问运营商内部 baidu服务 isp网关配置&#xff1a; <Huawei>sy Enter system view, return user view with CtrlZ. …

蘑菇书(EasyRL)学习笔记(2)

1、序列决策 1.1、智能体和环境 如下图所示&#xff0c;序列决策过程是智能体与环境之间的交互&#xff0c;智能体通过动作影响环境&#xff0c;环境则返回观测和奖励。智能体的目标是从这些反馈中学习出能最大化长期奖励的策略&#xff0c;这一过程通过不断试错和调整实现强化…

【C语言刷力扣】28.找出字符串中第一个匹配项的下标

题目&#xff1a; 解题思路&#xff1a; 暴力算法 int strStr(char* haystack, char* needle) {int n strlen(haystack), m strlen(needle);for (int i 0; i m < n; i) {bool res true;for (int j 0; j < m; j) {if (haystack[ji] ! needle[j]) {res false;break…