阿源玩电子 发表于 2025-6-25 22:02

【灵动微电子MM32F0121测评】5.I2C_EEPROM读写测试

I2C_EEPROM读写测试
1.原理图部分

2.基于MM32F0121,实现了I2C接口的EEPROM(AT24C系列)读写功能
I2C_BSP.C
#include "I2C_BSP.h"
#include <stdio.h>
#include <string.h>

#define EEPROM_I2C_ADDRESS      0xA0
#define EEPROM_PAGE_SIZE      0x08

void I2C_Configure(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;
    I2C_InitTypeDefI2C_InitStruct;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
    I2C_DeInit(I2C1);

    I2C_StructInit(&I2C_InitStruct);
    I2C_InitStruct.I2C_Mode       = I2C_MODE_MASTER;
    I2C_InitStruct.I2C_OwnAddress = I2C_OWN_ADDRESS;
    I2C_InitStruct.I2C_ClockSpeed = 100000;
    I2C_Init(I2C1, &I2C_InitStruct);

    I2C_TargetAddressConfig(I2C1, EEPROM_I2C_ADDRESS);

    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOB, ENABLE);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_1);
    GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_1);

    GPIO_StructInit(&GPIO_InitStruct);
    GPIO_InitStruct.GPIO_Pin   = GPIO_Pin_10 | GPIO_Pin_11;
    GPIO_InitStruct.GPIO_Speed = GPIO_Speed_High;
    GPIO_InitStruct.GPIO_Mode= GPIO_Mode_AF_OD;
    GPIO_Init(GPIOB, &GPIO_InitStruct);

    I2C_Cmd(I2C1, ENABLE);
}

void I2C_TxData_Polling(uint8_t *Buffer, uint8_t Length)
{
    for (uint8_t i = 0; i < Length; i++) {
      I2C_SendData(I2C1, Buffer);
      while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE)) {}
    }
}

void I2C_RxData_Polling(uint8_t *Buffer, uint16_t Length)
{
    for (uint16_t i = 0; i < Length; i++) {
      I2C_ReadCmd(I2C1);
      while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_RFNE)) {}
      Buffer = I2C_ReceiveData(I2C1);
    }
}

void EEPROM_WritePage(uint8_t Address, uint8_t *Buffer, uint8_t Length)
{
    I2C_TxData_Polling(&Address, 1);
    I2C_TxData_Polling(Buffer, Length);
    while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE)) {}
    I2C_GenerateSTOP(I2C1);
    while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE)) {}
}

void EEPROM_ReadData(uint8_t Address, uint8_t *Buffer, uint8_t Length)
{
    I2C_TxData_Polling(&Address, 1);
    I2C_RxData_Polling(Buffer, Length);
    I2C_GenerateSTOP(I2C1);
    while (RESET == I2C_GetFlagStatus(I2C1, I2C_STATUS_FLAG_TFE)) {}
}

void EEPROM_WriteData(uint8_t Address, uint8_t *Buffer, uint8_t Length)
{
    uint8_t Start = Address % EEPROM_PAGE_SIZE;
    uint8_t StartCount = 0, PageNumber = 0, FinalCount = 0;

    if (Start == 0) {
      PageNumber = Length / EEPROM_PAGE_SIZE;
      FinalCount = Length % EEPROM_PAGE_SIZE;
    } else {
      if ((Start + Length) <= EEPROM_PAGE_SIZE) {
            StartCount = Length;
      } else {
            StartCount = EEPROM_PAGE_SIZE - Start;
            PageNumber = (Length - StartCount) / EEPROM_PAGE_SIZE;
            FinalCount = (Length - StartCount) % EEPROM_PAGE_SIZE;
      }
    }

    if (StartCount) {
      EEPROM_WritePage(Address, Buffer, StartCount);
      Address += StartCount;
      Buffer+= StartCount;
      Delay_MS(50);
    }

    while (PageNumber--) {
      EEPROM_WritePage(Address, Buffer, EEPROM_PAGE_SIZE);
      Address += EEPROM_PAGE_SIZE;
      Buffer+= EEPROM_PAGE_SIZE;
      Delay_MS(50);
    }

    if (FinalCount) {
      EEPROM_WritePage(Address, Buffer, FinalCount);
    }
}

void I2C_Master_EEPROM_Polling_Sample(void)
{
    const char* targetString = "Hello 21ic, Hello MM32F0121";
    uint8_t len = strlen(targetString);
    uint8_t WriteBuffer;
    uint8_t ReadBuffer;
    uint8_t errors = 0;

    memset(ReadBuffer, 0, len);
    memcpy(WriteBuffer, targetString, len);

    I2C_Configure();
    EEPROM_WriteData(0, WriteBuffer, len);
    Delay_MS(50);
    EEPROM_ReadData(0, ReadBuffer, len);

    printf("\r\nEEPROM Write/Read Comparison (Length: %d bytes)\r\n", len);
    printf("Offset | Write Data   | Read Data      | Status\r\n");
    printf("-------+----------------+----------------+-----------\r\n");
   
    for (uint8_t i = 0; i < len; i++) {
      uint8_t writeVal = WriteBuffer;
      uint8_t readVal = ReadBuffer;
      char writeChar = (writeVal >= 0x20) ? writeVal : '.';
      char readChar = (readVal >= 0x20) ? readVal : '.';
      
      const char* status = "OK";
      if (writeVal != readVal) {
            status = "ERROR";
            errors++;
      }
      
      printf("%6d | 0x%02X '%c' (%-3d) | 0x%02X '%c' (%-3d) | %s\r\n",
               i,
               writeVal, writeChar, writeVal,
               readVal, readChar, readVal,
               status);
    }
   
    printf("\r\nOriginal String: \"");
    for (uint8_t i = 0; i < len; i++) {
      printf("%c", (WriteBuffer >= 0x20) ? WriteBuffer : '.');
    }
    printf("\"");
   
    printf("\r\nRead String:   \"");
    for (uint8_t i = 0; i < len; i++) {
      printf("%c", (ReadBuffer >= 0x20) ? ReadBuffer : '.');
    }
    printf("\"");
   
    printf("\r\n\r\nSummary: %d/%d bytes matched. %s\r\n",
         len - errors, len,
         (errors == 0) ? "SUCCESS (Strings match)" : "FAILED (Strings differ)");
}I2C_BSP.h
#include "hal_conf.h"
#include "delay_dsp.h"
void I2C_Configure(void);
void I2C_Master_EEPROM_Polling_Sample(void);3.实验现象


youtome 发表于 2025-7-2 12:46

学习I2C外设操作的入门实验。            

linfelix 发表于 2025-7-3 18:00

建议结合DMA传输数据,进一步提高I2C通信效率。

pmp 发表于 2025-7-4 09:57

可以帮助开发者理解和掌握I2C通信的工作原理和应用。

lzbf 发表于 2025-7-4 18:15

可以学习如何配置MCU的I2C接口、如何编写控制EEPROM的代码
页: [1]
查看完整版本: 【灵动微电子MM32F0121测评】5.I2C_EEPROM读写测试