abner_ma 发表于 2025-8-31 17:04

[沁恒CH32V17测评]IIC硬件读取FT24C32

本帖最后由 abner_ma 于 2025-8-31 17:14 编辑

   CH32V 系列是基于青稞 RISC-V 内核设计的工业级通用微控制器,包括 CH32V305 连接型 MCU、CH32V307/CH32V317 互联型 MCU、CH32V208 无线型 MCU 等。CH32V30x 和 CH32V31x 系列基于青稞 V4F微处理器设计,支持单精度浮点指令和快速中断响应,支持 144MHz 主频零等待运行,提供 8 组串口、4 组电机 PWM 高级定时器、SDIO、DVP 数字图像接口、4 组模拟运放、双 ADC 单元、双 DAC 单元,内置USB2.0 高速 PHY 收发器(480Mbps)、千兆以太网 MAC 控制器及 10 兆物理层收发器、10/100 兆物理层收发器(仅适用于 CH32V317)等。 2 个 I2C 接口(支持 SMBus/PMBus)。

本描述适用于 CH32F20x、CH32V20x、CH32V30x 和 CH32V31x 微控制器全系列产品。内部集成电路总线(I2C)广泛用在微控制器和传感器及其他片外模块的通讯上,它本身支持多主多从模式,仅仅使用两根线(SDA 和 SCL)就能以 100kHz(标准)和 400kHz(快速)两种速度通讯。I2C 总线还兼容 SMBus 协议,不仅支持 I2C 的时序,还支持仲裁、定时和 DMA,拥有 CRC 校验功能。
主要特征:
 支持主模式和从模式
 支持 7 位或 10 位地址
 从设备支持双 7 位地址
 支持两种速度模式:100kHz 和 400kHz
 多种状态模式,多种错误标志
 支持加长的时钟功能
 2 个中断向量
 支持 DMA
 支持 PEC
 兼容 SMBus



关于FM24C32
FT24C32A系列是串行电可擦除可编程只读存储器,通常称为EEPROM。它们被组织为4096个字,每个字8位(一个字节)。这些器件采用专有的先进CMOS工艺制造,适用于低功耗和低电压应用。这些器件有标准的8引脚DIP、8引脚SOP、8引脚MSOP、8引脚TSSOP、8引脚DFN、5引脚SOT23和5引脚TSOT23封装。标准的2线串行接口用于处理所有读写功能。VCC范围(1.8V至5.5V)器件可实现广泛的应用。


原理图:


程序设计:IIC 硬件配置
#include "debug.h"

/**********************************************************************
*@Note:
AT24Cxx:

READ EEPROM:Start + 0xA0 + 8bit Data Address + Start + 0xA1 + Read Data + Stop.
WRITE EERPOM:Start + 0xA0 + 8bit Data Address + Write Data + Stop.
*******************************************************************************/
/* EERPOM DATA ADDRESS Length Definition */
#define Address_8bit   0
#define Address_16bit    1

/* EERPOM DATA ADDRESS Length Selection */
#define Address_Lenth    Address_8bit
//#define Address_Lenth   Address_16bit

/* Global define */
#define SIZE             sizeof(TEXT_Buffer)

/* Global Variable */
const u8 TEXT_Buffer[] = {"I LOVE bbs.21ic.com!!"};

/*********************************************************************
* @fn      IIC_Init
*
* @brief   Initializes the IIC peripheral.
*
* @returnnone
*/
void IIC_Init(u32 bound, u16 address)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    I2C_InitTypeDefI2C_InitTSturcture = {0};

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOB, &GPIO_InitStructure);

    I2C_InitTSturcture.I2C_ClockSpeed = bound;
    I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;
    I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_2;
    I2C_InitTSturcture.I2C_OwnAddress1 = address;
    I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;
    I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
    I2C_Init(I2C2, &I2C_InitTSturcture);

    I2C_Cmd(I2C2, ENABLE);

    I2C_AcknowledgeConfig(I2C2, ENABLE);
}

/*********************************************************************
* @fn      AT24CXX_Init
*
* @brief   Initializes AT24xx EEPROM.
*
* @returnnone
*/
void AT24CXX_Init(void)
{
    IIC_Init(1000, 0xA0);
}

/*********************************************************************
* @fn      AT24CXX_ReadOneByte
*
* @brief   Read one data from EEPROM.
*
* @param   ReadAddr - Read frist address.
*
* @returntemp - Read data.
*/
u8 AT24CXX_ReadOneByte(u16 ReadAddr)
{
    u8 temp = 0;

    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
      ;
    I2C_GenerateSTART(I2C2, ENABLE);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
      ;
    I2C_Send7bitAddress(I2C2, 0XA0, I2C_Direction_Transmitter);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
      ;

#if(Address_Lenth == Address_8bit)
    I2C_SendData(I2C2, (u8)(ReadAddr & 0x00FF));
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      ;

#elif(Address_Lenth == Address_16bit)
    I2C_SendData(I2C2, (u8)(ReadAddr >> 8));
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      ;

    I2C_SendData(I2C2, (u8)(ReadAddr & 0x00FF));
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      ;

#endif

    I2C_GenerateSTART(I2C2, ENABLE);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
      ;
    I2C_Send7bitAddress(I2C2, 0XA0, I2C_Direction_Receiver);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
      ;
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
      I2C_AcknowledgeConfig(I2C2, DISABLE);

    temp = I2C_ReceiveData(I2C2);
    I2C_GenerateSTOP(I2C2, ENABLE);

    return temp;
}

/*********************************************************************
* @fn      AT24CXX_WriteOneByte
*
* @brief   Write one data to EEPROM.
*
* @param   WriteAddr - Write frist address.
*
* @returnDataToWrite - Write data.
*/
void AT24CXX_WriteOneByte(u16 WriteAddr, u8 DataToWrite)
{
    while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
      ;
    I2C_GenerateSTART(I2C2, ENABLE);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
      ;
    I2C_Send7bitAddress(I2C2, 0XA0, I2C_Direction_Transmitter);

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
      ;

#if(Address_Lenth == Address_8bit)
    I2C_SendData(I2C2, (u8)(WriteAddr & 0x00FF));
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      ;

#elif(Address_Lenth == Address_16bit)
    I2C_SendData(I2C2, (u8)(WriteAddr >> 8));
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      ;

    I2C_SendData(I2C2, (u8)(WriteAddr & 0x00FF));
    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      ;

#endif

    if(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXE) != RESET)
    {
      I2C_SendData(I2C2, DataToWrite);
    }

    while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
      ;
    I2C_GenerateSTOP(I2C2, ENABLE);
}

/*********************************************************************
* @fn      AT24CXX_Read
*
* @brief   Read multiple data from EEPROM.
*
* @param   ReadAddr - Read frist address. (AT24c02: 0~255)
*          pBuffer - Read data.
*          NumToRead - Data number.
*
* @returnnone
*/
void AT24CXX_Read(u16 ReadAddr, u8 *pBuffer, u16 NumToRead)
{
    while(NumToRead)
    {
      *pBuffer++ = AT24CXX_ReadOneByte(ReadAddr++);
      NumToRead--;
    }
}

/*********************************************************************
* @fn      AT24CXX_Write
*
* @brief   Write multiple data to EEPROM.
*
* @param   WriteAddr - Write frist address. (AT24c02: 0~255)
*          pBuffer - Write data.
*          NumToWrite - Data number.
*
* @returnnone
*/
void AT24CXX_Write(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite)
{
    while(NumToWrite--)
    {
      AT24CXX_WriteOneByte(WriteAddr, *pBuffer);
      WriteAddr++;
      pBuffer++;
      Delay_Ms(2);
    }
}
main函数测试程序编写
int main(void)
{
    u8 data;

    Delay_Init();
    USART_Printf_Init(115200);
    printf("SystemClk:%d\r\n", SystemCoreClock);

    AT24CXX_Init();

    printf("Start Write 24Cxx....\r\n");
    AT24CXX_Write(0, (u8 *)TEXT_Buffer, 18);
    printf("24Cxx Write Sucess!\r\n");

    Delay_Ms(500);

    printf("Start Read 24Cxx....\r\n");
    AT24CXX_Read(0, data, 18);
    printf("The Data Readed Is: \r\n");
    printf("%s\r\n", data);

    while(1)
      ;
}
运行结果
SystemClk:48000000
Start Write 24Cxx....
24Cxx Write Sucess!
Start Read 24Cxx....
The Data Readed Is:







星辰伴梦 发表于 2025-9-7 12:49

FT24C32的EEPROM存储器在低功耗应用中表现如何?

星辰相随 发表于 2025-9-26 21:40

老哥你用的是什么板子,自己搞的吗?
页: [1]
查看完整版本: [沁恒CH32V17测评]IIC硬件读取FT24C32