打印
[MM32硬件]

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

[复制链接]
676|4
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
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_InitTypeDef  I2C_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[i]);
        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[i] = 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[len];
    uint8_t ReadBuffer[len];
    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[i];
        uint8_t readVal = ReadBuffer[i];
        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[i] >= 0x20) ? WriteBuffer[i] : '.');
    }
    printf("\"");
   
    printf("\r\nRead String:     \"");
    for (uint8_t i = 0; i < len; i++) {
        printf("%c", (ReadBuffer[i] >= 0x20) ? ReadBuffer[i] : '.');
    }
    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.实验现象


MM32F0121C6PV_05I2C.zip

5.97 MB

工程

使用特权

评论回复
沙发
youtome| | 2025-7-2 12:46 | 只看该作者
学习I2C外设操作的入门实验。              

使用特权

评论回复
板凳
linfelix| | 2025-7-3 18:00 | 只看该作者
建议结合DMA传输数据,进一步提高I2C通信效率。

使用特权

评论回复
地板
pmp| | 2025-7-4 09:57 | 只看该作者
可以帮助开发者理解和掌握I2C通信的工作原理和应用。

使用特权

评论回复
5
lzbf| | 2025-7-4 18:15 | 只看该作者
可以学习如何配置MCU的I2C接口、如何编写控制EEPROM的代码

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

11

主题

29

帖子

0

粉丝