GX1833E——±0.2 ℃精度,内置 2kb EEPROM 的单总线 温度传感器,可替代DS18B20,附STM32驱动程序
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,有任何问题可随时沟通交流,需要完整测试程序请在评论区留言。