中科银河芯GX112,PIN TO PIN兼容TMP102、TMP112、CT7112、NST112,附STM32驱动程序
一、资源说明
二、基本参数
三、参考驱动
四、注意事项
一、资源说明
1、前言
北京中科银河芯自主研发的GX112数字式温度芯片,它兼容 IIC 和 SMBus通信协议,采用全集的COMS工艺制造,具有低功耗、高精度、稳定性好、快速响应的优点。被广泛应用于笔记本电脑、工控主板温度监控;储能电源、便携式电源、服务器、存储器等温度监控场景。
2、温度测量原理
2.1 利用集成电路中的PN结感知温度的变化,将温度变化信息转变为电压信号的变化;
2.2 调理电路将温度相关的电压信号放大、补偿并用数模转化电路(ADC) 将温度相关的电压转化成一 一对应的数字量来表示温度;
2.3 通过通信接口与上位机进行交互,上位机将读出的数字量译码成温度量。
二、基本参数
三、参考驱动
1、GX112引脚功能
2、IIC器件地址
IIC总线上可以接多个从机进行通信,从机识别是 7bit 器件地址。GX112器件地址和地址选择引脚的硬件连接有关,通过不同的连接,一条IIC总线可以连接多个不同地址的GX112。
IIC主机发送给从机的第一个字节格式是器件地址(7bit)+ 写(0)/读(1)(1bit)。因此ADD0 接 GND 实际地址 0x90 是写操作,0x91是读操作。其他地址应用相类似。
3、 GX112配置寄存器
IIC主机发送给从机的第二个字节是寄存器地址,表示需要进行 写 / 读 操作芯片的功能。对于GX112而言,一般是读 0x00 温度寄存器读取温度的测量数据。
4、通信时序
4.1 GX112写时序
格式为:开始 + IIC器件地址(写)+ 寄存器地址 + 数据0 + 数据1 + 停止。
4.2 GX112读时序
格式为: 开始 + IIC器件地址(写)+ 寄存器地址(写)+ 停止;
开始 + IIC器件地址(读)+ 数据0 + 数据1 + 停止。
5、GX112参考应用电路
6、驱动例程
6.1 GX112.h
#ifndef _Gx112_H
#define _Gx112_H
#include "stm32f10x.h"
#include "string.h"
#include "stdio.h"
#include "usart.h"
#define I2C_SCL GPIO_Pin_4
#define I2C_SDA GPIO_Pin_5
#define GPIO_I2C GPIOA
#define I2C_SCL_H GPIO_SetBits(GPIO_I2C,I2C_SCL)
#define I2C_SCL_L GPIO_ResetBits(GPIO_I2C,I2C_SCL)
#define I2C_SDA_H GPIO_SetBits(GPIO_I2C,I2C_SDA)
#define I2C_SDA_L GPIO_ResetBits(GPIO_I2C,I2C_SDA)
void I2C_INIT(void);
void I2C_SDA_OUT(void);
void I2C_StarT(void);
void I2C_StoP(void);
void I2C_Ack(void);
void I2C_NAck(void);
u8 I2C_Wait_Ack(void);
void I2C_Send_Byte(u8 txd);
u8 I2C_Read_Byte(u8 ack);
void GX112_read_result1(u8 addr);
#endif
6.2 GX112.C
#include "Gx112.h"
#include "delay.h"
#define write 0
#define read 1
char Temp_buff[20] = {0};
/****************************************************************************
* Function Name : IIC_Config
* Description : 初始化GPIO.
* Input : None
* Output : None
* Return : None
****************************************************************************/
void I2C_INIT()
{
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitStructure.GPIO_Pin = I2C_SCL;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
I2C_SCL_H;
I2C_SDA_H;
}
/*******************************************************************************
* 函 数 名 : I2C_SDA_OUT
* 函数功能 : SDA输出配置
* 输 入 : 无
* 输 出 : 无
*******************************************************************************/
void I2C_SDA_OUT()
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_SDA;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
void I2C_SDA_in(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Pin = I2C_SDA;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;
GPIO_Init(GPIOA, &GPIO_InitStructure);
}
//IIC 产生起始信号
void I2C_StarT(void)
{
I2C_SDA_OUT();
I2C_SDA_H;
I2C_SCL_H;
delay_us(5);
I2C_SDA_L;
delay_us(6);
I2C_SCL_L;
}
//IIC 产生停止信号
void I2C_StoP(void)
{
I2C_SDA_OUT();
I2C_SCL_L;
I2C_SDA_L;
I2C_SCL_H;
delay_us(6);
I2C_SDA_H;
delay_us(6);
}
//IIC 主机产生应答信号ACK
void I2C_Ack(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_L;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//IIC 主机不产生应答信号NACK
void I2C_NAck(void)
{
I2C_SCL_L;
I2C_SDA_OUT();
I2C_SDA_H;
delay_us(2);
I2C_SCL_H;
delay_us(5);
I2C_SCL_L;
}
//IIC 等待从机应答信号
//返回值:1 接收应答失败
// 0 接收应答成功
u8 I2C_Wait_Ack(void)
{
u8 tempTime = 0;
I2C_SDA_in();//I2C_SDA_IN();
I2C_SDA_H;
delay_us(1);
I2C_SCL_H;
delay_us(1);
while(GPIO_ReadInputDataBit(GPIO_I2C, I2C_SDA))
{
tempTime++;
delay_us(1);
if(tempTime > 250)
{
I2C_StoP();
return 1;
}
}
I2C_SCL_L;
delay_us(1);
return 0;
}
//I2C 发送一个字节
void I2C_Send_Byte(u8 txd)
{
u8 i = 0;
I2C_SDA_OUT();
I2C_SCL_L;//拉低时钟开始数据传输
for(i = 0; i < 8; i++)
{
if((txd & 0x80) > 0) //0x80 1000 0000
I2C_SDA_H;
else
I2C_SDA_L;
txd <<= 1;
delay_us(1);
I2C_SCL_H;
delay_us(2); //发送数据
I2C_SCL_L;
delay_us(2);
}
}
//I2C 读取一个字节
u8 I2C_Read_Byte(u8 ack)
{
u8 i = 0, receive = 0;
I2C_SDA_in();
for(i = 0; i < 8; i++)
{
I2C_SCL_L;
delay_us(2);
I2C_SCL_H;
//while(!GPIO_ReadInputDataBit(GPIO_I2C,I2C_SCL));
receive <<= 1;
if(GPIO_ReadInputDataBit(GPIO_I2C, I2C_SDA))
receive++;
delay_us(1);
}
if(ack == 0)
I2C_NAck();
else
I2C_Ack();
return receive;
}
void GX112_read_result1(u8 addr)
{
short tem, hum;
u8 buff[6];
float Temperature = 0;
I2C_StarT();
I2C_Send_Byte(addr << 1 | write); //写7位I2C设备地址加0作为写取位,1为读取位
I2C_Wait_Ack();
I2C_Send_Byte(0x00);
I2C_Wait_Ack();
delay_us(20);
I2C_StarT();
I2C_Send_Byte(addr << 1 | read); //写7位I2C设备地址加0作为写取位,1为读取位
if(I2C_Wait_Ack() == 0)
{
buff[0] = I2C_Read_Byte(1);
buff[1] = I2C_Read_Byte(0);
I2C_StoP();
}
else
{
buff[0] = 0;
buff[1] = 0;
I2C_StoP();
}
if(buff[0] & 0x80)
{
tem = (buff[0] << 8) | buff[1] ;
hum = (((~tem) >> 4) + 1) & 0x0fff;
Temperature = -(float)(hum * 0.0625);
}
else
{
tem = (buff[0] << 8) | buff[1] ;
hum = tem >> 4;
Temperature = (float)(hum * 0.0625);
}
sprintf((char *) Temp_buff, "addr_0x%x : %3.2f", addr, Temperature);
printf("%s\n\r\n", Temp_buff);
tem = 0;
hum = 0;
}
/*/
#if 0
int main(void)
{
Hardware_Init();
while(1)
{
GX112_read_result1(0x48); //addr0->GND
}
}
#endif
*//