Uriah 发表于 2024-10-4 12:15

基于赛元MCU的I2C通信应用及代码实现

赛元MCU(SYNWIT MCU)在低功耗、高性价比的嵌入式应用中非常有竞争力。今天我将分享一个基于赛元MCU实现I2C通信的简单应用,展示如何通过I2C总线与外部EEPROM芯片进行数据读写操作。

项目概述
我们将使用赛元MCU的I2C接口与一颗24C02 EEPROM芯片进行数据交互,主要实现数据的写入与读取操作。这个项目可以帮助我们掌握如何使用I2C通信协议,并扩展MCU的存储能力。

硬件需求
[*]赛元MCU开发板
[*]24C02 EEPROM芯片
[*]若干跳线用于连接I2C总线(SCL,SDA)
[*]4.7kΩ的上拉电阻(用于I2C总线)

软件开发环境
[*]使用Keil或IAR开发环境
[*]CubeMX用于I2C初始化配置(如赛元MCU有类似工具的话)

I2C硬件连接
[*]SCL: 连接赛元MCU的I2C时钟引脚
[*]SDA: 连接赛元MCU的I2C数据引脚
[*]使用4.7kΩ电阻将SCL和SDA分别上拉到3.3V

CubeMX配置
[*]打开CubeMX,选择赛元MCU型号。
[*]启用I2C外设,选择SCL和SDA对应的引脚。
[*]设置I2C的工作频率(通常为100kHz或400kHz)。
[*]生成代码并导入Keil或IAR开发环境。

代码实现#include "main.h"
#include "i2c.h"
#include "gpio.h"

#define EEPROM_ADDRESS 0xA0// 24C02的器件地址

I2C_HandleTypeDef hi2c1;// 定义I2C句柄

// 写入数据到EEPROM
void EEPROM_Write(uint16_t MemAddress, uint8_t *Data, uint16_t Size) {
    HAL_I2C_Mem_Write(&hi2c1, EEPROM_ADDRESS, MemAddress, I2C_MEMADD_SIZE_8BIT, Data, Size, HAL_MAX_DELAY);
}

// 从EEPROM读取数据
void EEPROM_Read(uint16_t MemAddress, uint8_t *Buffer, uint16_t Size) {
    HAL_I2C_Mem_Read(&hi2c1, EEPROM_ADDRESS, MemAddress, I2C_MEMADD_SIZE_8BIT, Buffer, Size, HAL_MAX_DELAY);
}

int main(void) {
    HAL_Init();            // 初始化HAL库
    SystemClock_Config();   // 配置系统时钟
    MX_GPIO_Init();         // 初始化GPIO
    MX_I2C1_Init();         // 初始化I2C

    // 写入"Hello"到EEPROM地址0x00
    uint8_t data[] = "Hello";
    EEPROM_Write(0x00, data, sizeof(data) - 1);

    // 读取EEPROM中的数据并存储在缓冲区中
    uint8_t readBuffer;
    EEPROM_Read(0x00, readBuffer, sizeof(readBuffer) - 1);
    readBuffer = '\0';// 添加字符串终止符

    // 可以通过调试或串口查看readBuffer中的数据
    while (1) {
      HAL_Delay(1000);// 让系统保持运行
    }
}

// I2C初始化代码
void MX_I2C1_Init(void) {
    hi2c1.Instance = I2C1;
    hi2c1.Init.ClockSpeed = 100000;
    hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
    hi2c1.Init.OwnAddress1 = 0;
    hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
    hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
    hi2c1.Init.OwnAddress2 = 0;
    hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
    hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
    if (HAL_I2C_Init(&hi2c1) != HAL_OK) {
      // 初始化失败处理
      Error_Handler();
    }
}

代码解释
[*]EEPROM_Write:通过HAL_I2C_Mem_Write函数将数据写入EEPROM的指定地址。
[*]EEPROM_Read:通过HAL_I2C_Mem_Read函数从EEPROM的指定地址读取数据。
[*]我们在主函数中,将字符串"Hello"写入EEPROM的地址0x00,并从同一地址读取数据并存入readBuffer,然后可以通过调试器查看数据是否正确写入和读取。

总结
通过I2C协议,我们可以轻松地扩展赛元MCU的功能,实现与各种外部器件(如EEPROM、传感器等)的数据交互。这段代码展示了如何通过I2C与EEPROM通信,适用于各种需要外部存储或传感器读写的项目。
赛元MCU的I2C接口稳定、可靠,适合低功耗和高性能的嵌入式应用场景。

公羊子丹 发表于 2024-10-4 12:16

这个教程太棒了!我一直在找赛元MCU的I2C应用实例,代码也写得很清晰,感谢分享!

周半梅 发表于 2024-10-4 12:16

正好最近在做I2C通信,没想到赛元MCU这么好用,明天试试!

帛灿灿 发表于 2024-10-4 12:16

写入和读取数据的流程讲解得很详细,这样一看I2C确实也没那么复杂。

童雨竹 发表于 2024-10-4 12:16

之前总是调不通I2C,看来还是初始化有问题,你这段代码让我豁然开朗!

万图 发表于 2024-10-4 12:17

我用的是同一个EEPROM芯片,正好可以参考你的实现,感谢!

Wordsworth 发表于 2024-10-4 12:17

第一次用赛元MCU,没想到上手这么简单,特别是有你这份代码,节省了我不少时间!

Bblythe 发表于 2024-10-4 12:17

I2C的上拉电阻一直没配置对,看到你说的4.7kΩ才恍然大悟,我一直用的10kΩ。

Pulitzer 发表于 2024-10-4 12:18

赛元MCU的I2C性能如何?传感器的数据传输速度够快吗?

Clyde011 发表于 2024-10-4 12:18

我也用CubeMX生成代码,没想到用在赛元MCU上也一样好用,真是神器啊!

gangong 发表于 2025-2-27 22:34

写得很好

复古留声机 发表于 2025-3-18 18:54

这个项目中,EEPROM的地址是0xA0,这个地址是固定的吗?还是可以根据需要进行修改呢?
页: [1]
查看完整版本: 基于赛元MCU的I2C通信应用及代码实现