I2C协议
一,简介
I2C(Inter-Integrated Circuit)是一种串行,半双工的通信协议,由数据线SDA和时钟线SCL两根信号线组成。这次实验使用的是STM32H750上的硬件I2C,也可以使用IO口模拟软件I2C。
二,I2C数据帧
1. 起始条件
SCL保持高电平期间,拉低SDA线的电平
2.结束条件
SCL保持高电平期间,将SDA线的电平拉高
3.发送一个字节
主机在SCL低电平期间将数据位放到SDA线上,然后释放SCL,随后从机在SCL高电平期间对SDA线上的电平信号进行读取,这样就发送了一位数据,相同的操作重复8次就发送了一个字节的数据。在SCL高电平期间,SDA线上的电平信号不能发生变化
4.接收一个字节
在接收数据之间,主机要释放SDA,然后在SCL低电平期间,从机将数据放到SDA线上,然后释放SCL,主机在SCL高电平期间读取数据。
5.发送应答
主机在接收一个字节过后,在下一个时钟里发送一位数据,0表示应答,1表示非应答
6.接收应答
主机在发送一个字节后释放SDA,并且在下一个时钟读取一位数据,判断从机是否应答,0表示应答,1表示非应答
7.空闲状态
SCL与SDA线都处于高电平,则总线处于空闲状态,总线电平被上拉电阻拉高
8.写通讯操作
主机先发出1位起始信号,7位从机地址和1位操作位(0表示读,1表示写)。然后从机接收到确认是自身的地址后发送1位应答,主机接收到应答引号后开始对从机发送数据,主机每发送一字节数据,接收依一次应答信号。最后发送一位停止数据位,写操作结束。
9.读通讯操作
读操作与写操作的过程相同,只有主机一直发送应答信号,从机才会一直发送数据。
三,AT24C02
AT24C02是一款2kbit的EEPROM存储芯片,具有掉电不丢失数据的功能,可以存储最多256个字节的数据,能保存100年。通过I2C总线进行读写操作,最快通讯速度可达400kHz。
24C02的地址前4位固定位1010,地址选择引脚默认接地,最后一位为0时表示写地址,最后一位为1时表示读地址,也就是说:
写地址:0xA0,读地址:0xA1
四,I2C的HAL配置
配置STM32上的I2C只需要在STM32CubeMX选择开启I2C即可
HAL库会将用到的IO口配置为复用开漏输出。
//向从机发送消息
HAL_I2C_Master_Transmit();
//接收来自从机的消息
HAL_I2C_Master_Receive ();
//向寄存器中写入
HAL_I2C_Mem_Write();
//从寄存器中读出
HAL_I2C_Mem_Read();
也可以使用中断和DMA的方式进行I2C通讯。
I2C写入AT24C02
调用此函数,可以向地址为addr的内存写入size长度的buf
uint8_t AT24C02_SendBuf(uint8_t addr,uint8_t* buf,uint16_t size)
{
int i;
uint8_t ret,ret1=1;
uint8_t remainder;
uint8_t count=size/8;
if(size%8!=0)
{
remainder=size%8;
}
for(i=0;i<count;i++)
{
ret=HAL_I2C_Mem_Write(&hi2c2,AT24CXX_Write_ADDR,addr+8*i,I2C_MEMADD_SIZE_8BIT,buf+8*i,8,0xFF);
if(ret!=HAL_OK)
{
break;
}
HAL_Delay(50);
}
if(remainder!=0)
{
ret1=HAL_I2C_Mem_Write(&hi2c2,AT24CXX_Write_ADDR,addr+8*(i+1),I2C_MEMADD_SIZE_8BIT,buf+8*(i+1),remainder,0xFF);
}
return ret&&ret1;
}
调用此函数,可以从地址为addr处的内存读取长度字节为size的数据存入到buf中
uint8_t AT24C02_RecvBuf(uint8_t addr,uint8_t* buf,uint16_t size)
{
return HAL_I2C_Mem_Read(&hi2c2,AT24CXX_Read_ADDR,addr,I2C_MEMADD_SIZE_8BIT,buf,size,0xFF);
}