day07 51单片机-18B20温度检测

18B20温度检测

1.1 需求描述

本案例讲解如何从18B20传感器获取温度信息并显示在LCD上。

1.2 硬件设计

1.2.1 硬件原理图

在这里插入图片描述

1.2.3 18B20工作原理

可以看到18B20有两根引脚负责供电,一根引脚负责数据交换。18B20就是通过数据线和单片机进行数据交换的。

1)18B20工作时序

在这里插入图片描述

2)初始化信号

在这里插入图片描述

#define DQ P44

/**
 * @brief 初始化方法
 *
 * @return 1代表存在,0代表不存在
 */
static bit Int_DS18B20_Init()
{
    bit result;

    // 主机拉低
    DQ = 0;
    Delay60us(8);

    // 主机释放DQ
    DQ = 1;
    Delay60us(1);

    // 查看18B20状态
    result = ~DQ;
    Delay60us(7);

    return result;
}

3)写数据时序

写‘1’时序

在这里插入图片描述

写‘0’时序

在这里插入图片描述

写字节

在这里插入图片描述

让18B20测量温度,并将温度保存在RAM中。

根据说明书第五节“温度测量”,我们需要向18B20发送功能指令0x44,可以触发温度测量动作,根据上面的事件序列,我们可以得知,这一步的通信流程如下:

发送初始化信号。

发送跳过ROM命令的指令(因为我们不需要ROM命令),查询ROM命令列表可得知,我们需要向18B20发送0xCC。

发送温度测量指令,查询功能命令列表可得知,我们需要向18B20发送0x44。

4)读数据时序

在这里插入图片描述

在这里插入图片描述

5)从18B20中读取刚刚测量的温度。

查询说明书的命令指令可得知,如果我们想读取18B20寄存器,需要向18B20发送功能指令0xBE,再从18B20中连续接收9字节数据。这9字节数据中,只有前两个字节是我们需要的温度数据。所以我们在接收两个字节后,需要再发送一次复位(初始化)信号,打断接下来的数据传输。整个通信流程如下:

 发送初始化信号。

 发送跳过ROM命令的指令0xCC。

 发送读取寄存器的命令0xBE。

 接收两个字节。

 发送初始化信号打断传输。

1.3软件设计

1)Util.h

在Util.h中加入新的延时函数声明。

/**
 * @brief 延时10us
 *
 */
void Delay10us();

/**
 * @brief 延时50us
 *
 */
void Delay50us();

/**
 * @brief 延时60us
 *
 * @param n 倍数
 */
void Delay60us(u8 n);

2)Util.c

void Delay60us(u8 n) //@11.0592MHz
{
    unsigned char data i;

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

void Delay10us() //@11.0592MHz
{
    unsigned char data i;

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

void Delay50us() //@11.0592MHz
{
    unsigned char data i;

    _nop_();
    i = 20;
    while (--i)
        ;
}

3)Int_DS18B20.h

在Int目录下创建Int_DS18B20.h,写入以下内容。

#ifndef __INT_DS18B20_H__
#define __INT_DS18B20_H__
#include <STC89C5xRC.H>
#include "Util.h"

/**
 * @brief 获取温度
 *
 * @return u8
 */
u8 Int_DS18B20_GetTemperature();

#endif

4)Int_DS18B20.c

在Int目录下创建Int_DS18B20.c,写入以下内容。

#include "Int_DS18B20.h"

#define DQ P44

/**
 * @brief 初始化方法
 *
 * @return 1代表存在,0代表不存在
 */
static bit Int_DS18B20_Init()
{
    bit result;

    // 主机拉低
    DQ = 0;
    Delay60us(8);

    // 主机释放DQ
    DQ = 1;
    Delay60us(1);

    // 查看18B20状态
    result = ~DQ;
    Delay60us(7);

    return result;
}

/**
 * @brief 向18B20发送字节
 *
 * @param dat 要发送的字节
 */
static void Int_DS18B20_SendByte(u8 dat)
{
    u8 i;

    for (i = 0; i < 8; i++)
    {
        // 首先拉低总线
        DQ = 0;
        // 延时10us
        Delay10us();
        // 根据要发送的bit决定是高是低
        DQ = dat & 0x1;
        dat >>= 1;
        // 延时50us
        Delay50us();
        // 释放总线
        DQ = 1;
    }
}

/**
 * @brief 从18B20读取字节
 *
 * @return u8 读取的字节
 */
static u8 Int_DS18B20_RecvByte()
{
    u8 i, result = 0;

    // 8个bit
    for (i = 0; i < 8; i++)
    {
        // 主机初始化读时段
        DQ = 0;
        result >>= 1;
        DQ = 1;
        // 等待10us
        Delay10us();

        // 采样
        if (DQ == 1)
        {
            result |= 0x80;
        }
        // 等待整个读时段过去
        Delay50us();
    }

    return result;
}

u8 Int_DS18B20_GetTemperature()
{
    u8 ls_byte, ms_byte;

    // 初始化
    Int_DS18B20_Init();
    // 发送跳过ROM指令的指令(0xCC)
    Int_DS18B20_SendByte(0xCC);
    // 发送温度转换指令(0x44)
    Int_DS18B20_SendByte(0x44);

    // 初始化
    Int_DS18B20_Init();
    // 发送0xCC
    Int_DS18B20_SendByte(0xCC);
    // 发送读取暂存器指令(0xBE)
    Int_DS18B20_SendByte(0xBE);
    // 收字节,总共9个,只要两个
    ls_byte = Int_DS18B20_RecvByte();
    ms_byte = Int_DS18B20_RecvByte();
    // 初始化
    Int_DS18B20_Init();

    // 将读取到的两字节转化成温度返回
    ls_byte >>= 4;
    ms_byte <<= 4;

    return ms_byte | ls_byte;
}

5)Main.c

在Main.c文件中,写入以下内容。

#include <STC89C5xRC.H>
#include "Int_LCD1602.h"
#include "Int_DS18B20.h"

void main()
{
    Int_LCD1602_Init();

    while (1)
    {
        Int_LCD1602_ShowNum(0, 0, Int_DS18B20_GetTemperature());
        Delay1ms(500);
    }
}

s_byte | ls_byte;
}


**5)Main.c**

在Main.c文件中,写入以下内容。

```c
#include <STC89C5xRC.H>
#include "Int_LCD1602.h"
#include "Int_DS18B20.h"

void main()
{
    Int_LCD1602_Init();

    while (1)
    {
        Int_LCD1602_ShowNum(0, 0, Int_DS18B20_GetTemperature());
        Delay1ms(500);
    }
}

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

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

相关文章

前端项目中使用插件prettier/jscodeshift/json-stringify-pretty-compact格式化代码或json数据

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、json代码格式化-选型二、json-stringify-pretty-compact简单试用三、prettier在前端使用四、查看prettier支持的语言和插件五、使用prettier格式化vue代码最终效果如图&#xff1a; ![在这里插入图片描述](https://im…

【ruoyi-vue】登录解析(后端)

调试登录接口 进入实现类可以有 验证码校验 登录前置校验 用户验证 验证码校验 通过uuid获取redis 中存储的验证码信息&#xff0c;获取后对用户填写的验证码数据进行校验比对 用户验证 1.进入控制器的 /login 方法 2.进入security账号鉴权功能&#xff0c;经过jar内的流…

python逆向基础流程(纯小白教程)

一&#xff0c;例题链接 NSSCTF | 在线CTF平台 二&#xff0c;文件特征 使用工具查看文件信息&#xff0c;发现是pyinsatller打包的exe文件&#xff0c;如果硬用ida分析成汇编或c语言根本摸清楚程序的逻辑&#xff0c;所以思路是反编译成py文件直接分析python代码 三&#xf…

【论文推导】基于有功阻尼的转速环PI参数整定分析

前言 在学习电机控制的路上&#xff0c;PMSM的PI电流控制是不可避免的算法之一&#xff0c;其核心在于内环电流环、外环转速环的设置&#xff0c;来保证转速可调且稳定&#xff0c;并且保证较好的动态性能。整个算法仿真在《现代永磁同步电机控制原理及matlab仿真》中已详细给出…

VUE项目使用.env配置多种环境以及如何加载环境

第一步&#xff0c;创建多个环境配置文件 Vue CLI 项目默认使用 .env 文件来定义环境变量。你可以通过创建不同的 .env 文件来为不同环境设置不同的环境变量&#xff0c;例如&#xff1a; .env —— 所有模式共用.env.local —— 所有模式共用&#xff0c;但不会被 git 提交&…

Clickhouse离线安装教程

https://blog.51cto.com/u_15060531/4174350 1. 前置 1.1 检查服务器架构 服务器&#xff1a;Centos7.X 需要确保是否x86_64处理器构架、Linux并且支持SSE 4.2指令集 grep -q sse4_2 /proc/cpuinfo && echo "SSE 4.2 supported" || echo "SSE 4.2 …

不墨迹,向媒体投稿不讲攻略,直接上方法

作为一名单位信息宣传员,我曾深陷于向媒体投稿的泥沼之中,饱尝了费时费力、审核严苛、出稿缓慢的苦涩,承受着领导急切期盼与自我压力交织的煎熬。然而,当我有幸接触到智慧软文发布系统,这一切困境如同阴霾散去,取而代之的是便捷流畅的投稿流程,以及领导满意、团队轻松的工作氛围…

Java Swing游戏开发学习24

内容来自RyiSnow视频讲解 这一节讲的是Scrolling Message, Leveling Up, Damage Calculation滚动消息&#xff0c;升级&#xff0c;伤害计算。 伤害计算 玩家与怪的战斗&#xff0c;玩家对怪的伤害值为攻击值减去怪的防御值。 int damage attack - gp.monster[i].defense; …

队列的实现(c语言实现)

队列的定义 队列&#xff08;Queue&#xff09;是一种特殊的线性数据结构&#xff0c;它遵循先进先出&#xff08;FIFO&#xff0c;First In First Out&#xff09;的原则。这意味着最早被添加到队列中的元素将是最先被移除的元素。队列的主要操作包括入队&#xff08;enqueue…

接口自动化测试框架建设的经验与教训

为什么选择这个话题&#xff1f; 一是发现很多“点工”在转型迷茫期都会问一些自动化测试相关的问题&#xff0c;可以说自动化测试是“点工”升级的必经之路&#xff1b;二是Google一下接口自动化测试&#xff0c;你会发现很多自动化测试框架相关的文章&#xff0c;但是大部分…

Nodejs--异步编程

异步编程 函数式编程 高阶函数 在通常的语言中&#xff0c;函数的参数只接受基本的数据类型或者是对象引用&#xff0c;返回值只能是基本数据类型和对象引用。 function foo(x) {return x }高阶函数是把函数作为参数&#xff0c;将函数作为返回值的函数 function foo(x) {…

Oceanbase体验之(二)Oceanbase集群的搭建(社区版4.2.2)

资源规划 3台observer CPU:4C及以上 内存&#xff1a;32G及以上 硬盘操作系统500G 存储盘1T及以上 虚拟机可以直接划分&#xff0c;物理机需要提前规划好资源 一、上传oceanbase安装包 登录ocp选择软件包管理 上传Oceanbase软件包&#xff08;软件包获取路径 官网免费下载社…

JavaWeb--04YApi,Vue-cli脚手架Node.js环境搭建,创建第一个Vue项目

04 1 Yapi2 Vue-cli脚手架Node.js环境搭建配置npm的全局安装路径 3 创建项目&#xff08;这个看下一篇文章吧&#xff09; 1 Yapi 前后端分离中的重要枢纽"接口文档",以下一款为Yapi的接口文档 介绍&#xff1a;YApi 是高效、易用、功能强大的 api 管理平台&#…

Hive主要介绍

Hive介绍 hive是基于 Hadoop平台操作 HDFS 文件的插件工具 可以将结构化的数据文件映射为一张数据库表 可以将 HQL 语句转换为 MapReduce 程序 1.hive 是由驱动器组成&#xff0c;驱动器主要由4个组件组成&#xff08;解析器、编译器、优化器、执行器&#xff09; 2.hive本身不…

递归排列枚举(c++)

全部排列问题 输入 n 输出 1…n 个数的全部排列。全部排列中&#xff0c;数字可以重复 。 例如 输入 3 输出全部排列的结果如下&#xff1a;111、112、113、121、122、123、131、132、133、211、212、213、221、222、223、231、232、233、311、312、313、321、322、323、33…

4.18.2 EfficientViT:具有级联组注意力的内存高效Vision Transformer

现有Transformer模型的速度通常受到内存低效操作的限制&#xff0c;尤其是MHSA&#xff08;多头自注意力&#xff09;中的张量整形和逐元素函数。 设计了一种具有三明治布局的新构建块&#xff0c;即在高效FFN&#xff08;前馈&#xff09;层之间使用单个内存绑定的MHSA&#x…

浅谈数据模型

1&#xff1a;事实表和维表的概述 前言&#xff1a;数据仓库是一种用于存储和管理大量数据的技术。其中&#xff0c;事实表和维表是数据仓库中的两个重要概念&#xff0c;首先了解一下事实表和维度表 1.事实表&#xff1a;是指用于存储测量“事实数据”的表&#xff0c;事实数…

Unity 异常 bug

OverlapBoxNonAlloc 使用bug 环境&#xff1a; Unity2021.3.15 在测试场景中使用 OverlapBoxNonAlloc 测试检测没有问题 但是到了真实应用场景&#xff0c;使用 OverlapBoxNonAlloc 检测移动中的小怪 小怪碰撞体为&#xff1a;带有 Rigidbody 的Circle Collider 2D 就会出现异…

Java虚拟机(jvm)常见问题总结

1.电脑怎样认识我们编写的Java代码 首先先了解电脑是二进制的系统&#xff0c;他只认识 01010101比如我们经常要编写 HelloWord.java 电脑是怎么认识运行的HelloWord.java是我们程序员编写的&#xff0c;我们人可以认识&#xff0c;但是电脑不认识 Java文件编译的过程 1. 程…

代码随想录(番外)图论3|1020. 飞地的数量|130. 被围绕的区域

代码随想录&#xff08;番外&#xff09;图论3|1020. 飞地的数量|130. 被围绕的区域 1020. 飞地的数量 class Solution { public:int dir[4][2]{0,1,1,0,0,-1,-1,0};int count;void dfs(vector<vector<int>>& grid,int x,int y){grid[x][y]0;count;for(int i…