使用51单片机模拟单总线时序与温度传感器DS18B20通信

目录

一、DS18B20单总线数字温度传感器

原件介绍

工作原理

引脚功能 

单总线时序

二、任务实现 

proteus仿真电路原理图

代码示例

仿真结果


  本章内容将引进DS18B20单总线数字温度传感器,并使用51单片机对实践内容进行软件仿真和实物操作,需要的相关软件如KEIL、Proteus及其相关操作可查看往期博客或者查看其他博客进行下载、学习。

实践内容:

使用51单片机的一个 IO 口模拟单总线时序与温度传感器DS18B20通信,将检测的环境温度读取出来。

一、DS18B20单总线数字温度传感器

原件介绍

DS18B20是一种数字温度传感器,采用单总线接口进行通信。它可以测量环境温度,并将其转换为数字信号输出。DS18B20具有高精度、数字输出、工作电压范围广、低功耗等特点,常用于各种温度监测应用中,如室内温度监控、工业自动化等。由于采用单总线接口,它可以方便地与微控制器等设备进行通信,并且可以通过一条总线连接多个DS18B20传感器,简化了布线结构。

DS18B20传感器有几种不同的封装类型,包括TO-92、TO-220、TO-263等,适用于不同的应用场景和安装需求。此外,DS18B20传感器还有一些衍生型号,如DS18S20、DS1822等,它们在功能和特性上与DS18B20类似,但可能有一些微小的差异。

工作原理

利用温度对其内部芯片的电特性产生微小的电压变化,这一变化被转换为数字信号。它采用了一种称为单总线协议的通信方式,即通过一个总线进行数据传输和通信。在通信过程中,主控设备发送指令给DS18B20传感器,传感器接收指令并执行相应的操作,如测量温度,并将结果通过总线返回给主控设备。由于采用单总线接口,DS18B20传感器可以通过一根总线连接到主控设备,简化了连接结构,并且可以方便地与微控制器等设备进行通信。

相关知识的详细讲解可以参考以下博客:

DB18B20的时序图讲解

https://blog.csdn.net/qzs_13933908434/article/details/8680623

DS18B20 时序完全解读

https://blog.csdn.net/farsight2009/article/details/51122678

DS18B20时序分析详细步骤

https://shequ.stmicroelectronics.cn/thread-635490-1-1.html

 

引脚功能 

引脚1为地(GND)引脚,连接到电路的地;

引脚2为数据引脚(DQ),用于与单总线通信;

引脚3为电源引脚(VCC),连接到电路的电源。

单总线时序

单总线时序是一种用于串行通信的协议,通常用于单线(单总线)连接的设备之间进行通信。它允许多个设备通过共享单个数据线进行通信,从而简化了硬件连接。单总线时序具有以下特点:

单线连接:所有设备都连接到同一根数据线上,通过在线路上发送不同的电平信号来表示不同的数据或控制信息。

异步通信:单总线通常是异步通信的,即设备之间的通信不需要共享时钟信号。每个设备在适当的时机发送和接收数据,而不需要与其他设备同步。

时序规范:单总线时序规定了数据和控制信号的传输时机和格式。这包括起始位、数据位、校验位、停止位等。

主从结构:在单总线通信中通常存在主设备和从设备的概念。主设备负责发起通信请求和控制通信的时序,而从设备则响应主设备的请求并提供所需的数据。

冲突检测与解决:由于所有设备共享同一条数据线,可能会出现冲突情况。单总线协议通常包括机制来检测和解决冲突,以确保数据的正确传输。

错误检测与校正:单总线协议通常也包括一些机制来检测和校正数据传输过程中的错误,例如使用校验位或CRC校验等。

它的优点是简化了硬件连接,但也存在一些局限性,例如通信速率较低、抗干扰能力相对较弱等。

二、任务实现 

proteus仿真电路原理图

代码示例

#include "reg51.h"      
#include "intrins.h"    
#define uchar unsigned char   
#define uint unsigned int      
#define out P0          
sbit smg1=out^4;        
sbit smg2=out^5;        
sbit DQ=P3^7;           
void delay5(uchar);     // 延时函数
void init_ds18b20(void);    //DS18B20初始化
uchar readbyte(void);       // 读取一个字节数据
void writebyte(uchar);      // 写入一个字节数据
uchar retemp(void);         //读取温度函数
 
void main(void)
{
    uchar i,temp;
    delay5(1000);       // 延时等待DS18B20初始化
    while(1)
    {
        temp=retemp();  // 读取温度值
        for(i=0;i<10;i++)   // 循环显示温度值
        {
            out=(temp/10)&0x0f; // 写入P0端口(十位)
            smg1=0;         // smg1置0,控制第一个数码管
            smg2=1;         // smg2置1,控制第二个数码管
            delay5(1000);   
            out=(temp%10)&0x0f; // 写入P0端口(个位)
            smg1=1;         // smg1置1,控制第一个数码管
            smg2=0;         // smg2置0,控制第二个数码管
            delay5(1000);   
        }
    }
}
 
 
void delay5(uchar n)
{
    do
    {
        _nop_();    // 空,延时
        _nop_();
        _nop_();
        n--;
    }
    while(n);
}
 
void init_ds18b20(void)
{
    uchar x=0; 
    DQ =0;      
    delay5(120);    
    DQ =1;      
    delay5(16);     
    delay5(80);    
}
 
uchar readbyte(void)
{
    uchar i=0;
    uchar date=0;
    for (i=8;i>0;i--)
    {
        DQ =0;    
        delay5(1);  
        DQ =1;      
        date>>=1;   
        if(DQ)      
            date|=0x80; 
        delay5(11); 
    }
    return(date);   // 返回读取的数据
}

void writebyte(uchar dat)
{
    uchar i=0;
    for(i=8;i>0;i--)
    {
        DQ =0;      
        DQ =dat&0x01;   // 写入数据
        delay5(12); 
        DQ = 1;     
        dat>>=1;    
        delay5(5);  
    }
}
 
uchar retemp(void)
{
    uchar a,b,tt;
    uint t;
    init_ds18b20(); // 初始化DS18B20
    writebyte(0xCC);    
    writebyte(0x44);    
    init_ds18b20(); 
    writebyte(0xCC);    
    writebyte(0xBE);   
    a=readbyte();  
    b=readbyte();  
    t=b;    /
    t<<=8;
    t=t|a;  
    tt=t*0.0625;   
    return(tt); // 返回温度值
}

仿真结果

  • 16
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
DS18B20是一款数字温度传感器,可以通过单总线接口与51单片机进行通讯。 使用DS18B20需要注意以下几点: 1. DS18B20的引脚包括VCC、GND和DQ(数据引脚)。其中,VCC接5V电源,GND接地,DQ连接单片机的IO口。 2. DS18B20采用的是单总线通讯协议,因此需要在程序中实现相应的通讯函数。 3. DS18B20的温度数据是以16位二进制补码形式存储的,需要将其转换为实际温度值进行使用。 下面是一个简单的示例代码,用于读取DS18B20的温度数据: ```c #include <reg52.h> sbit DQ = P1^4; // DQ连接单片机的P1.4口 unsigned int temp; // 保存温度数据的变量 void delay(unsigned int t) // 延时函数 { while(t--); } void init_ds18b20() // 初始化DS18B20 { DQ = 1; // 置高电平,准备发送复位脉冲 delay(500); // 延时500us DQ = 0; // 发送复位脉冲 delay(80); // 延时80us DQ = 1; // 释放总线 delay(500); // 等待DS18B20回应 } void write_ds18b20(unsigned char dat) // 向DS18B20写入一个字节 { unsigned char i; for(i=0; i<8; i++) { DQ = 0; // 拉低总线 DQ = dat & 0x01; // 发送数据位 delay(5); // 等待时序 DQ = 1; // 恢复总线 dat >>= 1; // 准备发送下一位数据 } } unsigned char read_ds18b20() // 从DS18B20读取一个字节 { unsigned char i, dat = 0; for(i=0; i<8; i++) { DQ = 0; // 拉低总线 dat >>= 1; // 准备接收数据位 if(DQ) dat |= 0x80; // 如果总线为高电平,接收数据位为1 delay(5); // 等待时序 DQ = 1; // 恢复总线 } return dat; } void get_temp() // 获取温度数据 { init_ds18b20(); // 初始化DS18B20 write_ds18b20(0xcc); // 跳过ROM操作 write_ds18b20(0x44); // 启动温度转换 delay(100); // 等待转换完成 init_ds18b20(); // 再次初始化DS18B20 write_ds18b20(0xcc); // 跳过ROM操作 write_ds18b20(0xbe); // 发送读取温度命令 temp = read_ds18b20(); // 读取温度低字节 temp |= read_ds18b20() << 8; // 读取温度高字节 } void main() { while(1) { get_temp(); // 获取温度数据 temp >>= 4; // 将温度数据右移4位,去掉小数部分 // 进行温度转换,具体公式见DS18B20的数据手册 temp = (temp * 625) / 100; // 将温度数据输出到LED灯 P2 = temp; delay(1000); // 延时1秒 } } ``` 需要注意的是,以上代码仅供参考,实际使用时需要根据具体情况进行修改。同时,DS18B20的通讯协议比较复杂,需要仔细阅读其数据手册并进行实验验证。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值