- /*
- * at24c02.h
- *
- * Created on: Dec 13, 2020
- * Author: dengrb
- */
- #ifndef BSP_INC_AT24C02_H_
- #define BSP_INC_AT24C02_H_
- #include "ch32v10x_conf.h"
- /* 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
- void IIC_Init( u32 bound, u16 address );
- void AT24CXX_Init(void);
- u8 AT24CXX_ReadOneByte(u16 ReadAddr);
- void AT24CXX_WriteOneByte(u16 WriteAddr,u8 DataToWrite);
- void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead);
- void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite);
- #endif /* BSP_INC_AT24C02_H_ */
3. 在at24c02.c文件里面实现IIC和at24c02的配置和初始化,以及读写函数等。
- /*
- * at24c02.c
- *
- * Created on: Dec 13, 2020
- * Author: dengrb
- */
- #include "at24c02.h"
- /*******************************************************************************
- * Function Name : IIC_Init
- * Description : Initializes the IIC peripheral.
- * Input : None
- * Return : None
- *******************************************************************************/
- void IIC_Init( u32 bound, u16 address )
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- I2C_InitTypeDef I2C_InitTSturcture;
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE ); //使能GPIOB时钟
- RCC_APB1PeriphClockCmd( RCC_APB1Periph_I2C2, ENABLE ); //使能I2C2时钟
- 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模式
- I2C_InitTSturcture.I2C_DutyCycle = I2C_DutyCycle_2; //设置I2C快速模式占空比。
- I2C_InitTSturcture.I2C_OwnAddress1 = address; //设置第一个设备自己的地址
- I2C_InitTSturcture.I2C_Ack = I2C_Ack_Enable; //使能应答
- I2C_InitTSturcture.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; //设置为7位应答
- I2C_Init( I2C2, &I2C_InitTSturcture ); //I2C初始化
- I2C_Cmd( I2C2, ENABLE ); //使能I2C2
- I2C_AcknowledgeConfig( I2C2, ENABLE ); //使能I2C2应答功能
- }
- /*******************************************************************************
- * Function Name : AT24CXX_Init
- * Description : Initializes AT24xx EEPROM.
- * Input : None
- * Return : None
- ********************************************************************************/
- void AT24CXX_Init(void)
- {
- IIC_Init( 100000, 0xA0);
- }
- /*******************************************************************************
- * Function Name : AT24CXX_ReadOneByte
- * Description : Read one data from EEPROM.
- * Input : ReadAddr: Read frist address.
- * Return : temp: 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 ) ); //检测EV5事件并清除标志
- I2C_Send7bitAddress( I2C2, 0XA0, I2C_Direction_Transmitter ); //发送设备地址+写信号
- while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED ) ); //检测EV6事件并清除标志
- #if (Address_Lenth == Address_8bit)
- I2C_SendData( I2C2, (u8)(ReadAddr&0x00FF) ); //发送数据地址
- while( !I2C_CheckEvent( I2C2, I2C_EVENT_MASTER_BYTE_TRANSMITTED ) ); //检测EV8事件并清除标志
- #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 ) ); //检测EV6事件并清除标志
- while( I2C_GetFlagStatus( I2C2, I2C_FLAG_RXNE ) == RESET )
- I2C_AcknowledgeConfig( I2C2, DISABLE ); //发送非应答信号
- temp = I2C_ReceiveData( I2C2 ); //接收数据
- I2C_GenerateSTOP( I2C2, ENABLE ); //停止信号
- return temp;
- }
- /*******************************************************************************
- * Function Name : AT24CXX_WriteOneByte
- * Description : Write one data to EEPROM.
- * Input : WriteAddr: Write frist address.
- * Return : DataToWrite: 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 );
- }
- /*******************************************************************************
- * Function Name : AT24CXX_Read
- * Description : Read multiple data from EEPROM.
- * Input : ReadAddr: Read frist address. (AT24c02: 0~255)
- * pBuffer: Read data.
- * NumToRead: Data number.
- * Return : None
- ********************************************************************************/
- void AT24CXX_Read(u16 ReadAddr,u8 *pBuffer,u16 NumToRead)
- {
- while(NumToRead)
- {
- *pBuffer++=AT24CXX_ReadOneByte(ReadAddr++);
- NumToRead--;
- }
- }
- /*******************************************************************************
- * Function Name : AT24CXX_Write
- * Description : Write multiple data to EEPROM.
- * Input : WriteAddr: Write frist address. (AT24c02: 0~255)
- * pBuffer: Write data.
- * NumToWrite: Data number.
- * Return : None
- ********************************************************************************/
- void AT24CXX_Write(u16 WriteAddr,u8 *pBuffer,u16 NumToWrite)
- {
- while(NumToWrite--)
- {
- AT24CXX_WriteOneByte(WriteAddr,*pBuffer);
- WriteAddr++;
- pBuffer++;
- Delay_Ms(2);
- }
- }
4. 在main.c中添加测试代码。
- #include <stdio.h>
- #include <string.h>
- #include "debug.h"
- #include "led.h"
- #include "usart.h"
- #include "tkey.h"
- #include "at24c02.h"
- /* Global typedef */
- /* Global define */
- /* Global Variable */
- u8 Write_Data[100]="Hello world!This is EEPROM Write and Read Test!";
- u8 Read_Data[100];
- /*******************************************************************************
- * Function Name : main
- * Description : Main program.
- * Input : None
- * Return : None
- *******************************************************************************/
- int main(void)
- {
- Delay_Init();
- USART_Printf_Init(115200);
- AT24CXX_Init();
- LED_Init();
- printf("SystemClk:%d\r\n",SystemCoreClock);
- LED1_ON();
- printf("Start Write 24Cxx....\r\n");
- AT24CXX_Write(100,(u8*)Write_Data,47); //写入数据
- printf("24Cxx Write Sucess!\r\n");
- LED1_OFF();
- Delay_Ms(1000);
- LED2_ON();
- printf("Start Read 24Cxx....\r\n");
- AT24CXX_Read(100,Read_Data,47); //读取数据
- printf("The Data Readed Is: \r\n");
- printf("%s\r\n", Read_Data); //打印输出数据
- LED2_OFF();
- while(1)
- {
- }
- }
(三) 效果演示