硬件I2C通信协议

目录

一、简介

二、物理层

三、协议层

 四、I2C在单片机的初始化

初始化过程:

I2C写一个字节数据:


一、简介

I2C全称为Integer Integrated Circuit,由于它的引脚少,硬件连接简单,所以很多时候都使用I2C来进行不同模块之间的通信,虽然速度没有SPI块。

I2C只使用了一根数据总线SDA和一根时钟总线SCL,属于串行通信,采用半双工通信

二、物理层

I2C的连接方式如下图所示:

  1. I2C支持多设备通信,同一时间只能有一个主机和从机进行通信,每个设备都会由一个独立的地址,可以是7位或10位
  2. 总线通过上拉电阻接到电源,当设备空闲时会输出高阻态,当所有设备都空闲时,由上拉电阻把总线拉成高电平,I2C就是利用这种特性,所以使用时把引脚设为复用开漏输出模式,输出信号源于I2C外设
  3. 设备空闲时输出高阻态是为了不干扰其他设备的通信,如果空闲时输出低电平,当其他数据发送数据1时,就会发生短路,烧坏设备。
  4. I2C具有三种传输模式:
  • 标准模式:传输速率100kbit/s
  • 快速模式:传输速率400kbit/s
  • 高速模式:传输速率3.4Mbit/s(大多还不支持)

三、协议层

  • I2C读写过程:

  1. 开始信号S:在SCL信号为高时(空闲时SCL为高),SDA从高电平到低电平转变
  2. SLAVE ADDRESS:将要通信的从机的地址总上SDA总线,该地址可以是7位或是10位
  3. R/W:表示数据传送方向,1表示从从机读取数据,0表示向从机写数据,常跟地址数据一起发送,组成8位数据
  4. A:从机向主机发送应答信号,才能继续向下进行
  5. DATA:接受到应答信号后开始发送数据,一次发送8位数据。数据发送完成后如果收到从机的应答信号(ACK),则会继续发送数据,直到收到非应答信号(NACK)或主机发送停止信号
  6. 停止信号P:在SCL保持高电平时,SDA由低电平向高电平转变
  • 数据的有效性:

SDA在SCL的一个时钟周期内传输一位数据,在SCL为高时数据有效,此时SDA为高表示1,为低时表示0;在SCL为低时SDA数据无效,一般在这个时候进行电平切换。

用9个时钟周期传输8位数据,第9个时钟周期是应答信号。

 四、I2C在单片机的初始化

初始化过程:
    //配置i2c引脚
    I2C_InitTypeDef i2c_congig = {0};

    RCC_APB1PeriphClockCmd(RCC_I2C_CLOCK, ENABLE);
    i2c_congig.I2C_Mode = I2C_Mode_I2C;//i2c模式
    i2c_congig.I2C_ClockSpeed = 100000;//标准模式:100kHz    快速模式:400kHz
    i2c_congig.I2C_DutyCycle = I2C_DutyCycle_2;//Tlow/Thigh = 2
    i2c_congig.I2C_Ack = I2C_Ack_Enable;//使能应答信号
    i2c_congig.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//7位地址
    i2c_congig.I2C_OwnAddress1 = MASTER_ADDRESS;//i2c地址
    I2C_Init(I2C_TYPE,&i2c_congig);

    //开启i2c
    I2C_Cmd(I2C_TYPE,ENABLE);
I2C写一个字节数据:
/***********************************************
* @brief : I2C向指定地址写入一个字节数据(8位)
* @param : addr:写入的地址
*          data:写入的数据
* @return: void
* @date  : 2023.9.17
* @author: L
************************************************/
void I2C_WriteByte(uint8_t addr,uint8_t data)
{
    while(I2C_GetFlagStatus(I2C_TYPE,I2C_FLAG_BUSY));//总线忙,则等待
    I2C_GenerateSTART(I2C_TYPE,ENABLE);//空闲时产生起始信号位

    while(!I2C_CheckEvent(I2C_TYPE,I2C_EVENT_MASTER_MODE_SELECT));//起始信号位还没送上I2C总线,则等待
    I2C_Send7bitAddress(I2C_TYPE,SLAVE_ADDRESS,I2C_Direction_Transmitter);//广播从机地址,确认主机为发送模式

    while(!I2C_CheckEvent(I2C_TYPE,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));//等待从机应答
    I2C_SendData(I2C_TYPE,addr);//发送寄存器地址

    while(!I2C_CheckEvent(I2C_TYPE,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待数据发送完成
    I2C_SendData(I2C_TYPE,data);//发送数据

    while(!I2C_CheckEvent(I2C_TYPE,I2C_EVENT_MASTER_BYTE_TRANSMITTED));//等待数据发送完成
    I2C_GenerateSTOP(I2C_TYPE,ENABLE);//产生停止信号位
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值