DS18B20-单总线

简介: DS18B20-单总线

3.1 单总线通讯协议(One-Wire)

3.1.1 简介

* 定义:主机和从机通过1根线进行通信,在一条总线上可挂接的从器件数量几乎不受限制。

* 特点:这是由达拉斯半导体公司推出的一项通信技术。它采用单根信号线,既可传输时钟,又能传输数据,而且数据传输是双向的。

* 优点:单总线技术具有线路简单,硬件开销少,成本低廉,便于总线扩展和维护等。

3.1.2 通讯过程
(1) 初始化

基于单总线上的所有传输过程都是以初始化开始的,初始化过程由主机发出的复位脉冲和从机响应的应答脉冲组成。应答脉冲使主机知道,总线上有从机设备,且准备就绪。黑色实线代表系统主机拉低总线,灰色实线代表从机拉低总线,而黑色的虚线则代表上拉电阻将总线拉高。

                 

     

初始化代码如下:

1.  /* 

2.   *主机给从机发送复位脉冲 

3.   */  

4.  static void DS18B20_Rst(void)  

5.  {  

6.      /* 主机设置为推挽输出 */  

7.      DS_GPIO_Set_OUT_Mode();  

8.    

9.      DS_PIN_CLR();  

10.    /* 主机至少产生480us的低电平复位信号 */  

11.    Delay_us(750);  

12.  

13.    /* 主机在产生复位信号后,需将总线拉高 */  

14.    DS_PIN_SET();  

15.  

16.    /*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/  

17.    Delay_us(15);  

18.}  

初始化后监测从机发送的存在脉冲,判断当前是否存在单总线设备,示例以DS18B20为例:

1.  /* 

2.   * 检测从机给主机返回的存在脉冲 

3.   * 0:成功 

4.   * 1:失败 

5.   */  

6.  static uint8_t DS18B20_Presence(void)  

7.  {  

8.      uint8_t pulse_time = 0;  

9.    

10.    /* 主机设置为输入 */  

11.    DS_GPIO_Set_IN_Mode();  

12.  

13.    /* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号 

14.     * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲 

15.     */  

16.    while( DS_PIN_READ() && pulse_time < 100 )  

17.    {  

18.        pulse_time++;  

19.        Delay_us(1);  

20.    }  

21.    /* 经过100us后,存在脉冲都还没有到来*/  

22.    if( pulse_time >=100 )  

23.        return 1;  

24.    else  

25.        pulse_time = 0;  

26.  

27.    /* 存在脉冲到来,且存在的时间不能超过240us */  

28.    while( !DS_PIN_READ() && pulse_time < 240 )  

29.    {  

30.        pulse_time++;  

31.        Delay_us(1);  

32.    }  

33.    if( pulse_time >=240 )  

34.        return 1;  

35.    else  

36.        return 0;  

37.}  

(2) 写时序

存在两种写时隙:"写1" 和"写0"。主机采用写 1 时隙向从机写入 1,而采用写 0 时隙向从机写入 0。所有写时隙至少需要 60 us,且在两次独立的写时隙之间至少需要 1u s 的恢复时间。两种写时隙均起始于主机拉低总线(图5 所示)。产生写 1 时隙的方式:主机在拉低总线后,接着必须在 15u s 之内释放总线,由5k 上拉电阻将总线拉至高电平;而产生写0 时隙的方式:在主机拉低总线后,只需在整个时隙期间保持低电平即可( 至少60 us)。在写时隙起始后 15-60 us 期间,单总线器件采样总线电平状态。如果在此期间采样为高电平,则逻辑1 被写入该器件;如果为0 ,则写入逻辑0。时序图如下:


示例代码如下:

1.  /*DS18B20bit函数*/  

2.  static void DS_Write_Bit(ds_pin_level level)  

3.  {  

4.      if(level == HIGH) //写一  

5.      {  

6.          DS_PIN_CLR();  

7.          Delay_us(5);  

8.    

9.          DS_PIN_SET(); //释放总线  

10.        Delay_us(50);  

11.    }  

12.  

13.    else              //0  

14.    {  

15.        DS_PIN_CLR();  

16.        Delay_us(60);  

17.  

18.        DS_PIN_SET(); //释放总线  

19.        Delay_us(2); //协议时间要求:1 < t < 无穷大,此处时间为10us  

20.    }  

21.}  

22.  

23./*DS18B20写一个字节函数*/  

24.static void DS_Write_Byte(uint8_t byte)  

25.{  

26.    uint8_t i = 0;  

27.  

28.    DS_GPIO_Set_OUT_Mode(); //配置为输出模式  

29.  

30.    for(i = 0; i < 8; i++)  

31.    {  

32.        if(byte & 0x01)  //先发送低位  

33.        {  

34.            DS_Write_Bit(HIGH);  

35.        }  

36.        else  

37.        {  

38.            DS_Write_Bit(LOW);  

39.        }  

40.  

41.        byte >>= 1;  

42.  

43.        Delay_us(2);  

44.    }  

45.}  

(3) 读时序

单总线器件仅在主机发出读时隙时,才向主机传输数, 所以, 在主机发出读数据命令后,必须马上产生读时隙,以便从机能够传输数据。所有读时隙至少需要 60us, 且在两次独立的读时隙之间至少需要 1us的恢复时间,每个读时隙都由主机发起,至少拉低总线 1us (图5 所示)。在主机发起读时隙之后,单总线器件才开始在总线上发送 0 或1。若从机发送1,则保持总线为高电平;若发送 0, 则拉低总线 。当发送 0 时,从机在该时隙结束后释放总线 。由上拉电阻将总线拉回至空闲高电平状态。从机发出的数据在起始时隙之后,保持有效时间 15us ,因而,主机在读时隙期间必须释放总线 ,并且在时隙起始后的 15 us 之内采样总线状态。时序图如下:


示例代码如下:

1.  /*DS18B20bit函数*/  

2.  static ds_pin_level DS_Read_Bit(void)  

3.  {  

4.      ds_pin_level temp;  

5.    

6.      DS_GPIO_Set_OUT_Mode();  

7.    

8.      DS_PIN_CLR();  

9.      Delay_us(10);      //协议时间要求:1 < t < 无穷大,此处时间为5us  

10.  

11.    DS_GPIO_Set_IN_Mode(); //配置DS18B20数据脚为输入模式  

12.  

13.    if(DS_PIN_READ() == GPIO_PIN_SET) // 1  

14.    {  

15.        temp = HIGH;  

16.    }  

17.    else                              //0  

18.    {  

19.        temp = LOW;  

20.    }  

21.  

22.    Delay_us(45);    //协议时间要求为45us  

23.  

24.    return temp;  

25.}  

26.  

27./*DS18B20读字节函数*/  

28.static uint8_t DS18B20_Read_Byte(void)  

29.{  

30.    uint8_t i = 0;  

31.    uint8_t level = 0;  

32.    uint8_t dat = 0;  

33.  

34.    for(i = 0; i < 8; i++)  

35.    {  

36.        level = DS_Read_Bit();  

37.        dat = (dat) | (level << i);  

38.    }  

39.  

40.    return dat;  

41.}  

(4) 搜索ROM

ROM搜索过程只是一个简单的三步循环程序:读一位、读该位的补码 、写入一个期望的数据位。总线主机在 ROM的每一位上都重复这样的三步循环程序。当完成某个器件后,主机就能够知晓该器件的ROM信息。剩下的设备数量及其 ROM代码通过相同的过即可获得。

下面的ROM搜索过程实例假设四个不同的器件被连接至同一条总线上,它们的 ROM代码如下所示:
        ROM1   00110101…
        ROM2   10101010…
        ROM3   11110101…
        ROM4   00010001…

具体搜索过程如下:
a: 主机发出复位脉冲,启动初始化序列。从机设备发出响应的应答脉冲;
b: 接着主机在总线上发出ROM搜索命令 ;
c: 主机从总线上准备读入一个数据位,这时,每个响应设备分别将 ROM代码的第一位输出到单总线上。ROM1 和ROM4 输出 0 至总线,而ROM2 和ROM3 输出 1 至总线。线上的输出结果将是所有器件的逻辑”与“ ,所以,主机从总线上读到的将是0 。接着, 主机开始读另一位,即每个器件分别输出 ROM代码中第一位的补码,此时,ROM1 ROM4 输出 1至总线,而ROM2和ROM3 输出 0 至总线 。这样,主机读到的该位补码还是 0 。主机由此判定,总线上有些器件的ROM代码第一位为0, 有些则为1。

(5) 注意事项

在使用STM32进行调试的是否需要将DS18B20的数据脚配置为输入上拉,否则读出来的温度数据会有问题。

相关文章
|
7月前
|
传感器
【STM32】I2C练习,SHT3X温度传感器的数据读取
【STM32】I2C练习,SHT3X温度传感器的数据读取
108 0
|
存储 芯片
51单片机--DS1302时钟
51单片机--DS1302时钟
129 0
PADS Logic原理图添加总线
原理图总线在连线很多的时候或者是连线信号可以归类的时候(比如存储器的数据信号),很适合使用,可以使原理图变得简洁,提高可读性,下面我们就看一下如何在原理图中添加总线。
549 0
|
传感器 芯片
51单片机读取DS18B20温度传感器
51单片机读取DS18B20温度传感器
272 0
|
传感器 C语言 异构计算
|
存储 C语言 芯片
51单片机&15单片机 时钟芯片DS1302
51单片机&15单片机 时钟芯片DS1302
251 0
|
传感器 存储 物联网
51单片机DS18B20的使用
51单片机DS18B20的使用
252 0
|
传感器 存储 编解码
51单片机&15单片机 温度传感器DS18B20
51单片机&15单片机 温度传感器DS18B20
383 0
【STC15单片机】模拟I2C操作AT24C02数据读取,PCF8591的A/D转换代码
【STC15单片机】模拟I2C操作AT24C02数据读取,PCF8591的A/D转换代码
311 0
|
传感器
STM32:DMA数据转运+AD多通道(软件篇)
STM32:DMA数据转运+AD多通道(软件篇)
283 0
STM32:DMA数据转运+AD多通道(软件篇)