51单片机——18B20温度检测、DS1302时钟

18B20概述

  1. 18B20是一种常用的数字温度传感器,广泛应用于环境监测、工业控制、家居自动化和设备温度监控等领域。

  2. 18B20引脚:8B20采用1-wire总线进行通信,数据的输入输出仅靠一个DQ引脚完成。           

  3. 工作原理:                                                      

1-Wire通信协议

  1. 1-Wire协议是一种半双工、串行通信协议,主要用于与各种低成本传感器和存储设备进行数据交换。同I2C协议类似,1-Wire也采用主从架构,一个主设备可以连接多个从设备。
  2. 由于1-wire总线也要求各设备以开漏(Open-Drain)模式接入,因此DQ信号线也要使用上拉电阻。(只有低电平和高阻态两种状态)。

  3. 另外,在1-Wire总线中,每个从设备都有一个唯一的64位地址,用于设备识别和通信,这64位地址是由制造商在生产设备时烧录进去的,不可更改。       

初始化

  1. 1-Wire规定,每次通信主设备都要先发送一个复位脉冲,从设备接收到该脉冲后,会进行复位(例如:从低功耗状态恢复到正常通信状态),然后回复一个存在脉冲,主设备可根据该存在脉冲获知从设备的健康状态。   

写操作

读操作

18B20通信

18B20规定,主设备与其的每次通信,都要遵循以下流程:

  1. 初始化:主设备发送复位脉冲,从设备回复存在脉冲。
  2. 发送ROM命令:
    1. 每个18B20都有一个唯一个的64位序列号,该序列号存储于其内部的一个64位的ROM中。
    2. 搜索ROM命令[0xF0]:识别和列出所有连接在总线上的18B20设备。
    3. 读取ROM命令[0x33]:在单设备连接时,主机可以使用此命令直接读取设备的ROM代码。
    4. 匹配ROM命令[0x55]:该命令后边会跟随一个特定的64位ROM代码,用以选择总线上特定的设备进行通信。
    5. 跳过ROM命令[0xCC]:在单设备环境中,跳过ROM步骤,直接与设备通信。
  3. 发送功能命令:功能命令用于控制18B20的具体操作,向前文提到的测温命令、读取温度命令等均属于功能命令。
    1. 温度转换[44h]:该命令的作用是启动温度测量并将温度数据转换为数字格式。接收到该命令后,18B20会读取其内部的温度传感元件,将测量到的温度值转换为数字信号,并存储在内部的暂存器中,以便后续读取。完成上述操作后,18B20会自动恢复到低功耗状态。
    2. 读取暂存寄存器[BFh]:该命令用于读取18B20暂存器中存储的值。该命令会返回暂存器中的全部数据,共9个字节,温度值保存在前两个字节,所以一般情况下,只需接收前两个字节即可。 
      1. 18B20测温的精度是可选的,有12位(bit0-bit11)、11(bit1-bit11)位、10位(bit2-bit11)和9位(bit3-bit11)可选,默认12位
      2. 上述两个字节中保存的是温度值的补码。
  4. 上述命令或者数据的读写操作均为低位优先。

原理图:

代码实现

// Dri_1Wire.h
#ifndef __DRI_1WIRE_H__
#define __DRI_1WIRE_H__
#include "Com_Util.h"
/**
 * @brief 初始化
 * 
 * @return bit 
 */
bit Dri_1Wire_Init();
/**
 * @brief 写入函数
 * 
 * @param byte 写入字节
 */
void Dri_1Wire_WriteByte(u8 byte);
/**
 * @brief 读取字节函数
 * 
 * @return u8 返回读取到的字节数据
 */
u8 Dri_1Wire_ReadByte();

#endif /* __DRI_1WIRE_H__ */

// Dri_1Wire.c
#include "Dri_1Wire.h"
#include <STC89C5xRC.H>
#define DQ P44

bit Dri_1Wire_Init()
{
    bit result;
    DQ = 0;
    Com_Util_Delay480us();
    DQ = 1;
    Com_Util_Delay60us();
    result = ~DQ;
    Com_Util_Delay420us();
    return result;
}

void Dri_1Wire_WriteByte(u8 byte)
{
    u8 i;
    for (i = 0; i < 8; i++) {
        DQ = 0;
        DQ = byte & 0x01;
        byte >>= 1;
        Com_Util_Delay60us();
        DQ = 1;
    }
}

u8 Dri_1Wire_ReadByte()
{
    u8 byte = 0x00;
    u8 i;
    for (i = 0; i < 8; i++) {
        DQ = 0;
        DQ = 1;
        Com_Util_Delay10us();
        byte >>= 1;
        if (DQ == 1) {
            byte |= 0x80;
        }
        Com_Util_Delay50us();
    }
    return byte;
}

// DS18B20.h
#ifndef __INT_DS18B20_H__
#define __INT_DS18B20_H__
/**
 * @brief 读取温度
 * 
 * @return char 返回当前温度值
 */
char Int_DS18B20_GetTemperature();

#endif /* __INT_DS18B20_H__ */
// DS18B20.C
#include "Int_DS18B20.h"
#include "Dri_1Wire.h"

char Int_DS18B20_GetTemperature()
{
    u8 ls_byte;
    u8 ms_byte;
    Dri_1Wire_Init();
    // 跳过ROM命令
    Dri_1Wire_WriteByte(0xCC);
    // 温度转换
    Dri_1Wire_WriteByte(0x44);

    Dri_1Wire_Init();
    Dri_1Wire_WriteByte(0xCC);
    // 读取暂存寄存器
    Dri_1Wire_WriteByte(0xBE);
    ls_byte = Dri_1Wire_ReadByte();
    ms_byte = Dri_1Wire_ReadByte();

    return (ls_byte >> 4) | (ms_byte << 4);
}


// main.c
#include "Int_OLED.h"
#include "Int_DS18B20.h"
#include "Com_Util.h"
void main()
{
    Int_OLED_Init();
    Int_OLED_Clear();
    while (1) {
        Int_OLED_ShowNum(0, 0, Int_DS18B20_GetTemperature());
        Com_Util_Delay1ms(500);
    }
}



DS1302时钟

DS1302是一个低功耗、实时时钟(RTC)芯片:                                 

DS1302概述

  1.  引脚功能:        
  2. 工作原理    

     

通讯协议

读操作

写操作

常用寄存器:

注意:DS1302内部有一个写保护寄存器,在向DS1302写入数据前需要先关闭写保护,写完再开启写保护。

需求:将时间信息和温度信息实时地显示在OLED上。

原理图:

代码实现

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值