zoukankan      html  css  js  c++  java
  • 51单片机 | 1-Wire总线及应用实例

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

    1-Wire总线

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    • 只使用一根导线(地址线、数据线、控制线合一)
    • 可以传输时钟和数据
    • 双向传输
    • 信号线上可挂许多测控对象,电源也由这根信号线提供
    • 适用于单Master,多个Slave。
      • 当只有一个Slave时,系统按照单节点系统操作
      • 当有多个Slave时,系统按照多节点系统操作
    • 优点:
      • 综合性:
        • 传感器、控制器、输入/输出设备均可按1-Wire协议接入网络
      • 简捷性:
        • 1-Wire单总线的设置和安装只需一条普通三芯电线连接至各从机接入点
        • 当系统需要增加Slave时,只需要从该总线拉出延长线即可
      • 可靠性:
        • 每个从机均有绝对唯一的地址码
        • 数据传输均采用CRC校验码
        • 1-Wire单总线上传输的是数字信号
    • 缺点:传输速率较低

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

    DS18B20

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    • 改进型智能数字温度传感器
    • 只需要一根导线就能读出被测温度,并实现双向通信
    • 根据需求实现9-12位数字值的读数方式,精度分别为0.5,0.25,0.125,0.0625
    • 适应电压范围宽,电压范围为3.0-5.5V,寄生电源方式下可由数据线供电
    • 支持多点组网功能,多个DS18B20通过并联方式,实现多点组网测温
    • 不需要任何外围元件,传感元件及转换电路已经集成了
    • 温度范围-55~+125℃,在-10~+85℃时,精度为±0.5℃
    • 转换速度较快。在9位分辨率时,最多在93.75ms内把温度转换为数字,12位分辨率时最多在750ms内把温度值转换为数字
    • 测试结果直接输出数字温度信号,以一条总线串行传送给CPU,同时可传送CRC校验码,具有极强的抗干扰纠错能力
    • 负压特性,当电源极性接反时,芯片不会因发热而烧毁,但也无法正常工作

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    三种封装形式及引脚说明

    • 当信号线DQ为高电平时,DQ为芯片供电,并且内部电容器储存电能
    • 当信号线DQ为低电平时,内部电容器为芯片供电,直至下一个高电平到来重新充电

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    内部结构:

    • 64位ROM
      • 厂家激光刻录的一个64位二进制ROM代码,是该芯片的标号

    8位循环冗余检验

    48位序列号

    8位分类编号(10H

    MSB ... LSB

    MSB ... LSB

    MSB ... LSB

    • 8位分类编号:10H,是DS18B20的分类号
    • 温度传感器
      • 温度范围-55~+125℃。9-12位分辨率,转换精度分别为0.5,0.25,0.125,0.0625
      • 出厂时默认为16位转换精度
      • 当接收到温度转换命令(44H)后开始转换,转换完成后的温度以16位带符号扩展的二进制补码形式表示。存储在高速缓存器RAM的第0、1字节中,二进制数的前5位为符号位
        • 如果温度>0,则该5位为0,只要将测到的数值乘上0.0625即可得到实际温度。
        • 如果温度<0,则该5位为1,测到的数值需要取反+1再乘上0.0625。
    • 高速缓存器:包含以下两个组件
      • 高速暂存器RAM:连续8字节的存储器
        • 前2字节是测得的温度信息,第1字节存放温度的低8位,第2字节存放温度的高8位
        • 第3/4/5字节分别是高温触发器、低温触发器、配置寄存器的易失性复制
        • 前5字节的内容在每次上电复位时被刷新
        • 第6/7/8字节用于暂时保留为1
      • 非易失性可电擦除EEPROM
    • 配置寄存器
      • 用于确定温度值的数字转换分辨率,按此寄存器的分辨率将温度转换为相应精度的数值,是高速缓存器的第5个字节
      • 该字节定义:

    TM

    R0

    R1

    1

    1

    1

    1

    1

    • TM是测试模式位,用于设置DS18B20在工作模式还是测试模式。工作模式时该位为0,用户不必改动。R1和R0用来设置分辨率,其余5位均固定为1。
    • 分辨率设置:

    R1

    R0

    分辨率

    最大转换时间/ms

    0

    0

    9

    93.75

    0

    1

    10

    187.5

    1

    0

    11

    375

    1

    1

    12

    750

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    测温工作原理:由以下部分组成

    • 斜率累加器:
      • 用于补偿和修正测温过程中的非线性
      • 其输出用于修正减法计数器的预置值
    • 温度系数振荡器:
      • 用于产生减法计数器脉冲信号
      • 低温度系数振荡器受温度的影响很小,用于产生固定频率的脉冲信号送给减法计数器1
      • 高温度系数振荡器受温度的影响较大,随温度的变化,其振荡频率明显改变,产生的信号作为减少计数器2的输入脉冲
    • 减法计数器
      • 减法计数器1对低温度系数振荡器产生的脉冲信号进行减法计数,当减法计数器1的预置值减到0时,温度寄存器的值将+1。
      • 之后,减法计数器1的预置将重新被装入。减法计数器1重新开始对低温度系数振荡器产生的脉冲信号进行计数,循环操作直到减法计数器2计数减到0,才会停止温度寄存器的值的累加。此时,温度寄存器中的数值即为所测温度。
      • 只要计数门未关闭就重复上述过程,直至温度寄存器的值达到被测温度值。
    • 温度寄存器
      • 暂存温度数值
    • 计数门
      • 当计数门打开时,DS18B20就对低温系数震荡器产生的时钟脉冲进行计数,从而完成温度测量。
      • 开启时间由高温度系数振荡器决定。
      • 每次测量前,首先将-55℃所对应的基数分别置入减法计数器1和高温寄存器中,减法计数器1和温度寄存器被预置在-55℃所对应的一个基数值。

    p.s. 每个芯片的信息交换是分时完成的,均有严格的读/写是时序要求,系统对DS18B20的操作协议为:

    初始化DS18B20(发复位脉冲)→ ROM功能命令 发存储器操作命令 处理数据

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    ROM命令

    操作

    命令代码

    详细说明

    ROM

    33H

    允许主设备读出64位二进制ROM代码

    只适用于总线上存在单只DS18B20

    匹配ROM

    55H

    若总线上有多个Slave,使用该命令可以选中某一指定的DS18B20,即只有与64位二进制ROM代码完成匹配的DS18B20才能响应其操作

    跳过ROM

    CCH

    启动所有DS18B20转换之前或系统只有一个DS18B20时,该命令允许Master不提供64位二进制ROM代码就使用存储器操作命令

    搜索ROM

    F0H

    确定系统中的Slave个数及其ROM代码

    报警搜索ROM

    ECH

    鉴别和定位系统中超出程序设定的报警温度值

    写暂存器

    4EH

    允许MasterDS18B20的暂存器写入2个字节的数据

    可以在任何时刻发出复位命令中止数据写入

    读暂存器

    BEH

    允许主设备读取暂存器的内容,从第1个字节开始,直到CRC读完第9个字节。也可以在任何时刻发出复位命令中止数据的读取操作

    复制暂存器

    48H

    将高温触发器和低温触发器中的字节复制到非易失性EEPROM

    若主机在该命令之后又发出读操作,而DS18B20正忙于复制过程时,DS18B20会输出一个0,复制结束时DS18B20会发出一个1

    如果使用寄生电源,则主设备发出该命令之后,立即发出强上拉并至少保持10ms以上时间。

    温度转换

    44H

    启动一次温度转换

    若主机在该命令之后又发出其他操作,DS18B20正忙于温度转换,则输出一个0,转换结束则输出一个1,

    若使用寄生电源,则Master发出该命令之后,立即发出强上拉并至少保持500ms以上的时间。

    复制回暂存器

    B8H

    将高温触发器和低温触发器的字节从EEPROM复制回暂存器中。

    若忙,同上

    读电源使用模式

    B4H

    Master将该命令发给DS18B20后发出读操作,DS18B20会返回它的电源使用模式:0为寄生电源,1为外部电源

       

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

    基于1-Wire的DS18B20测量温度的实例

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

    实现效果:

    实现代码:

      1 #include <reg52.h>
      2 typedef unsigned char uchar;
      3 typedef unsigned int uint;
      4 uchar code table[] =
      5 {
      6     0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0xee, 0x3e, 0x9c
      7 };
      8 uchar code address[] =
      9 {
     10     0xfe, 0xfd, 0xfb, 0xf7, 0xef, 0xdf, 0xbf, 0x7f
     11 };
     12 sbit DQ = P3 ^ 0; //DQ控制位
     13 sbit dot = P1 ^ 0; //小数点
     14 uchar temp1, temp2; //通过temp1和temp2存储温度低位和高位
     15 
     16 void Delay(uint m)
     17 {
     18     while(m--);
     19 }
     20 uchar ReadByte()
     21 {
     22     uchar byte = 0;
     23     uchar i;
     24     for (i = 0; i < 8; ++i)
     25     {
     26         DQ = 0;
     27         byte >>= 1;
     28         DQ = 1;
     29         if (DQ)
     30             byte = byte | 0x80;
     31         Delay(4);
     32     }
     33     return byte;
     34 }
     35 void WriteByte(uchar byte)
     36 {
     37     uchar i;
     38     for (i = 0; i < 8; ++i)
     39     {
     40         DQ = 0;
     41         byte >>= 1; //数据左移
     42         DQ = CY;
     43         Delay(5);
     44         DQ = 1;
     45     }
     46 }
     47 void Init()
     48 {
     49     DQ = 1;
     50     Delay(8);
     51     DQ = 0;
     52     Delay(80);
     53     DQ = 1;
     54     Delay(20);
     55 }
     56 void ReadTemp()
     57 {
     58     /* 初始化DS18B20 */
     59     Init();
     60     WriteByte(0xcc); //跳过ROM,当前只有一个Slave
     61     WriteByte(0x44); //启动温度转换
     62     Delay(10);
     63     Init();
     64     WriteByte(0xcc); //跳过ROM
     65     WriteByte(0xbe); //读取暂存器内容
     66     temp1 = ReadByte(); //低位存放在temp1中
     67     temp2 = ReadByte(); //高位存放在temp2中
     68 }
     69 void main()
     70 {
     71     bit flag;
     72     uint temp;
     73     uchar i;
     74     while(1)
     75     {
     76         /* 读取温度 */
     77         ReadTemp();
     78 
     79         /* 温度转化 */
     80         temp = temp1 & 0x0f; //temp存入温度低8位并保留低4位
     81         if (temp2 > 127) //temp2 > 01111111时,温度为负
     82         {
     83             flag = 1;
     84             temp1 = ~temp1;
     85             temp2 = ~temp2; //高低各取反
     86             temp = temp1 & 0x0f;
     87             temp += 0x01;  //取反后+1,得到负数值
     88         }
     89         temp = temp * 625;
     90         temp1 = temp1 & 0xf0;
     91         temp1 = temp1 / 16;
     92         temp2 = temp2 * 16;
     93         temp1 += temp2;
     94         if (flag)
     95             temp1 += 0x01;
     96 
     97         /* 温度显示 */
     98         for (i = 0; i < 4; ++i)
     99         {
    100             P2 = address[i];
    101             P1 = table[temp % 10];
    102             Delay(750);
    103             temp = temp / 10;
    104         }
    105         P2 = 0xef;
    106         P1 = table[temp1 % 10];
    107         dot = 1;
    108         Delay(750);
    109         if (temp1 / 100 || temp1 / 10)
    110         {
    111             P2 = 0xdf;
    112             P1 = table[temp1 / 10 % 10];
    113             Delay(750);
    114         }
    115         if (temp1 / 100)
    116         {
    117             P2 = 0xbf;
    118             P1 = table[temp1 / 100 % 10];
    119             Delay(800);
    120         }
    121         if (flag)
    122         {
    123             P2 = 0x7f;
    124             P1 = 0x02;
    125             Delay(750);
    126             flag = 0;
    127         }
    128     }
    129 }

  • 相关阅读:
    ReactJs入门
    Studio-Class Diagram
    Visual Studio-Sequence Diagram
    架构、职责、数据一致性
    Microsoft Build 2015
    Net下无敌的ORM
    SpringMVC1
    插件式Web框架
    ASP.NET的CMS
    Android Drawable绘图学习笔记(转)
  • 原文地址:https://www.cnblogs.com/hughdong/p/7106747.html
Copyright © 2011-2022 走看看