Tmp112数字温度传感器
前言
? ? ? ?前面介紹了IIC通信原理(專欄 -> 串行通訊原理 -> 串行通訊 -- IIC通訊原理),TMP112是一款IIC通信的數字溫度傳感器,本篇通過TMP112數字溫度傳感器講解IIC通信的應用方法。
一、TMP112介紹
1、器件地址和讀寫
? ? ? ?IIC通信可以接多個從機,從機識別是7bit器件地址。TMP112器件地址和硬件連接有關,通過不同的連接,一條IIC總線可以連接幾個TMP112。
| 器件地址 | A0連接 |
| 1001000(0x48) | GND |
| 1001001(0x49) | 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;
}
總結
以上是生活随笔為你收集整理的Tmp112数字温度传感器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: LBS基站定位和GPS卫星定位对比
- 下一篇: 自动对焦模块理论基础及其硬件实现浅析(一