STM32学习100步之第四十九-五十一步——I²C总线协议及其应用

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); //
}

这里算法采用了技巧是利用&按位与操作,如果寄存器该位的值为1,则加上对应的权值,本质上是二进制数转十进制数的原理。

在这里插入图片描述

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值