查看: 2175|回复: 0
收起左侧

第十四章:CH32V103应用教程——硬件I2C读写EEPROM

[复制链接]

  离线 

  • TA的每日心情
    慵懒
    2021-7-23 17:16
  • 签到天数: 17 天

    [LV.4]

    发表于 2021-4-23 11:15:31 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 草帽王子 于 2021-9-10 16:57 编辑

    本章教程将使用CH32V103的硬件I2C读写EEPROM24C02,并通过串口调试助手将读写结果打印显示。


    1、I2C简介及相关函数介绍

    内部集成电路总线(I2C)广泛用在微控制器和传感器及其他片外模块的通讯上,它本身支持多主多从模式,仅仅使用两根线(SDA和SCL)就能以100KHz(标准)和400KHz(快速)两种速度通讯。I2C总线还兼容SMBus协议,不仅支持I2C的时序,还支持仲裁、定时和DMA,拥有CRC校验功能。

    单片机I2C分为硬件I2C和模拟I2C。硬件I2C在进行程序编写时只需调用函数即可,且硬件I2C速度快、效率高、软件占用资源少,但其需使用固定GPIO脚,缺少灵活性,且某些单片机I2C并不稳定;模拟I2C通过软件程序控制管脚状态模拟I2C通信波形,使用灵活,且相对稳定,但其程序配置繁琐,代码量大,占用软件资源多。

    关于I2C具体信息,可参考CH32V103应用手册。I2C标准库函数具体内容如下:
    1. void I2C_DeInit(I2C_TypeDef* I2Cx);
    2. void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct);
    3. void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct);
    4. void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    5. void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    6. void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    7. void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState);
    8. void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState);
    9. void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState);
    10. void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address);
    11. void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    12. void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    13. void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState);
    14. void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data);
    15. uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx);
    16. void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction);
    17. uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register);
    18. void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    19. void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition);
    20. void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert);
    21. void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
    22. void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition);
    23. void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState);
    24. uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx);
    25. void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    26. void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState);
    27. void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle);
    复制代码

    1.1、void I2C_DeInit(I2C_TypeDef* I2Cx)
    功  能:将I2Cx外围寄存器初始化为其默认重置值。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。

    1.2、void I2C_Init(I2C_TypeDef* I2Cx, I2C_InitTypeDef* I2C_InitStruct)
    功  能:根据I2C_InitStruct中指定的参数初始化I2Cx外围设备。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_InitStruct:指向包含指定I2C外围设备配置信息的I2C_InitTypeDef结构的指针。

    1.3、void I2C_StructInit(I2C_InitTypeDef* I2C_InitStruct)
    功  能:用默认值填充每个I2C_InitStruct成员。
    输  入:I2C_InitStruct:指向将被初始化的I2C_InitTypeDef结构的指针。

    1.4、void I2C_Cmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C外围设备。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.5、void I2C_DMACmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C DMA请求。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.6、void I2C_DMALastTransferCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:指定下一次DMA传输是否是最后一次。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.7、void I2C_GenerateSTART(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:生成I2Cx通信启动条件。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.8、void I2C_GenerateSTOP(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:生成I2Cx通信停止条件。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.9、void I2C_AcknowledgeConfig(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C确认功能。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.10、void I2C_OwnAddress2Config(I2C_TypeDef* I2Cx, uint8_t Address)
    功  能:配置指定的I2C自身地址2。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。地址:指定7bit I2C自身地址2。

    1.11、void I2C_DualAddressCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C双寻址模式。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.12、void I2C_GeneralCallCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C常规调用功能。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.13、void I2C_ITConfig(I2C_TypeDef* I2Cx, uint16_t I2C_IT, FunctionalState NewState)
    功  能:启用或禁用指定的I2C中断。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_-IT:指定要启用或禁用的I2C中断源。NewState:启用或禁用。

    1.14、void I2C_SendData(I2C_TypeDef* I2Cx, uint8_t Data)

    功  能:通过I2Cx外围设备发送数据字节。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。数据:要传输的字节。

    1.15、uint8_t I2C_ReceiveData(I2C_TypeDef* I2Cx)
    功  能:返回I2Cx外围设备最近接收到的数据。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。

    1.16、void I2C_Send7bitAddress(I2C_TypeDef* I2Cx, uint8_t Address, uint8_t I2C_Direction)

    功  能:发送地址字节以选择从设备。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。Address:指定将要传输的从属地址。I2C_Direction:指定I2C设备是发射机还是接收机。

    1.17、uint16_t I2C_ReadRegister(I2C_TypeDef* I2Cx, uint8_t I2C_Register)
    功  能:读取指定的I2C寄存器并返回其值。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_Register:指定要读取的寄存器。

    1.18、void I2C_SoftwareResetCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C软件重置。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.19、void I2C_NACKPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_NACKPosition)
    功  能:在主接收器模式下选择指定的I2C NACK位置。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_NACKPosition:指定NACK位置。

    1.20、void I2C_SMBusAlertConfig(I2C_TypeDef* I2Cx, uint16_t I2C_SMBusAlert)
    功  能:驱动指定I2C的SMBusAlert引脚高或低。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_SMBusAlert:指定SMBAlert pin级别。

    1.21、void I2C_TransmitPEC(I2C_TypeDef* I2Cx, FunctionalState NewState)

    功  能:启用或禁用指定的I2C PEC传输。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.22、void I2C_PECPositionConfig(I2C_TypeDef* I2Cx, uint16_t I2C_PECPosition)
    功  能:选择指定的I2C PEC位置。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_PECPosition:I2C配置位置:指定PEC位置。

    1.23、void I2C_CalculatePEC(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用传输字节的PEC值计算。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.24、uint8_t I2C_GetPEC(I2C_TypeDef* I2Cx)
    功  能:返回指定I2C的PEC值。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。

    1.25、void I2C_ARPCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C ARP。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.26、void I2C_StretchClockCmd(I2C_TypeDef* I2Cx, FunctionalState NewState)
    功  能:启用或禁用指定的I2C时钟拉伸。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。NewState:启用或禁用。

    1.27、void I2C_FastModeDutyCycleConfig(I2C_TypeDef* I2Cx, uint16_t I2C_DutyCycle)
    功  能:选择指定的I2C快速模式占空比。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_DutyCycle:指定快速模式占空比。

    1.28、ErrorStatus I2C_CheckEvent(I2C_TypeDef* I2Cx, uint32_t I2C_EVENT)
    功  能:检查最后一个I2Cx事件是否等于作为参数传递的事件。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_EVENT:指定要检查的事件。

    1.29、uint32_t I2C_GetLastEvent(I2C_TypeDef* I2Cx)
    功  能:返回最后一个I2Cx事件。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。

    1.30、FlagStatus I2C_GetFlagStatus(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
    功  能:检查最后一个I2Cx事件是否等于作为参数传递的事件。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_FLAG:指定要检查的标志。

    1.31、void I2C_ClearFlag(I2C_TypeDef* I2Cx, uint32_t I2C_FLAG)
    功  能:清除I2Cx的挂起标志。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_FLAG:指定要清除的标志。

    1.32、ITStatus I2C_GetITStatus(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
    功  能:检查指定的I2C中断是否发生。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_IT:指定要检查的中断源。

    1.33、void I2C_ClearITPendingBit(I2C_TypeDef* I2Cx, uint32_t I2C_IT)
    功  能:清除I2Cx中断挂起位。
    输  入:I2Cx:其中x可以是1或2,以选择I2C外围设备。I2C_-IT:指定要清除的中断挂起位。

    以上函数使用时直接在程序中进行调用即可。


    2、硬件设计

    本章教程使用硬件I2C读写24C02,由原理图可知,24C02的IIC_SCL引脚和IIC_SDA引脚通过J5引出来。由CH32V103数据手册可知,CH32V103的PB6和PB7引脚分别对应I2C1_SCL和I2C1_SDA,PB10和PB11引脚对应I2C2_SCL和I2C2_SDA,本章教程使用I2C2,连接方式如下:

    • PB10连接J5的SCL引脚
    • PB11连接J5的SDA引脚


    3、软件设计

    硬件I2C读写24C02相较于模拟I2C读写24C02在程序代码量上少了很多,具体程序如下:

    iic.h文件
    1. #ifndef __IIC_H
    2. #define __IIC_H

    3. #include "ch32v10x_conf.h"

    4. /* EERPOM DATA ADDRESS Length Definition */
    5. #define Address_8bit  0
    6. #define Address_16bit  1

    7. /* EERPOM DATA ADDRESS Length Selection */
    8. #define Address_Lenth   Address_8bit
    9. //#define Address_Lenth   Address_16bit

    10. void IIC_Init( u32 bound, u16 address );
    11. void AT24CXX_Init(void);
    12. u8 AT24CXX_ReadOneByte(u16 ReadAddr);
    13. void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);
    14. void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);
    15. void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);

    16. #endif
    复制代码
    iic.h文件主要是相关定义及函数声明;


    iic.c文件
    1. #include "iic.h"

    2. /*******************************************************************************
    3. * Function Name  : IIC_Init
    4. * Description    : Initializes the IIC peripheral.
    5. * Input          : None
    6. * Return         : None
    7. *******************************************************************************/
    8. void IIC_Init( u32 bound, u16 address )
    9. {
    10.     GPIO_InitTypeDef GPIO_InitStructure;
    11.     I2C_InitTypeDef I2C_InitTSturcture;

    12.     RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟
    13.     RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE );  //使能I2C2时钟

    14.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
    15.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //开漏复用模式
    16.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    17.     GPIO_Init( GPIOB, &GPIO_InitStructure );

    18.     GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
    19.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; //开漏复用模式
    20.     GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    21.     GPIO_Init( GPIOB, &GPIO_InitStructure );

    22.     I2C_InitTSturcture.I2C_ClockSpeed = bound;          //设置时钟频率
    23.     I2C_InitTSturcture.I2C_Mode = I2C_Mode_I2C;         //设置I2C模式
    24.     I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_2; //设置I2C快速模式占空比。
    25.     I2C_InitTSturcture.I2C_OwnAddress1 = address;       //设置第一个设备自己的地址
    26.     I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable;        //使能应答
    27.     I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //设置为7位应答
    28.     I2C_Init( I2C2, &I2C_InitTSturcture );              //I2C初始化

    29.     I2C_Cmd( I2C2, ENABLE );               //使能I2C2

    30.     I2C_AcknowledgeConfig( I2C2, ENABLE ); //使能I2C2应答功能
    31. }

    32. /*******************************************************************************
    33. * Function Name  : AT24CXX_Init
    34. * Description    : Initializes AT24xx EEPROM.
    35. * Input          : None
    36. * Return         : None
    37. ********************************************************************************/
    38. void AT24CXX_Init(void)
    39. {
    40.     IIC_Init( 100000, 0xA0);
    41. }

    42. /*******************************************************************************
    43. * Function Name  : AT24CXX_ReadOneByte
    44. * Description    : Read one data from EEPROM.
    45. * Input          : ReadAddr: Read frist address.
    46. * Return         : temp: Read data.
    47. ********************************************************************************/
    48. u8 AT24CXX_ReadOneByte(u16 ReadAddr)
    49. {
    50.     u8 temp=0;

    51.     while( I2C_GetFlagStatus( I2C2, I2C_FLAG_BUSY ) != RESET ); //等待总线空闲
    52.     I2C_GenerateSTART( I2C2, ENABLE ); //开始信号

    53.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_MODE_SELECT ) ); //检测EV5事件并清除标志
    54.     I2C_Send7bitAddress( I2C2, 0XA0, I2C_Direction_Transmitter );   //发送设备地址+写信号

    55.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) ); //检测EV6事件并清除标志

    56. #if (Address_Lenth  == Address_8bit)
    57.     I2C_SendData( I2C2, (u8)(ReadAddr&0x00FF) ); //发送数据地址
    58.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) ); //检测EV8事件并清除标志

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

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

    64. #endif

    65.     I2C_GenerateSTART( I2C2, ENABLE );

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

    68.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED ) ); //检测EV6事件并清除标志
    69.     while( I2C_GetFlagStatus( I2C2, I2C_FLAG_RXNE ) ==  RESET )
    70.     I2C_AcknowledgeConfig( I2C2, DISABLE ); //发送非应答信号

    71.     temp = I2C_ReceiveData( I2C2 );   //接收数据
    72.     I2C_GenerateSTOP( I2C2, ENABLE ); //停止信号

    73.     return temp;
    74. }

    75. /*******************************************************************************
    76. * Function Name  : AT24CXX_WriteOneByte
    77. * Description    : Write one data to EEPROM.
    78. * Input          : WriteAddr: Write frist address.
    79. * Return         : DataToWrite: Write data.
    80. ********************************************************************************/
    81. void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite)
    82. {
    83.     while( I2C_GetFlagStatus( I2C2, I2C_FLAG_BUSY ) != RESET );
    84.     I2C_GenerateSTART( I2C2, ENABLE );

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

    87.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) );

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

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

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

    96. #endif

    97.     if( I2C_GetFlagStatus( I2C2, I2C_FLAG_TXE ) !=  RESET )
    98.     {
    99.         I2C_SendData( I2C2, DataToWrite );
    100.     }

    101.     while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) );
    102.     I2C_GenerateSTOP( I2C2, ENABLE );
    103. }

    104. /*******************************************************************************
    105. * Function Name  : AT24CXX_Read
    106. * Description    : Read multiple data from EEPROM.
    107. * Input          : ReadAddr: Read frist address. (AT24c02: 0~255)
    108. *                  pBuffer: Read data.
    109. *                  NumToRead: Data number.
    110. * Return         : None
    111. ********************************************************************************/
    112. void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
    113. {
    114.     while(NumToRead)
    115.     {
    116.         *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
    117.         NumToRead--;
    118.     }
    119. }

    120. /*******************************************************************************
    121. * Function Name  : AT24CXX_Write
    122. * Description    : Write multiple data to EEPROM.
    123. * Input          : WriteAddr: Write frist address. (AT24c02: 0~255)
    124. *                  pBuffer: Write data.
    125. *                  NumToWrite: Data number.
    126. * Return         : None
    127. ********************************************************************************/
    128. void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
    129. {
    130.     while(NumToWrite--)
    131.     {
    132.         AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
    133.         WriteAddr++;
    134.         pBuffer++;
    135.         Delay_Ms(2);
    136.     }
    137. }
    复制代码
    iic.c文件主要是iic初始化配置及硬件iic读写配置函数。

    main.c函数
    1. /*******************************************************************************
    2. * Function Name  : main
    3. * Description    : Main program.
    4. * Input          : None
    5. * Return         : None
    6. *******************************************************************************/
    7. int main(void)
    8. {
    9.     u8 data[SIZE];

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

    13.     AT24CXX_Init();

    14.     printf("Start Write 24Cxx....\r\n");
    15.     AT24CXX_Write(100,(u8*)TEXT_Buffer,SIZE);  //写入数据
    16.     printf("24Cxx Write Sucess!\r\n");

    17.     Delay_Ms(500);

    18.     printf("Start Read 24Cxx....\r\n");
    19.     AT24CXX_Read(100,data,SIZE);               //读取数据
    20.     printf("The Data Readed Is: \r\n");
    21.     printf("%s\r\n", data);                    //打印输出数据

    22.     while(1);
    23. }
    复制代码
    main.c文件主要进行相关函数初始化以及flash数据的写入和读取。


    4、下载验证

    将编译好的程序下载到开发板并复位,串口打印情况具体如下:

    CH32V CH573单片机芯片-第十四章:CH32V103应用教程——硬件I2C读写EEPROMrisc-v单片机中文社区(1)

    硬件IIC.rar附件下载
    CH32V CH573单片机芯片-第十四章:CH32V103应用教程——硬件I2C读写EEPROMrisc-v单片机中文社区(2) 13、硬件IIC.rar (473.31 KB, 下载次数: 27)
    链接:https://pan.baidu.com/s/1Of8nGN4x2uDGtYYzZHvmVg
    提取码:vgkr
    复制这段内容后打开百度网盘手机App,操作更方便哦







    上一篇:第十三章:CH32V103应用教程——DMA(存储器到存储器)
    下一篇:第十五章:CH32V103应用教程——SPI读写FLASH
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-11-26 09:37 , Processed in 0.461465 second(s), 49 queries .

    快速回复 返回顶部 返回列表