ARM32开发——(十九)I2C原理

1. 重点

  • 理解I2C通讯原理
  • 理解I2C通讯过程中的信号
  • 理解软件I2C实现过程
  • 理解硬件I2C的工作内容

2. 主要内容

在消费电子、工业电子等领域,会使用各种类型的芯片,如微控制器、电源管理、显示驱动、传感器、存储器、转换器等,它们有着不同的功能。有时需要快速地进行数据交互。为了使用最简单的方式使这些芯片互联互通,I2C(Inter-Integrated Circuit)协议应运而生。

I2C协议(或称IIC)是由飞利浦(现在的恩智浦半导体)公司开发的一种通用的总线协议。它使用两根线(时钟线和数据线)来传输数据,支持多个设备共享同一条总线。 I2C协议通常用于连接微控制器、传感器、存储器和其他外围设备。

2.1 I2C通讯规则

I2C总线包括两根信号线:SDA(串行数据线)和SCL(串行时钟线)。这两根信号线共用一个总线,因此在总线上可以连接多个设备。在I2C总线上,每个设备都有一个唯一的地址,用于标识设备。

SCL线是时钟线,用于控制数据传输的速度和时序;SDA线是数据线,用于传输实际的数据.

2.2 I2C写操作

流程如下:

  • 开始。
  • 发送设备地址,等待从设备响应
  • 发送寄存器地址,等待从设备响应
  • 发送一个字节,等待从设备响应。这个操作是循环执行,直到没有数据。
  • 停止。

2.3 I2C读流程

流程如下:

  • 开始。
  • 发送设备地址(写地址),等待从设备响应
  • 发送寄存器地址,等待从设备响应。
  • 开始
  • 发送设备地址(读地址),等待从设备响应
  • 接收一个字节,发送响应给从设备。这个操作是循环执行,直到没有数据。当是最后一个数据时,发送空响应。
  • 停止。

2.4 通讯信号

2.4.1 开始

static void start() {
    SDA_OUT();

    SDA(1);
    delay_1us(5);
    SCL(1);
    delay_1us(5);

    SDA(0);
    delay_1us(5);
    SCL(0);
    delay_1us(5);
}
2.4.2 结束

static void stop() {
    SDA_OUT();

    SCL(0);
    SDA(0);

    SCL(1);
    delay_1us(5);
    SDA(1);
    delay_1us(5);
}
2.4.3 发送数据
2.4.3.1 bit发送

数据有效性:

  • SCL上升沿到下降沿这个阶段,SDA电平的高低,表示数据bit的1和0
  • 如果SDA电平在这个阶段发生变化,则无效,参考start和stop信号。
2.4.3.2 Byte发送

基于数据有效性,将byte按bit位变化为高低电平,发送出去。

static void send(uint8_t data) {
    uint8_t i;
    SDA_OUT();

    for(i = 0; i < 8; i++) {
        if(data & 0x80) {
            SDA(1);
        } else {
            SDA(0);
        }
        SCL(1);
        delay_1us(5);
        SCL(0);
        delay_1us(5);
        data <<= 1;
    }
}
2.4.4 等待响应

wait ack:Acknowledge character。表示等待响应,每发送一个数据,需要确认对方是否收到,就需要等待对方响应。

static uint8_t wait_ack() {
    int8_t retry = 10;

    SCL(0);
    SDA(1);
    SDA_IN();
    delay_1us(5);
    SCL(1);
    delay_1us(5);

    while(SDA_STATE() == 1 && retry > 0) {
        retry --;
        delay_1us(5);
    }

    if(retry <= 0) {
        stop();
        return 1;
    } else {
        SCL(0);
        SDA_OUT();
    }
    return 0;
}
2.4.5 接收数据
2.4.5.1 bit接收

2.4.5.2 Byte接收

static uint8_t recv() {
    uint8_t i, data;
    SDA_IN();
    data = 0;
    for(i = 0; i < 8; i++) {
        SCL(0);
        delay_1us(5);
        SCL(1);
        delay_1us(5);

        data <<= 1;

        data |= SDA_STATE();

        delay_1us(5);
    }
    SCL(0);
    return data;
}
2.4.6 发送响应

static void send_ack(){
	// 主机发送ACK响应
	
	// 主机获取SDA控制权,进入输出模式
	SDA_OUT();
	// 拉低SDA
	SDA(0);
	DELAY();
	
	// 拉高SCL
	SCL(1);
	DELAY();
	
	// 拉低SCL
	SCL(0);
	DELAY();	
}
static void send_nack(){
	// 主机发送NACK响应
	// 主机获取SDA控制权,进入输出模式
	SDA_OUT();
	// 拉高SDA
	SDA(1);
	DELAY();
	
	// 拉高SCL
	SCL(1);
	DELAY();
	
	// 拉低SCL
	SCL(0);
	DELAY();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值