I²C通信协议
I²C底层协议较为复杂,其特点是只有一个主机(单片机),它和其他的从设备可以相互通信,而从设备之间无法直接相互通信。作为初学者只需要掌握初始化和调用函数即可,该总线的作用是单片机和各个芯片之间进行通信,它们之间的通信有一种协议。
连接原理图如下:
需要注意的是:I²C是板级总线一般不超过两米,所有的芯片和单片机必须共地,另外两条数据线需要连接上拉电阻,一般在1-10k在不同的电路中选取合适的值,达到最佳传输效果。
连接原理图如下:
作为初学者,只需要会调用I²C总线的驱动函数即可,调用程序如下:
void I2C_ Configuration(); //I2C初始化
void I2C_ SAND_ BUFFER(); //I2C发送数据串
void I2C_ SAND_ BYTE(); //I2C发送一个字节.
void I2C_ READ_ BUFFER(); //I2C读取数据串
u8 I2C_ READ_ BYTE(); //I2C读取一个字节
其中I2C_ Configuration()初始化函数中包含I2C接口初始化函数,不需要重新初始化接口。
I2C_READ_BYTE(u8 SlaveAddr,u8 readAddr)
该函数为读一个字节函数,第一个形参是单片机要读取某个芯片的地址,第二个是单片机要读取的芯片内部寄存器对于该芯片的地址,目的是读取该寄存器中的内容。
I2C_SAND_BYTE(u8 SlaveAddr,u8 writeAddr,u8 pBuffer)
该函数为写一个字节函数,第一个形参是单片机要写入的某个芯片的地址,第二个是单片机要写入的芯片内部寄存器对于该芯片的地址,目的是将内容写入该寄存器中,第三个是要写的内容。
I2C_READ_BUFFER(u8 SlaveAddr,u8 readAddr,u8* pBuffer,u16 NumByteToRead)
该函数是单片机从该芯片读取一个字符串,前两个形参和前面相同,后两个形参:第一个读取内容存放于指针所指内容的首地址,第二个形参是要读取字节的数目,通过指针的传递直接改变实参。
I2C_SAND_BUFFER(u8 SlaveAddr,u8 WriteAddr,u8* pBuffer,u16 NumByteToWrite)
该函数和上面函数基本形参意义相同,不同的是,该函数为发送函数。
温度传感器IM75A
对于初学者应用,只需要掌握两个函数即可,即函数如下:
void LM75A_GetTemp(u8 *Tempbuffer);//读温度
void LM75A_POWERDOWN(void); //掉电模式
相应的寄存器功能如下:
图中指针值便是该寄存器的地址。结合上面I²C的读写函数即可对该寄存器进行读写操作。
其中,读取温度函数和设置掉电模式方式分别如下:
void LM75A_GetTemp(u8 *Tempbuffer){
u8 buf[2]; //温度值储存
u8 t=0,a=0;
I2C_READ_BUFFER(LM75A_ADD,0x00,buf,2); //读出温度值(器件地址,子地址,数据储存器,字节数)
t = buf[0]; //处理温度整数部分,0~125度
*Tempbuffer = 0; //温度值为正值
if(t & 0x80){ //判断温度是否是负(MSB表示温度符号)
*Tempbuffer = 1; //温度值为负值
t = ~t; t++; //计算补码(原码取反后加1)
}
if(t & 0x01){ a=a+1; } //从高到低按位加入温度积加值(0~125)
if(t & 0x02){ a=a+2; }
if(t & 0x04){ a=a+4; }
if(t & 0x08){ a=a+8; }
if(t & 0x10){ a=a+16; }
if(t & 0x20){ a=a+32; }
if(t & 0x40){ a=a+64; }
Tempbuffer++;
*Tempbuffer = a;
a = 0;
t = buf[1]; //处理小数部分,取0.125精度的前2位(12、25、37、50、62、75、87)
if(t & 0x20){ a=a+12; }
if(t & 0x40){ a=a+25; }
if(t & 0x80){ a=a+50; }
Tempbuffer++;
*Tempbuffer = a;
}
//LM75进入掉电模式,再次调用LM75A_GetTemp();即可正常工作
//建议只在需要低功耗情况下使用
void LM75A_POWERDOWN(void){//
I2C_SAND_BYTE(LM75A_ADD,0x01,1); //
}