GX1833E高精度温度传感器:替代DS18B20,内置2kb EEPROM与单总线技术详解,STM32程序及多设备挂接指南

GX1833E——±0.2 ℃精度,内置 2kb EEPROM 的单总线 温度传感器,可替代DS18B20,附STM32驱动程序

  • GX1833E传感器概述
  • 一、基本性能
  • 二、引脚说明
  • 三、参考电路和供电建议
  • 四、详细说明
  • 4.1.温度输出
  • 4.2.缓存区映射
  • 4.3.存储器映射
  • 4.4.芯片地址
  • 4.4.1标准地址(64 位 RID)
  • 4.4.2自定义地址(24 位 UID)
  • 4.5.位通信
  • 4.6.通信流程
  • 4.6.1寻址阶段
  • 4.6.2功能阶段
  • 五、驱动代码
  • GX1833E传感器概述

    GX1833E是一款高精度、兼容1-Wire通信的数字输出温度传感器,无需任何外部感温单元即可获得16位温度输出,并且在-20℃至+85℃范围内具有小于±0.2℃的最大测温误差。每颗芯片在出厂时均已完成精密校准,用户无需对温度输出进行任何额外补偿处理。

    GX1833E内置2048位EEPROM,允许主机以64位为单位存储应用数据,以256位为单位设置擦写保护,从而避免数据的意外覆盖。每颗芯片都具有独一无二的工厂编程64位RID,可用于通信寻址和产品溯源。

    一、基本性能

    • 测量范围:−55℃ ~ +150℃
    • 最大误差:± 0.2℃ (-20℃ ~ + 85℃)
    • 高分辨率:0.0078125℃@16bits
    • 电源电压:2.5V ~ 5.5V
    • 转换时间:35ms
    • 低功耗:平均电流2μA@1Hz,关断电流0.5μA
    • 存储容量:2k-bit EEPROM
    • 通信协议:1-Wire
    • 每颗芯片具有独一无二的64位RID
    • 用于快速搜索的用户自定义24位UID

    二、引脚说明

    三、参考电路和供电建议

    GX1833E 典型连接如图 7 所示,芯片 VDD 引脚必须跟主机和上拉电阻连接至同一电源轨下,否则可能导致通信失败。上拉电阻取值可以根据通信速率和总线负载情况在 1kΩ 至 10kΩ 范围内调整。

    GX1833E 可以通过在 VDD 引脚连接 1nF 储能电容来改造成总线供电连接,如图 8 所示。总线为逻辑高时,GX1833E 从总线上“窃取”电流,并为内部模块供电。总线为逻辑低时,GX1833E 使用储能电容中保存的电荷为内部模块供电,并通过片内集成的二极管来确保通信过程中电容电荷不会反向泄漏。但对于擦除和编程存储器这类大功率操作,主机必须提前开启强上拉电路(可使用 PMOS 管实现),以避免芯片因供电不足而掉电复位。

    四、详细说明

    4.1.温度输出

    每次温度转换的 16 位数字输出保存在只读的温度寄存器中,其中 1 LSB=0.0078125℃,负数以二进制补码形式表示。温度寄存器的上电初始值为 0x0000。每次转换结束后,GX1833E 会自动更新温度寄存器。

    4.2.缓存区映射

    GX1833E 内部缓存区由 9 个字节组成,其映射关系如表 5 所示。字节 2 至 6 备份于 EEPROM 指定位置中,并在每次上电或复位后重新加载到缓存区中。

    保护状态寄存器(字节 7)的内容说明如表 6 所示。每次上电或复位时,GX1833E 会自动读取保护控制数据(页 7 块 1,地址 0xE8),并更新保护生效标志 WP。一旦标志生效,那么相应地址区间将禁止擦除和编程。

    4.3.存储器映射

    GX1833E 内置 2kb EEPROM 存储器,共划分为 8 个数据页,每页包含 4 个数据块。访问以数据块(8 字节)为单位。具体的存储器映射关系如表 7 所示。

    数据页 7 的内容说明如表 8 所示。块 3(地址 0xF8)和块 2(地址 0xF0)为工厂保留值,该区域禁止擦除和编程。块 1(地址 0xE8)为保护控制,每个字节分别保护不同的地址区间(参见表 6),仅在取值为 0x55 时生效,其他任何值均表示未生效。块 0(地址 0xE0)为缓存区备份,其中字节 5、6 和 7 组成 24 位用户自定义 ID。

    块 1 中任一保护生效,都会禁止对块 1 的擦除操作。编程操作虽然仍被允许,但对生效字节的编程将被忽略,对未生效字节的编程则不受影响。在设置擦写保护以前,请务必读取对应地址区间的数据,并验证是否正确。否则一旦生效,数据将永远无法修改。

    4.4.芯片地址

    4.4.1标准地址(64 位 RID)

    GX1833E 支持 1-Wire 通信协议的 64 位标准地址(RID)。该地址由工厂编程,且无法被客户应用程序更改。GXCAS 确保出厂的每颗芯片都具有独一无二的标准地址,并以此提供产品溯源。

    4.4.2自定义地址(24 位 UID)


    GX1833E 支持 24 位自定义地址(UID)。该地址保存于 EEPROM 存储器中(参见表 8),由用户自行编程。主机可通过设置擦写保护,来防止自定义地址被应用程序无意中修改。

    4.5.位通信

    1-Wire 通信均通过固定时隙与可变脉冲宽度异步实现,以分别表示逻辑 0 和逻辑 1。在空闲状态下,外部上拉电阻将通信线维持在高电平。无论是写操作还是读操作,所有的位通信均由主机驱动数据线产生下降沿信号,随后根据数据线在下降沿之后保持低电平或高电平的时间对位值进行解码。尽管每次通信仅传输一个比特位,但主机与芯片之间的数据交互是以字节为单位完成的。每个字节的传输从最低有效位开始。若传输的字节不完整,则无法保证芯片的行为表现。

    复位操作是主机重置总线上所有芯片通信状态的过程。如图 2 所示,主机通过将数据线拉低 t RST 时间后释放来启动复位操作。此时总线上的所有芯片,无论其当前状态如何,都会恢复至初始状态,并对主机发起的总线复位作出响应。芯片将以主机释放数据线为起点,等待 t PDH 时间后拉低数据线,并在维持 t PDL 时间后释放。主机必须在释放数据线 t MSP 时间后对数据线进行采样,以确定总线上是否有芯片作出响应。


    4.6.通信流程

    1-Wire 通信分为寻址和功能两个阶段。如图 3 所示,任何通信都开始于复位操作,总线上的每个从机都必须对此作出响应。在寻址阶段,主机选择目标芯片进行访问。在功能阶段,主机为所选芯片指定期望执行的功能。

    4.6.1寻址阶段


    GX1833E 共支持 8 条寻址命令:
    跳过 芯片 地址(Skip RID , 0xCC )
    读取芯片 地址(Read RID , 0x33 )
    匹配芯片 地址(Match RID , 0x55)
    搜索芯片地址(Search RID , 0xF0 )
    搜索报警芯片地址(Alarm Search RID , 0xEC )
    匹配自定义地址(Match UID , 0x22)
    搜索自定义地址(Search UID , 0xF8 )
    搜索报警自定义地址(Alarm Search UID , 0xF4 )

    4.6.2功能阶段


    GX1833E 共支持 6 种功能:
    启动温度转换(Convert , 0x44 )
    软复位 (Soft Reset , 0xB8 )
    读取缓存区(Read Buffer , 0xBE)
    读取存储器(Read Memory , 0xF0)
    擦除存储器(Erase Memory , 0xC1)
    编程存储器(Write Memory , 0xC5 )

    五、驱动代码

    5.1 gx1833e_gpio.c

    #include "gx1833e.h"
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_gpio_configure
      Description : configure the DQ port
      Parameter   : none
      Return      : none
    ---------------------------------------------------------------------*/
    void gx1833e_gpio_configure (void)
    {
        
      GPIO_InitTypeDef pin_cfg;
      // enable peripheral clock
      RCC_APB2PeriphClockCmd(GX1833e_GPIO_CLK, ENABLE);
    	
      // configure I/O port of DQ
    
      pin_cfg.GPIO_Pin   = GX1833e_GPIO_PIN;
      pin_cfg.GPIO_Mode  = GPIO_Mode_Out_OD;	  // open-drain output
      pin_cfg.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GX1833e_GPIO_PORT, &pin_cfg);
    	
    	GPIO_SetBits(GX1833e_GPIO_PORT, GX1833e_GPIO_PIN);  // default HIGH
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_gpio_pulldown
      Description : pull down the 1-wire bus
      Parameter   : none
      Return      : none
    ---------------------------------------------------------------------*/
    void gx1833e_gpio_pulldown (void)
    {
      GPIO_ResetBits(GX1833e_GPIO_PORT, GX1833e_GPIO_PIN);
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_gpio_release
      Description : release the 1-wire bus
      Parameter   : none
      Return      : none
    ---------------------------------------------------------------------*/
    void gx1833e_gpio_release (void)
    {
      GPIO_SetBits(GX1833e_GPIO_PORT, GX1833e_GPIO_PIN);
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_gpio_sample
      Description : sample the 1-wire bus
      Parameter   : none
      Return      : sampled data
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_gpio_sample (void)
    {
    	return GPIO_ReadInputDataBit(GX1833e_GPIO_PORT, GX1833e_GPIO_PIN);
    }
    
    
    
    

    5.2 gx1833e_gpio.h

    
    
    #ifndef __GX1833e_GPIO_HEADER_FILE
    #define __GX1833e_GPIO_HEADER_FILE
    
    #include "sys.h"   
    
    
    #define GX1833e_GPIO_CLK  RCC_APB2Periph_GPIOB
    #define GX1833e_GPIO_PORT GPIOB
    #define GX1833e_GPIO_PIN  GPIO_Pin_7
    
    // function declaration
    void    gx1833e_gpio_configure (void);
    void    gx1833e_gpio_pulldown  (void);
    void    gx1833e_gpio_release   (void);
    uint8_t gx1833e_gpio_sample    (void);
    
    #endif
    
    

    5.3 gx1833e_onewire.c

    
    #include "gx1833e.h"
    #include "delay.h"
    /*---------------------------------------------------------------------
      Function    : gx1833e_onewire_reset
      Description : initialization sequence (reset pulse + presence pulse)
      Parameter   : none
      Return      : if presence pulse is detected
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_onewire_reset (void)
    {
      uint8_t rxd = 1;
      
      // transmit reset pulse
      gx1833e_gpio_pulldown();
      delay_us(GX1833e_TIME_RST);
      gx1833e_gpio_release();
      
      // detect presence pulse
      delay_us(GX1833e_TIME_MSP);
      rxd = gx1833e_gpio_sample();
      delay_us(GX1833e_TIME_RST - GX1833e_TIME_MSP);
    
      return ((rxd == 0) ? GX1833e_ACK : GX1833e_NACK);
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_onewire_read_bit
      Description : read one bit from the 1-wire bus
      Parameter   : none
      Return      : received bit
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_onewire_read_bit (void)
    {
      uint8_t rxd = 0;
      
      // start read slot
    	gx1833e_gpio_pulldown();	
        delay_us(GX1833e_TIME_RL);
    	gx1833e_gpio_release();
      
      // sample the 1-wire bus
    	delay_us(GX1833e_TIME_MSR - GX1833e_TIME_RL);
    	rxd = gx1833e_gpio_sample();
        delay_us(GX1833e_TIME_SLT - GX1833e_TIME_MSR);
      
      // recovery time
      delay_us(GX1833e_TIME_REC);
      
      return rxd;
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_onewire_write_bit
      Description : write one bit to the 1-wire bus
      Parameter 1 : bit to be transmitted
      Return      : none
    ---------------------------------------------------------------------*/
    void gx1833e_onewire_write_bit (uint8_t txd)
    {
      if(txd == 0) {
    		// start write-zero slot
        gx1833e_gpio_pulldown();
        delay_us(GX1833e_TIME_W0L);
    	gx1833e_gpio_release();
    	}
      else {
    		// start write-one slot
        gx1833e_gpio_pulldown();
        delay_us(GX1833e_TIME_W1L);
    	gx1833e_gpio_release();
        delay_us(GX1833e_TIME_SLT - GX1833e_TIME_W1L);
    	}
      
      // recovery time
        delay_us(GX1833e_TIME_REC);
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_onewire_read_byte
      Description : read one byte from the 1-wire bus
      Parameter   : none
      Return      : received byte
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_onewire_read_byte (void)
    {
      uint8_t dat = 0;
      uint8_t rxd = 0;
      uint8_t i;
      for(i = 0; i < 8; i ++) {
        dat = dat >> 1;
        rxd = gx1833e_onewire_read_bit();
        dat = dat | ((rxd == 0) ? 0x00 : 0x80);
      }
      
      return dat;
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_onewire_write_byte
      Description : write one byte to the 1-wire bus
      Parameter 1 : byte to be transmitted
      Return      : none
    ---------------------------------------------------------------------*/
    void gx1833e_onewire_write_byte (uint8_t dat)
    {
      uint8_t txd = 0;
      uint8_t i;
      for(i = 0; i < 8; i ++) {
        txd = dat & 0x01; // LSB first
        dat = dat >> 1;
        gx1833e_onewire_write_bit(txd);
      }
       delay_us(500);
    }
    
    

    5.4 gx1833e_onewire.h

    
    
    #ifndef __GX1833e_ONEWIRE_HEADER_FILE
    #define __GX1833e_ONEWIRE_HEADER_FILE
    
    #include"stdint.h"
    // ACK/NACK
    #define GX1833e_ACK      0x01
    #define GX1833e_NACK     0x00
    
    // timing definition in microseconds (us)
    // 1. SLOT
    #define GX1833e_TIME_SLT   70
    #define GX1833e_TIME_REC    5  //30
    // 2. RESET & PRESENCE
    #define GX1833e_TIME_RST  300
    #define GX1833e_TIME_MSP   70
    // 3. WRITE
    #define GX1833e_TIME_W0L   70
    #define GX1833e_TIME_W1L    5
    // 4. READ
    #define GX1833e_TIME_RL     5
    #define GX1833e_TIME_MSR   15
    
    // function declaration
    uint8_t gx1833e_onewire_reset      (void);
    uint8_t gx1833e_onewire_read_bit   (void);
    void    gx1833e_onewire_write_bit  (uint8_t txd);
    uint8_t gx1833e_onewire_read_byte  (void);
    void    gx1833e_onewire_write_byte (uint8_t dat);
    
    #endif
    
    

    5.5 gx1833e_driver.c

    
    #include "gx1833e_driver.h"
    #include "usart.h"
    #include "delay.h"
    
    #include "gx1833e.h"
    #include "usart.h"
    /*---------------------------------------------------------------------
      Function    : gx1833e_search
      Description : execute search algorithm
      Parameter   : RID array of devices found
      Return      : number of devices found (0=no device was found)
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_search (uint64_t * ids)
    {
      uint8_t  num     = 0;   // number of devices found
      uint8_t  pos     = 0;   // current bit position
      uint8_t  dir     = 0;   // search direction
      uint8_t  val     = 0;   // current bit
      uint8_t  val_cmp = 0;   // complement of current bit
      uint8_t  brn_new = 0;   // the bit position where a new branch is taken
      uint8_t  brn_chk = 0;   // branch checkpoint
      uint64_t cur_rid = 0;   // current RID
      uint64_t reg_rid = 0;   // last RID found
      
      do {
        if(gx1833e_onewire_reset() == GX1833e_ACK) {
          brn_new = 0;
          cur_rid = 0;
          gx1833e_onewire_write_byte(GX1833E_SEARCH);
          for(pos = 1; pos < 65; pos ++) {
            cur_rid = cur_rid >> 1;
            val     = gx1833e_onewire_read_bit();
            val_cmp = gx1833e_onewire_read_bit();
            /*
              00 : There are both 0s and 1s in the current bit position of the participating RIDs => discrepancy
              01 : There are only 0s        in the current bit position of the participating RIDs
              10 : There are only 1s        in the current bit position of the participating RIDs
              11 : No device participating in the search (atypical situation)
            */
            if((val == 0) && (val_cmp == 0)) {
              /*
                pos < brn_chk : take the same path as last time (from last RID found)
                pos = brn_chk : take the  "1" path
                pos > brn_chk : take the  "0" path
              */
              if(pos < brn_chk)
                dir = ((uint8_t) (reg_rid >> (pos - 1))) & 0x01;
              else if(pos == brn_chk)
                dir = 1;
              else
                dir = 0;
              
              if(dir == 0)
                brn_new = pos;
            }
            else if((val == 0) && (val_cmp != 0))
              dir = 0;
            else if((val != 0) && (val_cmp == 0))
              dir = 1;
            else {
              return 0; // Error : the device discovered is removed from the 1-wire bus during the search
            }
            cur_rid = cur_rid | ((dir == 0) ? 0x0000000000000000 : 0x8000000000000000);
            gx1833e_onewire_write_bit(dir);
          }
          brn_chk  = brn_new;
          reg_rid  = cur_rid;
          ids[num] = cur_rid;
          num ++;
        }
        else {
          return 0; // Error : no device on the bus
        }
      } while (brn_chk > 0);
      
      return num; // Returning zero means that no device was found
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_alarm
      Description : execute search algorithm (only alarm devices participate)
      Parameter   : RID array of devices found
      Return      : number of devices found (0=no device was found)
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_alarm (uint64_t * ids)
    {
      uint8_t  num     = 0;   // number of device found
      uint8_t  pos     = 0;   // current bit position
      uint8_t  dir     = 0;   // search direction
      uint8_t  val     = 0;   // current bit
      uint8_t  val_cmp = 0;   // complement of current bit
      uint8_t  brn_new = 0;   // the bit position where a new branch is taken
      uint8_t  brn_chk = 0;   // branch checkpoint
      uint64_t cur_rid = 0;   // current RID
      uint64_t reg_rid = 0;   // last RID found
      
      do {
        if(gx1833e_onewire_reset() == GX1833e_ACK) {
          brn_new = 0;
          cur_rid = 0;
          gx1833e_onewire_write_byte(GX1833E_ALARM);
          for(pos = 1; pos < 65; pos ++) {
            cur_rid = cur_rid >> 1;
            val     = gx1833e_onewire_read_bit();
            val_cmp = gx1833e_onewire_read_bit();
            /*
              00 : There are both 0s and 1s in the current bit position of the participating RIDs => discrepancy
              01 : There are only 0s        in the current bit position of the participating RIDs
              10 : There are only 1s        in the current bit position of the participating RIDs
              11 : No device participating in the search (atypical situation)
            */
            if((val == 0) && (val_cmp == 0)) {
              /*
                pos < brn_chk : take the same path as last time (from last RID found)
                pos = brn_chk : take the  "1" path
                pos > brn_chk : take the  "0" path
              */
              if(pos < brn_chk)
                dir = ((uint8_t) (reg_rid >> (pos - 1))) & 0x01;
              else if(pos == brn_chk)
                dir = 1;
              else
                dir = 0;
              
              if(dir == 0)
                brn_new = pos;
            }
            else if((val == 0) && (val_cmp != 0))
              dir = 0;
            else if((val != 0) && (val_cmp == 0))
              dir = 1;
            else {
    					return 0; // Error : the device discovered is removed from the 1-wire bus during the search
            }
            cur_rid = cur_rid | ((dir == 0) ? 0x0000000000000000 : 0x8000000000000000);
            gx1833e_onewire_write_bit(dir);
          }
          brn_chk  = brn_new;
          reg_rid  = cur_rid;
          ids[num] = cur_rid;
          num ++;
        }
        else {
          return 0; // Error : no device on the bus
        }
      } while (brn_chk > 0);
      
      return num; // Returning zero means that no device was found
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_read_rom
      Description : read RID
      Parameter   : none
      Return      : RID of current device (0=no device on the bus)
    ---------------------------------------------------------------------*/
    uint64_t gx1833e_read_rom (void)
    {
      uint8_t  rxd = 0;
      uint64_t rid = 0;
      uint8_t i;
      if(gx1833e_onewire_reset() == GX1833e_ACK) {
    		gx1833e_onewire_write_byte(GX1833E_READ);
        for( i = 0; i < 8; i ++) {
          rxd = gx1833e_onewire_read_byte();
          rid = rid | (((uint64_t) rxd) << (8 * i));
        }
    		return rid;
      }
      else {
    		return 0; // Error : no device on the bus
    	}
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_match
      Description : match RID
      Parameter   : RID of selected device
      Return      : finish flag (0=no device on the bus)
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_match (uint64_t rid)
    {
      uint8_t txd = 0;
      uint8_t i;
      if(gx1833e_onewire_reset() == GX1833e_ACK) {
        gx1833e_onewire_write_byte(GX1833E_MATCH);
        for( i = 0; i < 8; i ++) {
          txd = (uint8_t) (rid >> (8 * i));
          gx1833e_onewire_write_byte(txd);
        }
        return 1;
      }
      else {
        return 0; // Error : no device on the bus
      }
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_skip
      Description : skip addressing
      Parameter   : none
      Return      : finish flag (0=no device on the bus)
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_skip (void)
    {
      if(gx1833e_onewire_reset() == GX1833e_ACK) {
        gx1833e_onewire_write_byte(GX1833E_SKIP);
        return 1;
      }
      else {
        return 0; // Error : no device on the bus
      }
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_convert
      Description : start temperature conversion
      Parameter   : none
      Return      : none
    ---------------------------------------------------------------------*/
    void gx1833e_convert (void)
    {
      gx1833e_onewire_write_byte(GX1833E_CONVERT);
    }
    
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_search_uid
      Description : execute search algorithm
      Parameter   : UID array of devices found
      Return      : number of devices found (0=no device was found)
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_search_uid (uint32_t * ids)
    {
      uint8_t  num     = 0;   // number of devices found
      uint8_t  pos     = 0;   // current bit position
      uint8_t  dir     = 0;   // search direction
      uint8_t  val     = 0;   // current bit
      uint8_t  val_cmp = 0;   // complement of current bit
      uint8_t  brn_new = 0;   // the bit position where a new branch is taken
      uint8_t  brn_chk = 0;   // branch checkpoint
      uint64_t cur_rid = 0;   // current RID
      uint64_t reg_rid = 0;   // last RID found
      
      do {
        if(gx1833e_onewire_reset() == GX1833e_ACK) {
          brn_new = 0;
          cur_rid = 0;
          gx1833e_onewire_write_byte(GX1833E_SEARCH_UID);
          for(pos = 1; pos < 25; pos ++) {
            cur_rid = cur_rid >> 1;
            val     = gx1833e_onewire_read_bit();
            val_cmp = gx1833e_onewire_read_bit();
            /*
              00 : There are both 0s and 1s in the current bit position of the participating RIDs => discrepancy
              01 : There are only 0s        in the current bit position of the participating RIDs
              10 : There are only 1s        in the current bit position of the participating RIDs
              11 : No device participating in the search (atypical situation)
            */
            if((val == 0) && (val_cmp == 0)) {
              /*
                pos < brn_chk : take the same path as last time (from last RID found)
                pos = brn_chk : take the  "1" path
                pos > brn_chk : take the  "0" path
              */
              if(pos < brn_chk)
                dir = ((uint8_t) (reg_rid >> (pos - 1))) & 0x01;
              else if(pos == brn_chk)
                dir = 1;
              else
                dir = 0;
              
              if(dir == 0)
                brn_new = pos;
            }
            else if((val == 0) && (val_cmp != 0))
              dir = 0;
            else if((val != 0) && (val_cmp == 0))
              dir = 1;
            else {
              return 0; // Error : the device discovered is removed from the 1-wire bus during the search
            }
            cur_rid = cur_rid | ((dir == 0) ? 0x00000000 : 0x00800000);
            gx1833e_onewire_write_bit(dir);
          }
          brn_chk  = brn_new;
          reg_rid  = cur_rid;
          ids[num] = cur_rid;
          num ++;
        }
        else {
          return 0; // Error : no device on the bus
        }
      } while (brn_chk > 0);
      
      return num; // Returning zero means that no device was found
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_alarm_search_uid
      Description : execute search algorithm (only alarm devices participate)
      Parameter   : RID array of devices found
      Return      : number of devices found (0=no device was found)
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_alarm_search_uid (uint32_t * ids)
    {
      uint8_t  num     = 0;   // number of device found
      uint8_t  pos     = 0;   // current bit position
      uint8_t  dir     = 0;   // search direction
      uint8_t  val     = 0;   // current bit
      uint8_t  val_cmp = 0;   // complement of current bit
      uint8_t  brn_new = 0;   // the bit position where a new branch is taken
      uint8_t  brn_chk = 0;   // branch checkpoint
      uint64_t cur_rid = 0;   // current RID
      uint64_t reg_rid = 0;   // last RID found
      
      do {
        if(gx1833e_onewire_reset() == GX1833e_ACK) {
          brn_new = 0;
          cur_rid = 0;
          gx1833e_onewire_write_byte(GX1833E_ALARM_SEARCH_UID);
          for(pos = 1; pos < 25; pos ++) {
            cur_rid = cur_rid >> 1;
            val     = gx1833e_onewire_read_bit();
            val_cmp = gx1833e_onewire_read_bit();
            /*
              00 : There are both 0s and 1s in the current bit position of the participating RIDs => discrepancy
              01 : There are only 0s        in the current bit position of the participating RIDs
              10 : There are only 1s        in the current bit position of the participating RIDs
              11 : No device participating in the search (atypical situation)
            */
            if((val == 0) && (val_cmp == 0)) {
              /*
                pos < brn_chk : take the same path as last time (from last RID found)
                pos = brn_chk : take the  "1" path
                pos > brn_chk : take the  "0" path
              */
              if(pos < brn_chk)
                dir = ((uint8_t) (reg_rid >> (pos - 1))) & 0x01;
              else if(pos == brn_chk)
                dir = 1;
              else
                dir = 0;
              
              if(dir == 0)
                brn_new = pos;
            }
            else if((val == 0) && (val_cmp != 0))
              dir = 0;
            else if((val != 0) && (val_cmp == 0))
              dir = 1;
            else {
    					return 0; // Error : the device discovered is removed from the 1-wire bus during the search
            }
            cur_rid = cur_rid | ((dir == 0) ? 0x00000000 : 0x00800000);
            gx1833e_onewire_write_bit(dir);
          }
          brn_chk  = brn_new;
          reg_rid  = cur_rid;
          ids[num] = cur_rid;
          num ++;
        }
        else {
          return 0; // Error : no device on the bus
        }
      } while (brn_chk > 0);
      
      return num; // Returning zero means that no device was found
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_match_uid
      Description : match UID
      Parameter   : UID of selected device
      Return      : finish flag (0=no device on the bus)
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_match_uid (uint32_t uid)
    {
      uint8_t txd = 0;
      uint8_t i;
      if(gx1833e_onewire_reset() == GX1833e_ACK) {
        gx1833e_onewire_write_byte(GX1833E_MATCH_UID);
        for( i = 0; i < 3; i ++) {
          txd = (uint8_t) (uid >> (8 * i));
          gx1833e_onewire_write_byte(txd);
        }
        return 1;
      }
      else {
        return 0; // Error : no device on the bus
      }
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_generate_crc8             
      Description : generate CRC-8 of 1-wire packet
      Parameter   : data packet
      Return      : calculated CRC-8
    ---------------------------------------------------------------------*/
    uint8_t gx1833e_generate_crc8 (uint64_t dat, uint8_t crc_reg_init)
    {
      uint8_t dat_in  = 0; // data input bit
      uint8_t crc_in  = 0; // crc  input bit
      uint8_t crc_reg = 0; // crc  register
      uint8_t i;
        
      crc_reg =  crc_reg_init;
        
      for( i = 0; i < 64; i ++) {
        dat_in  = (uint8_t) ((dat >> i) & 0x0000000000000001); // LSB first
        crc_in  = (crc_reg & 0x01) ^ dat_in;
        crc_reg = (crc_reg >> 1) ^ ((crc_in != 0) ? CRC_POLY : 0x00);
      }
      
      return crc_reg;
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_read_scratchpad
      Description : read scratchpad
      Parameter   : none
    Return      : received data (WrtProt OffsetH OffsetL CONF,TLOW,THIG,TEMP-MSByte,TEMP-LSByte)
    ---------------------------------------------------------------------*/
    uint64_t gx1833e_read_scratchpad (void)
    {
    	uint8_t  cnt     = 0;
    	uint64_t rxd     = 0;
    	uint8_t  crc_rxd = 0;
    	uint8_t  crc_cal = 0;
    	
      gx1833e_onewire_write_byte(GX1833E_READ_SCRATCHPAD);
    	
    	for(cnt = 0; cnt < 8; cnt ++) {
    		rxd = rxd | (((uint64_t) gx1833e_onewire_read_byte()) << (8 * cnt));
    	}
    	crc_rxd = gx1833e_onewire_read_byte();
    	crc_cal = gx1833e_generate_crc8(rxd,0);
    	
    	if(crc_rxd == crc_cal) {
        return rxd;
    	}
    	else {
        return 0; // Error : CRC-8 verification failed
    	}
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_Read_EE
      Description : gx1833e_Read_EE
      Parameter   : none
    ---------------------------------------------------------------------*/
    void gx1833e_Read_EE  (uint8_t addr, uint8_t block)
    {
    	uint8_t  cnt     = 0;
    	uint64_t rxd     = 0;
    	uint8_t  crc_rxd = 0;
    	uint8_t  crc_cal = 0;
    	
       gx1833e_onewire_write_byte(GX1833E_Read_Memory);
       gx1833e_onewire_write_byte(addr);	
       
       while(block--)
       {    
           delay_ms(5);       
            for(cnt = 0; cnt < 8; cnt ++) {
                rxd = rxd | (((uint64_t) gx1833e_onewire_read_byte()) << (8 * cnt));
            }
            crc_rxd = gx1833e_onewire_read_byte();
            crc_cal = gx1833e_generate_crc8(rxd,0);
            
            if(crc_rxd == crc_cal) {
              UartOutDW((rxd>>32));
              UartOutDW(rxd);
              rxd  = 0;
            }
            else {
              UartOutDW(0xEEEEEEEE);
              UartOutDW(0xEEEEEEEE);        
            }
       }
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_Program_EE
      Description : gx1833e_Program_EE
      Parameter   : none
    ---------------------------------------------------------------------*/
    void gx1833e_Program_EE  (uint8_t addr, uint8_t block, uint64_t *array)
    {
    	uint8_t  i     = 0;    
    	uint8_t  cnt     = 0;
    	uint8_t  crc_rxd = 0;
    	uint8_t  crc_cal = 0;
    	
       gx1833e_onewire_write_byte(GX1833E_Write_Memory);
       
       for(i = 0; i < block; i ++) 
       {       
           gx1833e_onewire_write_byte(addr);	
           for(cnt = 0; cnt < 8; cnt ++) {
               gx1833e_onewire_write_byte((array[i]>>(cnt*8)));
    
                
            }
    
            crc_rxd = gx1833e_onewire_read_byte();
            crc_cal = gx1833e_generate_crc8((uint64_t)addr<<56,0);
            crc_cal = gx1833e_generate_crc8(array[i], crc_cal);
            
            if(crc_rxd == crc_cal) {
            gx1833e_onewire_write_byte(0xA5);
            delay_ms(150);
            addr+=8;
            }
            else {
              UartOutDW(0xEEEEEEEE);
              UartOutDW(0xEEEEEEEE);  
             
            }          
       }
    }
    
    /*---------------------------------------------------------------------
      Function    : gx1833e_Program_EE
      Description : gx1833e_Program_EE
      Parameter   : none
    ---------------------------------------------------------------------*/
    void gx1833e_Program_EE_block  (uint8_t addr, uint64_t data)
    {
    	uint8_t  cnt     = 0;
    	uint8_t  crc_rxd = 0;
    	uint8_t  crc_cal = 0;
    	
       gx1833e_onewire_write_byte(GX1833E_Write_Memory);
           
           gx1833e_onewire_write_byte(addr);	
           for(cnt = 0; cnt < 8; cnt ++) {
               gx1833e_onewire_write_byte((data>>(cnt*8)));
                
            }
            crc_rxd = gx1833e_onewire_read_byte();
            crc_cal = gx1833e_generate_crc8((uint64_t)addr<<56,0);
            crc_cal = gx1833e_generate_crc8(data, crc_cal);
            
            if(crc_rxd == crc_cal) {
            gx1833e_onewire_write_byte(0xA5);
            delay_ms(150);
            }
            else {
              UartOutDW(0xEEEEEEEE);
              UartOutDW(0xEEEEEEEE);        
            }          
    }
    
    

    5.6 gx1833e_driver.h

    #ifndef __GX1833E_DRIVER_HEADER_FILE
    #define __GX1833E_DRIVER_HEADER_FILE
    
    #include "sys.h"  
    
    // CRC-8 generator polynomial
    #define CRC_POLY                 0x8C
    
    
    // definition of addressing command
    #define GX1833E_SEARCH                0xF0
    #define GX1833E_ALARM                 0xEC
    #define GX1833E_READ                  0x33
    #define GX1833E_MATCH                 0x55
    #define GX1833E_SKIP                  0xCC
    
    #define GX1833E_SEARCH_UID            0xF8
    #define GX1833E_ALARM_SEARCH_UID      0xF4
    #define GX1833E_MATCH_UID             0x22
    
    // definition of function command
    #define GX1833E_CONVERT               0x44
    #define GX1833E_READ_SCRATCHPAD       0xBE
    #define GX1833E_WRITE_SCRATCHPAD      0x4E
    #define GX1833E_RESET                 0xB8
    #define GX1833E_Erase_Memory          0xC1
    #define GX1833E_Read_Memory           0xF0
    #define GX1833E_Write_Memory          0xC5
    
    
    #define MAX_NUM 16
    
    // function declaration
    uint8_t gx1833e_search_uid (uint32_t * ids);
    uint8_t gx1833e_alarm_search_uid (uint32_t * ids);
    uint8_t gx1833e_match_uid (uint32_t uid);
    
    
    
    uint8_t gx1833e_generate_crc8 (uint64_t dat, uint8_t crc_reg_init);
    
    uint64_t gx1833e_read_scratchpad (void);
    uint64_t gx1833e_VerifyRead_EE  (uint8_t mode, uint8_t addr);
    void gx1833e_Read_EE  (uint8_t addr, uint8_t block);
    void gx1833e_Program_EE  (uint8_t addr, uint8_t block, uint64_t *array);
    void gx1833e_Program_EE_block  (uint8_t addr, uint64_t data);
    // function declaration
    uint8_t  gx1833e_search           (uint64_t * ids);
    uint8_t  gx1833e_alarm            (uint64_t * ids);
    uint64_t gx1833e_read_rom         (void);
    uint8_t  gx1833e_match            (uint64_t   id);
    uint8_t  gx1833e_skip             (void);
    void     gx1833e_convert          (void);
    
    
    
    #endif
    
    
    
    

    欢迎各位伙伴咨询、测试GX1833E,有任何问题可随时沟通交流,需要完整测试程序请在评论区留言。

    作者:Mar_Quis

    物联沃分享整理
    物联沃-IOTWORD物联网 » GX1833E高精度温度传感器:替代DS18B20,内置2kb EEPROM与单总线技术详解,STM32程序及多设备挂接指南

    发表回复