Tmp112数字温度传感器

前言

       前面介绍了IIC通信原理(专栏 -> 串行通讯原理 -> 串行通讯 -- IIC通讯原理),TMP112是一款IIC通信的数字温度传感器,本篇通过TMP112数字温度传感器讲解IIC通信的应用方法。

一、TMP112介绍

1、器件地址和读写

       IIC通信可以接多个从机,从机识别是7bit器件地址。TMP112器件地址和硬件连接有关,通过不同的连接,一条IIC总线可以连接几个TMP112。

器件地址

A0连接

1001000(0x48)

GND

1001001(0x49)

扫描二维码关注公众号,回复: 14727241 查看本文章

V+

1001010(0x4A)

SDA

1001011(0x4B)

SCL

       IIC主机发送给从机的第一个字节格式是器件地址(7bit)+ 写/读(1bit)。所以A0接GND实际地址0x90是写,0x91是读。其他地址类似。

2、寄存器

TMP112寄存器地址如下:

寄存器地址

寄存器

0

温度寄存器

1

配置寄存器

2

下限寄存器

3

上限寄存器

       IIC主机发送给从机的第二个字节是寄存器地址,表示需要写/读的是哪个单元或功能。对于TMP112,一般是读地址0的温度寄存器。

二、通信时序

       下图是技术规格书的写时序,格式是:开始+器件地址(写)+寄存器地址+数据1+数据2+结束。

       下图是技术规格书的读时序,格式是:

       开始+器件地址(写)+寄存器地址(写)+结束

       开始+器件地址(读)+数据1+数据2+停止。

三、例程

/***************************************

*I2C IO口定义 SCL SDA

***************************************/

#define  SDA_HI GPIO_Init_Input(I2C_SDA) //SDA高,配置输入,通过上拉电阻拉高  

#define  SDA_LO GPIO_Output_Off(I2C_SDA) //SDA低

#define  SCL_HI  GPIO_Init_Input(I2C_SCL) //SCL高

#define  SCL_LO  GPIO_Output_Off(I2C_SCL) //SCL低

/***************************************

*I2C 地址定义

***************************************/

#define  I2C_ADDR_TMP112   0x90    

/***************************************

*I2C 延时定义

*延时2US,时钟频率250KHz,降低频率延时增加。频率最高400KHz

*250K = 1000000/(2+2)

*此延时单片机16M,单周期指令1/16M=62.5ns

***************************************/

void DELAY_2US(void)

{

int delay_time = 100000;

while(delay_time--);

}

/***************************************

*I2C start

***************************************/

void I2CStart(void)

{

    SCL_HI;  

    DELAY_2US();

    SDA_LO;  //SDA高->低(start)

    DELAY_2US();

    SCL_LO;  

    DELAY_2US();

}

/***************************************

*I2C stop

***************************************/

void I2CStop(void)

{

    SDA_LO;  

    DELAY_2US();

    SCL_HI;  //SCL置高,SCL高电平时,SDA低->高(stop)

    DELAY_2US();

    SDA_HI;  

    DELAY_2US();

}

/***************************************

*I2C 向从设备发送一个字节

*_dat 写入的值

***************************************/

void I2C_SendByte(unsigned char _dat)

{

    unsigned char  i;

   

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

    {

  SCL_LO;

        if(_dat & 0x80)

        {

            SDA_HI; //输出高

        }

        else

        {

            SDA_LO; //输出低

        }

        DELAY_2US();

        SCL_HI;     

        DELAY_2US();

       _dat <<= 1;  //下个BIT,

    }

    SCL_LO;

    SDA_HI;

    DELAY_2US();

    SCL_HI; //第9个应答BIT时钟,注:主机不判断从机ACK信号

    DELAY_2US();

    SCL_LO;

}

/***************************************

*I2C 读一个字节

*返回读取值

***************************************/

unsigned char I2C_ReadByte(unsigned char _ack)

{

    unsigned char i,Dat;

    

Dat = 0;

SDA_HI;

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

{

    DELAY_2US();

    SCL_HI;     

    Dat <<= 1;

    if(GPIO_Input_Read(I2C_SDA)) //判断SDA高低

     {

         Dat |= 0x01;

        }

    DELAY_2US();

    SCL_LO;     

    }

    if(_ack)

{

SDA_LO; //输出低

}

else

{

 SDA_HI; //输出高

}

    DELAY_2US();

    SCL_HI;    

    DELAY_2US();

    SCL_LO;

    SDA_HI;

    return(Dat);   

}

/**********************************************************

*写N字节到TMP112对应地址

* dev_addr器件地址,是固定的。

*_addr从设备寄存器地址,_dat写入值

***********************************************************/

void I2C_WriteTMP112(unsigned char dev_addr, unsigned char _addr, unsigned char *_dat , unsigned char num)

{

    I2CStart();

I2C_SendByte(dev_addr);

I2C_SendByte(_addr);

while(num--)

{

I2C_SendByte(*_dat--);

}

I2CStop();

}

/**********************************************************

*读TMP112对应地址N字节

*_addr 读地址

*返回读取值

***********************************************************/

unsigned char ReadByte24C02(unsigned char dev_addr, unsigned char _addr, unsigned char *_dat , unsigned char num)

{

    unsigned char Dat;

    

    I2CStart();

I2C_SendByte(dev_addr);

I2C_SendByte(_addr);

    DELAY_2US();

    I2CStart();

I2C_SendByte(dev_addr + 1);

while(num--)

{

if(num)

{

*_Dat++ = I2C_ReadByte(1);

}

else

{

*_Dat++ = I2C_ReadByte(0);

}

}

I2CStop();

return(Dat);

}

/**********************************************************

*读TMP112温度

*返回读取值

***********************************************************/

unsigned char read_temp(void)

{

unsigned char temp[2];

int temphi,templo;

ReadByte24C02(I2C_ADDR_TMP112,0,temp,2);

temphi = temp[0];

temphi <<= 4;

templo = temp[1];

templo >>= 4;

temphi += templo;

temphi /= 16;

return (unsigned char)temphi;

}

猜你喜欢

转载自blog.csdn.net/ccwaff/article/details/127769244