GX451 —— 拥有η因子和温度偏移校正、串联电阻消除、可编程数字滤波器的本地、远程温度传感器,兼容TMP451,附STM32程序
文章目录
GX451概述
GX451 是一款内置本地测温通道的高精度、低功耗远程温度传感器。远程测温探头通常是低成本的分立 NPN 或 PNP 晶体管,或者是作为微处理器、FPGA 组成部分的衬底热晶体管或二极管。本地与远程测温结果均为 12 位数字输出,分辨率 0.0625°C,有扩展测温模式,测温范围 – 55℃ ~ 150℃,支持 SMBus 通信协议。
一、基 本 性 能
• 测温范围:
本地、远程通道:-55 ℃~150 ℃
• 本地测温精度:±1.0°C
• 远程测温精度:±2.0°C
• 本地、远程测温分辨率:0.0625°C (12 Bits )
• 封装:DFN-8 / WSON-8
• 电源电压:1.7 V ~ 5.5 V
• 低静态电流
正常工作:27μA (0.0625Hz )
165μA (16Hz )
关断模式:3μA
• 数字输出:兼容SMBus 、I 2 C接口
• 芯片功能
— 串联电阻消除
— η 因子和测温偏 移 校正
— 可编程数字滤波器
— 远程测温二极管误连接检测
二、引 脚 配 置 和 功 能
三、典型电路连接
注:GX451 在实现远程测温时,需在 D+ 和 D- 引脚间接入一个远程测温探头。该测温探头可以为 NPN管、PNP 管或二极管。根据远程测温原理,无论使用 NPN 管或 PNP 管,只要将 BJT 的基极-发射极结用于远程温度感应即可。需要注意的是,若采用 NPN 管作为远程测温探头,NPN 须为二极管连接;若采用PNP 管,则可以是二极管连接或晶体管连接。
四、芯片特性说明
4.1、测温数据格式
GX451默认工作在标准测温模式下,在标准测温模式中任何低于 0°C 的温度值均表示为 00h,高于 127°C的温度值均表示为 7Fh。通过将配置寄存器的 RANGE 位写为 1,GX451 可实现在扩展测温范围内进行测温,测温范围和数据格式将在下一次温度转换时变为扩展模式。在扩展测温模式中得到的测温结果是在标准测温模式结果的基础上加 64(40h)得到的,测温范围增至-55°C~150°C。
GX451的本地和远程测温结果均使用两个字节表示,高字节的分辨率为 1°C,用来存储温度的整数部分;低字节的分辨率为0.0625°C,用来存储温度的小数部分。
4.2、读写操作
GX451 与 SMBus 接口兼容,其从机地址固定为 4Ch(1001 100b)。
GX451 写命令时序如下:
GX451 读命令时序如下:
4.3、寄存器
五、驱动代码
gx451.c
#include "gx451.h"
#include "delay.h"
#include "usart.h"
/*******************************************************************************************************************************************************/
/*******************************************************IIC_IO口初始化*************************************************************************************/
/*******************************************************************************************************************************************************/
void IIC_Init(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD ; //开漏输出
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB, &GPIO_InitStructure);
GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7);
}
void IIC_SCL(uint8_t state)
{
if(state==0) GPIO_ResetBits(GPIOB,GPIO_Pin_6);
else if(state==1) GPIO_SetBits(GPIOB,GPIO_Pin_6);
}
void IIC_SDA(uint8_t state)
{
if(state==0) GPIO_ResetBits(GPIOB,GPIO_Pin_7);
else if(state==1) GPIO_SetBits(GPIOB,GPIO_Pin_7);
}
uint8_t READ_SDA(void)
{
return GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7);
}
/*******************************************************************************************************************************************************/
/*******************************************************IIC基础时序*************************************************************************************/
/*******************************************************************************************************************************************************/
//产生IIC起始信号
void IIC_Start(void)
{
IIC_SDA(1);
IIC_SCL(1);
delay_us(15);
IIC_SDA(0);
delay_us(15);
IIC_SCL(0);
}
//产生IIC停止信号
void IIC_Stop(void)
{
IIC_SCL(0);
IIC_SDA(0);
delay_us(15);
IIC_SCL(1);
delay_us(15);
IIC_SDA(1);
delay_us(15);
}
//等待应答信号到来
//返回值:1,接收应答失败
// 0,接收应答成功
/*等待接收应答的器件,首先把sda,scl拉高,
如果一直为高 说明接受的是非应答信号(NACK或者代表接收失败),
如果sda被拉为低电平代表接收到了应答信号,
*/
uint8_t IIC_Wait_Ack(void)
{
uint8_t ucErrTime=0;
IIC_SDA(1);
IIC_SCL(1);delay_us(5);
while(READ_SDA())
{
ucErrTime++;
if(ucErrTime>1)
{
IIC_Stop();
return 1;
}
}
IIC_SCL(0);//时钟输出0
return 0;
}
//产生ACK应答
void IIC_Ack(void)
{
IIC_SCL(0);
delay_us(5);
IIC_SDA(0);
delay_us(5);
IIC_SCL(1);
delay_us(5);
IIC_SCL(0);
}
//不产生ACK应答
void IIC_NAck(void)
{
IIC_SCL(0);
delay_us(5);
IIC_SDA(1);
delay_us(5);
IIC_SCL(1);
delay_us(5);
IIC_SCL(0);
}
//IIC发送一个字节
void IIC_Send_Byte(uint8_t txd)
{
uint8_t t;
IIC_SCL(0);
for(t=0;t<8;t++)
{
if((txd&0x80)>>7)
IIC_SDA(1);
else
IIC_SDA(0);
txd<<=1;
delay_us(5);
IIC_SCL(1);
delay_us(5);
IIC_SCL(0);
delay_us(5);
}
IIC_SDA(1);
}
//读1个字节,ack=1时,发送ACK,ack=0,发送nACK
uint8_t IIC_Read_Byte(unsigned char ack)
{
unsigned char i,receive=0;
IIC_SDA(1);
for(i=0;i<8;i++ )
{
IIC_SCL(0);
delay_us(5);
IIC_SCL(1);
receive<<=1;
if(READ_SDA())receive++;
delay_us(5);
}
if (!ack) IIC_NAck();//发送nACK
else IIC_Ack(); //发送ACK
return receive;
}
/*******************************************************************************************************************************************************/
/*******************************************************GX451读写*************************************************************************************/
/*******************************************************************************************************************************************************/
//GX451从指定寄存器读取数据
//w_addr :从机地址(写)
//point_reg:寄存器地址
//r_addr :从机地址(读)
uint8_t GX451_Read_Register(uint8_t w_addr,uint8_t point_reg,uint8_t r_addr)
{
u8 value;
IIC_Start();
delay_us(10);
IIC_Send_Byte(w_addr); IIC_Wait_Ack(); //W_ADDR
delay_us(5);
IIC_Send_Byte(point_reg); IIC_Wait_Ack(); //pointer
delay_us(5);
IIC_Stop();
delay_us(10);
IIC_Start();
delay_us(10);
IIC_Send_Byte(r_addr); IIC_Wait_Ack(); //R_ADDR
delay_us(5);
value = IIC_Read_Byte(0);
delay_us(10);
IIC_Stop();
return value;
}
//GX451向指定寄存器写入数据
//w_addr :从机地址(写)
//point_reg:寄存器地址
//data1 :写入数据
void GX451_Write_Register(uint8_t w_addr,uint8_t point_reg,uint8_t data1)
{
IIC_Start();
delay_us(10);
IIC_Send_Byte(w_addr); IIC_Wait_Ack(); //W_ADDR
delay_us(5);
IIC_Send_Byte(point_reg); IIC_Wait_Ack(); //pointer
delay_us(5);
IIC_Send_Byte(data1); IIC_Wait_Ack(); //data
delay_us(10);
IIC_Stop();
}
//读GX451温度
//mode=0:正常模式读温,mode=1:扩展模式读温
void GET_GX451_TEMP(u8 mode)
{
uint8_t temp_LH, temp_LL ,temp_RH, temp_RL;
int16_t temp_Local, temp_Remote;
//读本地温度
temp_LH = GX451_Read_Register(0x98,0x00,0x99); //高字节
temp_LL = GX451_Read_Register(0x98,0x15,0x99); //低字节
//读远程温度
temp_RH = GX451_Read_Register(0x98,0x01,0x99); //高字节
temp_RL = GX451_Read_Register(0x98,0x10,0x99); //低字节
temp_Local =(int16_t)((temp_LH<<8)|temp_LL);
temp_Remote=(int16_t)((temp_RH<<8)|temp_RL);
printf("\r\nTEMP_LOCAL = %#X\r\n",temp_Local); //本地温度原码
printf("\r\nTEMP_REMOTE = %#X\r\n",temp_Remote);//远程温度原码
if(mode==0) //正常模式读温
{
printf("\r\nTEMP_LOCAL = %f\r\n", (temp_Local>>4)*0.0625);
printf("\r\nTEMP_REMOTE = %f\r\n", (temp_Remote>>4)*0.0625);
}
else if(mode==1) //扩展模式读温
{
printf("\r\nTEMP_LOCAL = %f\r\n", (temp_Local>>4)*0.0625-64);
printf("\r\nTEMP_REMOTE = %f\r\n", (temp_Remote>>4)*0.0625-64);
}
}
gx451.h
#ifndef __GX451_H
#define __GX451_H
#include "stdint.h"
void IIC_Init(void);
void IIC_SCL(uint8_t state);
void IIC_SDA(uint8_t state);
uint8_t READ_SDA(void);
void IIC_Start(void);
void IIC_Stop(void);
uint8_t IIC_Wait_Ack(void);
void IIC_Ack(void);
void IIC_NAck(void);
void IIC_Send_Byte(uint8_t txd);
uint8_t IIC_Read_Byte(unsigned char ack);
uint8_t GX451_Read_Register(uint8_t w_addr,uint8_t point_reg,uint8_t r_addr);
void GX451_Write_Register(uint8_t w_addr,uint8_t point_reg,uint8_t data1);
void GET_GX451_TEMP(u8 mode);
#endif
欢迎各位伙伴咨询、测试GX451,有任何问题可随时沟通交流。
作者:weixin_44250170