DS18B20与单片机的通信、DS18B20采集温度、MODBUS协议、练习框架

我要成为嵌入式高手之4月9日51单片机第四天!!
————————————————————————————

DS18B20温度传感器

单总线数字温度计

异步的半双工的串行通信

测量范围从-55℃ ~ +125℃,增量值为0.5℃

要用DS18B20采集温度,就要实现与单片机之间的通信,因此有两个问题

Bus master active low:主机执行低电平

DS1820 active low:DS18B20执行低电平

Both bus master and DS1820 active low:全都释放低电平

Resistor pull-up:电阻拉高

1、如何向DS18B20发送数据

sendChar(发送单字节的数据)

主机(单片机)向DS18B20写入(发送)0: 

        空闲时总线上呈现高电平,如果要发送0,就把总线电平拉低:至少(MIN)拉低15微秒,典型(TYP)拉低30微秒,最多(MAX)拉低60微秒。这样一段时间就表示单片机向DS18B20写入一个0;(由于是异步传输,故0 和 1只能靠控制时间长短来表示)

主机(单片机)向DS18B20写入(发送)1:

        空闲时总线上呈现高电平,如果要发送1,就把总线电平拉低,拉低时间大于1微秒后,立刻又将电平拉高,拉高时间为:至少(MIN)拉高15微秒,典型(TYP)拉高30微秒,最多(MAX)拉高60微秒。

2、如何从DS18B20读取数据

readChar()

MASTER SAMPLES:主机采样(读引脚电平)

主机(单片机)从DS18B20读取(接收)0:

        空闲时总线上呈现高电平,DS18B20会将电平拉低,在拉低后的15微秒以内,单片机进行采样,若为低电平,说明收到的是0;

主机(单片机)从DS18B20读取(接收)1:

        空闲时总线上呈现高电平,DS18B20会将电平拉低,在拉低后1微秒之后且15微秒以内,单片机进行采样,若为高电平,说明收到的是1;

以上两图即为DS18B20数据收发原理

———————————————————————————————————————————

DS18B20采集流程

复位

1、单片机向DS18B20发送0xCC

2、单片机向DS18B20发送0x44(启动温度变换)

3、延时(将温度模拟转换为数字需要时间,大约为700ms)

复位

4、单片机向DS18B20发送0xCC

5、单片机向DS18B20发送0xBE(读取温度)

6、单片机连续从DS18B20读取两个字节

如何将读取到的字节转换为浮点型(float)?

读出的两个字节是一个补码,需要 * 0.0625(2 ^ -4)得到温度

涉及到的问题:

        单片机P37和DS18B20总线连接起来,要是P37要拉低电平,总线要拉高电平,那到底是高电平还是低电平?

        答:一定是低电平,因为有任一方拉低,相当于该总线接地,那么就是低电平。

        那么如何保证该总线一定是高电平呢?

        答:在该总线上外接一个上拉电阻(4.7k ~ 10k)(因为51的内部构造,导致51的上拉电平非常弱,因此需要这个电阻来添一把力,保证它是高电平),这样在单片机和DS18B20同时拉高时,该总线一定是高电平。

这俩表现出一种特性:线与特性

拉高总线的操作称为:释放总线

拉低总线的操作称为:占有总线

初始化过程"复位和存在脉冲"

黑色线表示单片机拉低,此时DS18B20释放总线(最少480最多960微秒);然后单片机释放总线在60~240微秒之内DS18B20要拉低总线,这样就能检测到低电平,在240微秒之后,DS18B20再次释放总线,此时总线上必然会检测到高电平,这样就表示该信号存在可以被使用

延时10us函数

//延时10us
void delay10us(unsigned int n)	//@12.000MHz
{
	unsigned char data i;

	while (n--)
	{
		i = 2;
		while (--i);
	}
}

初始化

#include "ds18b20.h"

#define DS18B20CLR (P3 &= ~(1 << 7))
#define DS18B20SET (P3 |= (1 << 7))
#define DS18B20TST ((P3 & (1 << 7)) != 0)//判断总线是否为高电平,1为高电平,0为低电平

void delay10us(unsigned int n)	//@12.000MHz
{
	unsigned char data i;

	while (n--)
	{
		i = 2;
		while (--i);
	}
}

int rest18b20(void)
{
	int t = 0;

	DS18B20CLR;//单片机拉低
	delay10us(70);//延时
	DS18B20SET;//释放总线

	while (t <= 24 && DS18B20TST)//240us之内,DS18B20为高电平
	{
		delay10us(1);
		++t;		
	}
	if (t >= 24)//超过240us
	{
		return 0;//说明初始化有问题
	}
	
	t = 0;
	while (t <= 24 && !DS18B20TST)//240us之内,DS18B20为低电平
	{
		delay10us(1);
	}
	if (t > 24)
	{
		return 0;//一直为低电平,跳不上高电平,初始化有问题
	}	
	return 1;//在240us之内出现低电平,初始化正确,返回1
}

 向18b20发送数据

/*******************
 *向18b20发送数据
 *一次发送一个char
 *先发低位
 ******************/
void sendChar(unsigned char n)//LSB先行,先发低位
{
	int i = 0;
	
	for (i = 0; i < 8; ++i)
	{
		if ((n & 0x01) != 0)//判断要发的位不为0,此时应该找1的时序图
		{
			DS18B20CLR;
			_nop_();
			_nop_();
			DS18B20SET;
			delay10us(3);			
		}
		else
		{
			DS18B20CLR;
			delay10us(5);
			DS18B20SET;
		}
		n >>= 1;
	}
}

从18b20接收数据

/********************
 *从18b20接收数据
 *一次发送一个char
 *从低位开始接收
 *返回接收到的数据
 ********************/
unsigned char readChar(void)//接收18b20的数据,每次接收一个字符
{
	unsigned char ret = 0;
	int i = 0;

	for (i = 0; i < 8; ++i)
	{
		DS18B20CLR;//拉低总线
		_nop_();//空指令,但是消耗了一个指令周期,1us
		_nop_();
		DS18B20SET;//释放总线
		_nop_();
		_nop_();
		_nop_();
		//采样:DS18B20TST表示P37是(1)否(0)为高电平,若接收到1,左移或运算可以将指定位置1(第i位为1,其余位为0)
		ret |= DS18B20TST << i;
		delay10us(5);
	}
	return ret;
}

获取温度(按照流程)

float getTemerature(void)
{
	unsigned char t1, t2;	
	int ret = 0;
//接收温度的总流程
	rest18b20();
	sendChar(0xCC);
	sendChar(0x44);
	delay10us(60000);
	rest18b20();
	sendChar(0xCC);
	sendChar(0xBE);

	t1 = readChar();//低位
	t2 = readChar();//高位
	//将字符型转换为浮点型
	ret = t2 << 8 | t1;
	return ret * 0.0625;	
//
}

 main.c

如何查看获取到的温度的数据呢?

这里采用串口调试查看(uart->send_buffer)

#include "ds18b20.h"
#include "uart.h"

int main(void)
{
	float f;
	char s[16];	

	uart_init();	

	while (1)
	{
		f = getTemerature();
		sprintf(s, "%f", f);
		send_buffer(s, strlen(s));
	}
		
	return 0;
}

MODBUS协议框架

帧:

起始字节地址码功能码数据长度数据码数据码校验码 结束码
0xAA0x01
01读温度
02读秒数
03设置秒数

02xxxxxx

0x0D

例如:

读温度:

上位机发出:AA 01 01 00 ** 0D        下位机回复:AA 81 01 04 xx xx xx xx ** 0D

                        0000 0001                                        1000 0001

                        第一位0代表上位机发给下位机,第一位1代表下位机发给上位机

读秒数:

上位机发出:AA 01 02 00 ** 0D        下位机回复:AA 81 02 xx xx ** 0D

                                                                               两个字节的数值,大端发送

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

STM32之FreeRTOS移植

1.FreeRTOS的移植过程是将系统需要的文件和代码进行移植和裁剪&#xff0c;其移植的主要过程为&#xff1a; &#xff08;1&#xff09;官网上下载FreeRTOS源码&#xff1a;https://www.freertos.org/ &#xff08;2&#xff09;移植文件夹&#xff0c;在portable文件夹中只需…

【数字化转型】上市公司智能制造词频统计数据(1991-2022年)

数据来源&#xff1a;上市公司年报 时间跨度&#xff1a;1991-2022年 数据范围&#xff1a;上市公司 数据指标&#xff1a; 版本一 智能制造 智能机器 智能生产 机器人 全自动 全机器 版本二 宏观政策 中国制造2025 工业4.0 互联网 范式特征 自动化 信息化 信息…

多态【C/C++复习版】

目录 一、多态是什么&#xff1f;如何实现&#xff1f; 二、 什么是重写&#xff1f;有什么特点&#xff1f; 三、什么是协变&#xff1f; 四、析构函数能实现多态吗&#xff1f;为什么要实现&#xff1f; 五、override和final的作用是什么&#xff1f; 六、 多态的原理是…

【vscode】在本地加载远端环境并开发

【vscode】在本地利用远程服务器显卡跑代码 写在最前面vscode&#xff1a;远程到本地1、安装ssh插件2、添加服务器连接配置3、连接服务器4. SSH配置5. 在ssh中安装python解释器 vscode基本操作 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光…

得物 Zookeeper SLA 也可以 99.99% | 得物技术

一、背景 ZooKeeper&#xff08;ZK&#xff09;是一个诞生于2007年的分布式应用程序协调服务。尽管出于一些特殊的历史原因&#xff0c;许多业务场景仍然不得不依赖它。比如&#xff0c;Kafka、任务调度等。特别是在 Flink 混合部署 ETCD 解耦 时&#xff0c;业务方曾要求绝对…

双数据库的安装

双MySQL的安装 【0】前言 ​ 本地已经安装过mysql5.1版本&#xff0c;应项目需求需要安装mysql5.7版本&#xff1b; ​ 官方网站下载对应版本&#xff1a;https://downloads.mysql.com/archives/community/ 【1】压缩包下载完成后解压至本地磁盘 【2】进入根目录下bin文件夹…

Element-UI 自定义-下拉框选择年份

1.实现效果 场景表达&#xff1a; 默认展示当年的年份&#xff0c;默认展示前7年的年份 2.实现思路 创建一个新的Vue组件。 使用<select>元素和v-for指令来渲染年份下拉列表。 使用v-model来绑定选中的年份值。 3.实现代码展示 <template><div><el-…

数据结构复习指导之线性表(线性表的顺序表示)

文章目录 线性表的顺序表示 1.顺序表的定义 1.1知识总览 1.2顺序表 1.3静态分配 1.4动态分配 1.5顺序表的特点 1.6知识回顾与重要考点 线性表的顺序表示 1.顺序表的定义 1.1知识总览 1.2顺序表 线性表的顺序存储又称顺序表。它是用一组地址连续的存储单元依次存储线性…

spring04:注解使用

spring04&#xff1a;注解使用 文章目录 spring04&#xff1a;注解使用前言&#xff1a;一、 Autowired Qualifier和 Resource 和 nullable1. Autowired 2. Resource &#xff1a;使用在类的属性上面&#xff08;和Autowired类似&#xff09;3. nullable 二、 Component 和 Re…

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE

JetBrains RubyMine 2024.1 发布 - 最智能的 Ruby 与 Rails IDE 请访问原文链接&#xff1a;JetBrains RubyMine 2024.1 (macOS, Linux, Windows) - 最智能的 Ruby 与 Rails IDE&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org…

ELK日志

​​​​​​​

JavaGUI编程

目录 GUI概念 Swing概念 组件 容器组件 窗口&#xff08;JFrame&#xff09; 代码 运行 面板&#xff08;JPanel&#xff09; 代码 运行 布局管理器 FlowLayout 代码 运行 BorderLayout 代码 运行 GridLayout 代码 运行 常用组件 标签(JLabel) 代码 运…

Vue列表渲染

一、Vue列表渲染 1.用 v-for 把一个数组对应为一组元素 我们可以用 v-for 指令基于一个数组来渲染一个列表。v-for 指令需要使用 item in items 形式的特殊语法&#xff0c;其中 items 是源数据数组&#xff0c;而 item 则是被迭代的数组元素的别名。 <ul id"exampl…

Agent调研--19类Agent框架对比

代理&#xff08;Agent&#xff09;指能自主感知环境并采取行动实现目标的智能体&#xff0c;即AI作为一个人或一个组织的代表&#xff0c;进行某种特定行为和交易&#xff0c;降低一个人或组织的工作复杂程度&#xff0c;减少工作量和沟通成本。 背景 目前&#xff0c;我们在探…

Qt 4.8中的ftp 功能在Qt 5.9.4 之前版本中的应用

很久以前也就是在Qt 4.8版本后&#xff0c; 如果想要用Qt ftp功能&#xff0c;是把Qt 4.8中的QFtp源码拉出来&#xff0c;编译、修改然后就能在Qt 其他版本使用。 但每一次升级Qt 版本&#xff0c;就要把Qt ftp 源码在相应的Qt 版本编译&#xff0c;修改。太麻烦了&#xff0c;…

C#下Httpclient post请求获取令牌

1.postman测试ok 2.C#代码 public static async Task<string> testGetToken(string URL, string param){string responseBody "eee";//using (var clientHandler new HttpClientHandler()){ var handler new HttpClientHandler();handler.ServerCertificat…

【JavaScript】对象 ② ( 对象使用 | 调用对象属性 | 调用对象方法 | 变量与属性区别 | 函数与方法区别 )

文章目录 一、对象使用1、使用字面量创建对象要点2、调用对象属性3、调用对象方法 二、变量与属性区别三、函数与方法区别 一、对象使用 1、使用字面量创建对象要点 使用字面量创建对象要点 : 在上一篇博客 【JavaScript】对象 ① ( 对象概念 | 对象使用场景 | 使用字面量创建对…

Android Studio开发学习(六)———TableLayout(表格布局)、FrameLayout(帧布局)

目录 前言 一、Tablelayout &#xff08;一&#xff09;Tablelayout的相关简介 &#xff08;二&#xff09;TableLayout使用方法 1. 当TableLayout下面写控件、则控件占据一行的大小。(自适应一行&#xff0c;不留空白) 2.多个组件占据一行&#xff0c;则配合TableRow实现…

Redis中的集群(六)

集群 ASK错误 在进行重新分片期间&#xff0c;源节点向目标节点迁移一个槽的过程中&#xff0c;可能会出现这样一种情况:属于被迁移槽的一部分键值对保存在源节点里面&#xff0c;而另一部分键值对则保存在目标节点里面。当客户端向源节点发送一个与数据库有关的命令&#xf…

【PHP程序设计(高阶版)】——PHP操作MySQL教程

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…