适用于基于STM32F103、STM32F407核心板的
三轴加速度计传感器
大气压力传感器
磁场强度传感器
光照强度传感器
一、IIC通信协议
1、I2C简介:
I2C总线是由Philips公司开发的一种简单、双向二线制同步串行总线。它只需要两根线即可在连接于总线上的器件之间传送信息。 SDA(串行数据线)和SCL(串行时钟线)都是双向I/O线,接口电路为开漏输出.需通过上拉电阻接电源VCC.当总线空闲时.两根线都是高电平,连接总线的外同器件都是CMOS器件,输出级也是开漏电路.在总线上消耗的电流很小,因此,总线上扩展的器件数量主要由电容负载来决定,因为每个器件的总线接口都有一定的等效电容.而线路中电容会影响总线传输速度.当电容过大时,有可能造成传输错误.所以,其负载能力为400pF,因此可以估算出总线允许长度和所接器件数量。
2、I2C总线特点:
在硬件上,I2C总线只需要一根数据线和一根时钟线两根线,总线接口已经集成在芯片内部,简化了硬件电路PCB布线,降低了系统成本,提高了系统可靠性。
I2C总线是一个真正的多主机总线,如果两个或多个主机同时初始化数据传输,可以通过冲突检测和仲裁防止数据破坏,每个连接到总线上的器件都有唯一的地址,任何器件既可以作为主机也可以作为从机,但同一时刻只允许有一个主机。数据传输和地址设定由软件设定,非常灵活。总线上的器件增加和删除不影响其他器件正常工作。
3、I2C通信协议:
空闲状态:
I2C总线总线的SDA和SCL两条信号线同时处于高电平时,规定为总线的空闲状态。
此时各个器件的输出级场效应管均处在截止状态,即释放总线,由两条信号线各自的上拉电阻把电平拉高。
起始位与停止位的定义:
起始信号:当SCL为高电平时,SDA由高电平到低电平的跳变;启动信号是一种电平跳变时序信号,而不是一个电平信号。
停止信号:当SCL为高电平时,SDA由低电平到高电平的跳变;停止信号也是一种电平跳变时序信号,而不是一个电平信号。
ACK:
发送器每发送一个字节,就在时钟脉冲9期间释放数据线,由接收器反馈一个应答信号。应答信号为低电平时,规定为有效应答位(ACK简称应答位),表示接收器已经成功地接受了该字节;应答信号为高电平时,规定为非应答位(NACK),一般表示接收器接收该字节没有成功。
数据有效性:
I2C总线进行数据传送时,时钟信号为高电平期间,数据线上的数据必须保持稳定,只有在时钟线上的信号为低电平期间,数据线上的高电平或低电平状态才允许变化。
数据的传送:
在I2C总线上传送的每一位数据都有一个时钟脉冲相对应(或同步控制),即在SCL串行时钟的配合下,在SDA上逐位地串行传送每一位数据。数据位的传输是边沿触发。
工作过程:
总线上的所有通信都是由主控器引发的。在一次通信中,主控器和被控器总是在扮演着两种不同的角色。在通信之初,主从机必须根据自己的要求约定好通信规则:command的定义和位置、address的位数和位置。
以读写从机寄存器数据为例:
假设从机寄存器地址为8位、从机寄存器也位8位(被读取数据为8位);
约定读command为0x01,写command位0x02;约定主机发起通信后,第一个slave address字节收到ack后,紧跟的一个字节为command,再下面一个字节为address。
二、代码实现
一、读寄存器数据步骤:
主机先发起一次通信,将读command(0x01)和需要读取的寄存器地址address写入从机;(主机发出写操作)。
从机firmware的处理:
将command和address分别提取出来;
判断command的含义(本例中,是读指令还是写指令);
根据收到的的address,将对应寄存器的的数据放入从机I2C输出buffer;(这个步骤可以使用指针)。
主机再次发起一次通信,读取从机的数据;(主机发出读操作)。
二、读取数据代码实现示例
/* 第1步:发起I2C总线启动信号 */
BSP_MyIIC_Start();
/* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
BSP_MyIIC_SendByte(BH1750_Addr | I2C_RD);/* 此处是读指令 */
/* 第3步:发送ACK */
if (BSP_MyIIC_WaitAck() != 0)
{
goto cmd_fail;/* 器件无应答 */
}
/* 第4步:读取数据 */
Result = BSP_MyIIC_ReadByte();/* 读高字节 */
BSP_MyIIC_Ack();/* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */
Result = (Result<<8) | BSP_MyIIC_ReadByte();/* 读低字节 */
BSP_MyIIC_NAck();/* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
/* 发送I2C总线停止信号 */
BSP_MyIIC_Stop();
return Result;/* 执行成功 */