[单片机芯片] [沁恒CH32V17测评]IIC硬件读取FT24C32

[复制链接]
313|0
abner_ma 发表于 2025-8-31 17:04 | 显示全部楼层 |阅读模式
本帖最后由 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)。
M1.png
  本描述适用于 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)器件可实现广泛的应用。
   M2.png

原理图:
Z4.png

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

  2. /**********************************************************************
  3. *@Note:
  4. AT24Cxx:

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

  11. /* EERPOM DATA ADDRESS Length Selection */
  12. #define Address_Lenth    Address_8bit
  13. //#define Address_Lenth   Address_16bit

  14. /* Global define */
  15. #define SIZE             sizeof(TEXT_Buffer)

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

  18. /*********************************************************************
  19. * @fn      IIC_Init
  20. *
  21. * @brief   Initializes the IIC peripheral.
  22. *
  23. * @return  none
  24. */
  25. void IIC_Init(u32 bound, u16 address)
  26. {
  27.     GPIO_InitTypeDef GPIO_InitStructure = {0};
  28.     I2C_InitTypeDef  I2C_InitTSturcture = {0};

  29.     RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  30.     RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C2, ENABLE);

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

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

  39.     I2C_InitTSturcture.I2C_ClockSpeed = bound;
  40.     I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;
  41.     I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_2;
  42.     I2C_InitTSturcture.I2C_OwnAddress1 = address;
  43.     I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;
  44.     I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;
  45.     I2C_Init(I2C2, &I2C_InitTSturcture);

  46.     I2C_Cmd(I2C2, ENABLE);

  47.     I2C_AcknowledgeConfig(I2C2, ENABLE);
  48. }

  49. /*********************************************************************
  50. * @fn      AT24CXX_Init
  51. *
  52. * @brief   Initializes AT24xx EEPROM.
  53. *
  54. * @return  none
  55. */
  56. void AT24CXX_Init(void)
  57. {
  58.     IIC_Init(1000, 0xA0);
  59. }

  60. /*********************************************************************
  61. * @fn      AT24CXX_ReadOneByte
  62. *
  63. * @brief   Read one data from EEPROM.
  64. *
  65. * @param   ReadAddr - Read frist address.
  66. *
  67. * @return  temp - Read data.
  68. */
  69. u8 AT24CXX_ReadOneByte(u16 ReadAddr)
  70. {
  71.     u8 temp = 0;

  72.     while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
  73.         ;
  74.     I2C_GenerateSTART(I2C2, ENABLE);

  75.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
  76.         ;
  77.     I2C_Send7bitAddress(I2C2, 0XA0, I2C_Direction_Transmitter);

  78.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  79.         ;

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

  84. #elif(Address_Lenth == Address_16bit)
  85.     I2C_SendData(I2C2, (u8)(ReadAddr >> 8));
  86.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  87.         ;

  88.     I2C_SendData(I2C2, (u8)(ReadAddr & 0x00FF));
  89.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  90.         ;

  91. #endif

  92.     I2C_GenerateSTART(I2C2, ENABLE);

  93.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
  94.         ;
  95.     I2C_Send7bitAddress(I2C2, 0XA0, I2C_Direction_Receiver);

  96.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED))
  97.         ;
  98.     while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET)
  99.         I2C_AcknowledgeConfig(I2C2, DISABLE);

  100.     temp = I2C_ReceiveData(I2C2);
  101.     I2C_GenerateSTOP(I2C2, ENABLE);

  102.     return temp;
  103. }

  104. /*********************************************************************
  105. * @fn      AT24CXX_WriteOneByte
  106. *
  107. * @brief   Write one data to EEPROM.
  108. *
  109. * @param   WriteAddr - Write frist address.
  110. *
  111. * @return  DataToWrite - Write data.
  112. */
  113. void AT24CXX_WriteOneByte(u16 WriteAddr, u8 DataToWrite)
  114. {
  115.     while(I2C_GetFlagStatus(I2C2, I2C_FLAG_BUSY) != RESET)
  116.         ;
  117.     I2C_GenerateSTART(I2C2, ENABLE);

  118.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_MODE_SELECT))
  119.         ;
  120.     I2C_Send7bitAddress(I2C2, 0XA0, I2C_Direction_Transmitter);

  121.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED))
  122.         ;

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

  127. #elif(Address_Lenth == Address_16bit)
  128.     I2C_SendData(I2C2, (u8)(WriteAddr >> 8));
  129.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  130.         ;

  131.     I2C_SendData(I2C2, (u8)(WriteAddr & 0x00FF));
  132.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  133.         ;

  134. #endif

  135.     if(I2C_GetFlagStatus(I2C2, I2C_FLAG_TXE) != RESET)
  136.     {
  137.         I2C_SendData(I2C2, DataToWrite);
  138.     }

  139.     while(!I2C_CheckEvent(I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED))
  140.         ;
  141.     I2C_GenerateSTOP(I2C2, ENABLE);
  142. }

  143. /*********************************************************************
  144. * @fn      AT24CXX_Read
  145. *
  146. * @brief   Read multiple data from EEPROM.
  147. *
  148. * @param   ReadAddr - Read frist address. (AT24c02: 0~255)
  149. *          pBuffer - Read data.
  150. *          NumToRead - Data number.
  151. *
  152. * @return  none
  153. */
  154. void AT24CXX_Read(u16 ReadAddr, u8 *pBuffer, u16 NumToRead)
  155. {
  156.     while(NumToRead)
  157.     {
  158.         *pBuffer++ = AT24CXX_ReadOneByte(ReadAddr++);
  159.         NumToRead--;
  160.     }
  161. }

  162. /*********************************************************************
  163. * @fn      AT24CXX_Write
  164. *
  165. * @brief   Write multiple data to EEPROM.
  166. *
  167. * @param   WriteAddr - Write frist address. (AT24c02: 0~255)
  168. *          pBuffer - Write data.
  169. *          NumToWrite - Data number.
  170. *
  171. * @return  none
  172. */
  173. void AT24CXX_Write(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite)
  174. {
  175.     while(NumToWrite--)
  176.     {
  177.         AT24CXX_WriteOneByte(WriteAddr, *pBuffer);
  178.         WriteAddr++;
  179.         pBuffer++;
  180.         Delay_Ms(2);
  181.     }
  182. }

main函数测试程序编写
  1. int main(void)
  2. {
  3.     u8 data[SIZE];

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

  7.     AT24CXX_Init();

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

  11.     Delay_Ms(500);

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

  16.     while(1)
  17.         ;
  18. }
运行结果
  1. SystemClk:48000000
  2. Start Write 24Cxx....
  3. 24Cxx Write Sucess!
  4. Start Read 24Cxx....
  5. The Data Readed Is:








您需要登录后才可以回帖 登录 | 注册

本版积分规则

认证:项目经理
简介:资深嵌入式开发工程师

104

主题

190

帖子

3

粉丝
快速回复 在线客服 返回列表 返回顶部