【裸机开发】I2C 通信接口(三)—— I2C 底层驱动接口实现

I2C总线通信:初始化与数据读写实现
该文详细介绍了I2C总线的初始化步骤,包括设置时钟源和分频,以及如何产生开始、重复开始和停止信号。接着,文中阐述了在阻塞模式下向总线发送和从总线读取数据的实现方法,涉及中断处理和错误检测。最后,提供了一个统一的数据传输接口,该接口支持读写操作并涵盖了整个通信流程。

目录

一、I2C 初始化

二、产生开始 / 停止信号

1、开始信号

2、重复开始信号

3、停止信号

三、向总线上发送数据(阻塞模式)

四、从总线上读取数据(阻塞模式)

五、整合:数据读写统一调用接口


一、I2C 初始化

初始化步骤如下:

  • 时钟源配置。PERCLK_CLK_ROOT 的时钟源是 66MHz
  • 关闭 I2C。在配置 I2C 相关寄存器时,我们需要先将 I2C 关闭
  • 分频。分频的目的是控制 I2C 的传输速率(如果要控制 I2C 的速率为 100K,可以640 分频)
  • 开启 I2C 

/* i2c 初始化 */
void i2c_init()
{
    // 时钟源的初始化放到了时钟初始化(CCM_init)

    // 关闭I2C
    I2C1_I2CR &= ~(1 << 7);
    // 设置分频值(分频值为 640)
    I2C1_IFDR = 0x15;
    // 打开I2C
    I2C1_I2CR |= (1 << 7);
}

 

二、产生开始 / 停止信号

1、开始信号

当总线空闲时,总线上的设备可以发送开始信号来占用总线。如果存在多个设备同时占用总线,此时就会发生冲裁。

  • 判断总线是否空闲
  • 设为主机模式,设为发送模式
  • 发送要通信的设备地址和通信方向
/* 产生开始信号 */
i2c_status_t i2c_master_start(unsigned char address, i2c_direction direction)
{
    /* 总线是否被占用 */
    if (is_bus_busy())
    {
        return Status_I2C_Busy;
    }

    /* 
     * 发送开始信号
     * bit 5: 1 主机
     * bit 4: 1 发送
     */
    I2C1_I2CR |= ((1 << 4) | (1 << 5));

    /* 发送通信地址和通信方向 */
    I2C1_I2DR = (((unsigned int)address << 1) | (direction == I2C_Read ? 1 : 0));

    return Status_I2C_Success;
}

2、重复开始信号

当某个设备在通信时,可能会需要临时改变通信方向,此时就可以发送一个重复开始信号来改变通信方向。发送重复开始信号要求总线空闲,且当前设备是主机,只要有一者不满足,就会发送失败

  • 判断主机是否空闲,且当前设备是否为主机模式
  • 发送一个重复开始信号
  • 发送通信地址和通信方向
/* 重复产生开始信号(可能是修改通信方向、通信设备的地址) */
i2c_status_t i2c_master_repeated_start(unsigned char address, i2c_direction direction)
{
    /* 
     * 总线是否被占用
     *  - 如果是其他设备占用总线,直接返回
     *  - 如果是当前设备占用总线,发送一个重复的开始信号
     */
    if (is_bus_busy() && is_master() == 0)
    {
        return Status_I2C_Busy;
    }

    /* 产生一个重复开始信号 */
    I2C1_I2CR |= ((1 << 2) | (1 << 4));

    /* 发送通信地址和通信方向 */
    I2C1_I2DR = (((unsigned int)address << 1U) | (direction & 0x01));

    return Status_I2C_Success;
}

 

3、停止信号

当主机打算继续通信时,可以发送一个停止信号来结束通信;如果从机不想继续通信,可以选择不回应主机表示想结束通信。

    <
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值