灵动微电子 · 2023年11月06日

灵动微课堂 (第272讲)|基于MM32F0140的I2C与24C02通信

前提

Mini_F0140原理图上I2C连接着24C02:

image.png

一.IIC介绍

I2C(Inter-Integrated Circuit)是一种通用的总线协议,实现I2C需要两根信号线完成信息交换,SCL时钟作为信号线,SDA作为数据输入/输出线。I2C属于同步通信,由于输入输出数据均使用一根线,因此通信方向为半双工。

主要特征有:

  1. I2C 总线协议转换器/并行总线
  2. 半双工同步操作
  3. 支持主从模式
  4. 支持 7 位和 10 位地址格式
  5. 支持起始(START)、停止(STOP)、重新起始(RESTART)以及应答(ACK)信号的生成和检测
  6. 支持标准模式(最大 100Kbps)、快速模式(最大 400Kbps)
  7. 分别有 2 字节的发送和接收缓冲
  8. 支持过滤毛刺功能
  9. 支持 DMA 操作
  10. 支持中断和查询操作
  11. 支持多个从地址(详细见用户手册)

下图为信号变化及其特定含义:

image.png

当主发送器如下图所示传输数据时,从接收器在接收到的每个字节后产生一个 ACK 来响应主发送器。

image.png

二.24C02

24C02是低工作电压的2K位串行电可擦除只读存储器,内部组织为256个字节,每个字节8位,该芯片被广泛应用于低电压及低功耗的工商业领域。

主器件通过发送一个起始信号启动发送过程,然后发送它所要寻址的从器件的地址。8位从器件地址的高4位固定为1010。接下来的3位(A2、A1、A0)为器件的地址位。当接收数据时,与I2C连接的从器件名为0xA0。

三.例程

向从机写数据后,再读取数据。

1. I2C配置

RCC_APB1PeriphClockCmd(RCC_APB1ENR_I2C1, ENABLE);
    I2C_StructInit(&I2C_InitStruct);
    //Configure I2C as master mode
    I2C_InitStruct.Mode = I2C_CR_MASTER;
    I2C_InitStruct.OwnAddress = 0;
    I2C_InitStruct.Speed = I2C_CR_STD;
    I2C_InitStruct.ClockSpeed = 100000;
    I2C_Init(I2Cx, &I2C_InitStruct);
    I2C_Send7bitAddress(I2Cx, 0xA0, I2C_Direction_Transmitter);
    I2C_Cmd(I2Cx, ENABLE);

2. 定义24C02结构体

typedef struct {
    u8 busy;
    u8 ack;
    u8 fault;
    u8 opt;
    u8 sub;
    u8 cnt;
    u8* ptr;
    u8 sadd;
} gEepromTypeDef;

3. 写数据

EEPROM_WriteByte(sub);
    while (cnt --) {
        EEPROM_WriteByte(*ptr);
        ptr++;
    }
    I2C_GenerateSTOP(I2C1, ENABLE);
    while((I2C_GetITStatus(I2C1, I2C_IT_STOP_DET)) == 0);
    gEeprom.ack = true;
    gEeprom.busy = false;
    EEPROM_WaitEEready();
    return true;

4. 读数据

u8 i, flag = 0, _cnt = 0;
    for (i = 0; i < gEeprom.cnt; i++) {
        while(1) {
            //Write command is sent when RX FIFO is not full
            if ((I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFNF)) && (flag == 0)) {
                I2C_ReadCmd(I2C1);
                _cnt++;
                if (_cnt == gEeprom.cnt)
                    flag = 1;
            }
            //Check receive FIFO not empty
            if (I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_RFNE)) {
                gEeprom.ptr[i] = I2C_ReceiveData(I2C1);
                break;
            }
        }
    }

5. 结果

image.png

作者:灵动MM32MCU
文章来源:灵动MM32MCU

推荐阅读

更多MM32F5系列资料请关注灵动MM32 MCU专栏。如想进行MM32相关芯片技术交流,请添加极术小姐姐微信(id:aijishu20)加入微信群。
推荐阅读
关注数
6144
内容数
276
灵动MM32 MCU相关技术知识,欢迎关注~
目录
极术微信服务号
关注极术微信号
实时接收点赞提醒和评论通知
安谋科技学堂公众号
关注安谋科技学堂
实时获取安谋科技及 Arm 教学资源
安谋科技招聘公众号
关注安谋科技招聘
实时获取安谋科技中国职位信息