- /*
- *@Note
- I2C接口操作EEPROM外设例程: 此代码在官方例程基础上修改,其中部分代码借鉴了stm32等其他类型单片机的IIC流程
- I2C1_SCL(PB10)、I2C1_SDA(PB11)。
- 本例程使用 EEPROM 为 AT24Cxx系列。
- 操作步骤:
- READ EEPROM:Start + 0xA0 + 8bit Data Address + Start + 0xA1 + Read Data + Stop.
- WRITE EERPOM:Start + 0xA0 + 8bit Data Address + Write Data + Stop.
- */
-
- #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)
- //写入和读取的初始地址
- #define WR_Address 2
- //器件的页大小
- #define PAGE_SIZE 16
- /* Global Variable */
- const u8 TEXT_Buffer[] = {"CH32V103 IIC TEST GOOD LUCK!\r Let's Go!\r AT24C02 Page=8,AT24C4/8/16 Page=16,AT24C32/64 Page=32."};
-
- /*********************************************************************
- * @fn IIC_Init
- *
- * [url=home.php?mod=space&uid=247401]@brief[/url] Initializes the IIC peripheral.
- *
- * [url=home.php?mod=space&uid=266161]@return[/url] none
- */
- void IIC_Init(u32 bound, u16 address)
- {
- GPIO_InitTypeDef GPIO_InitStructure = {0};
- I2C_InitTypeDef I2C_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.
- *
- * @return none
- */
- void AT24CXX_Init(void)
- {
- IIC_Init(100000, 0xA0);
- }
-
- /*********************************************************************
- * @fn AT24CXX_ReadOneByte
- *
- * @brief Read one data from EEPROM.
- *
- * @param 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));
- 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_MulitReadByte
- *
- * @brief Read one data from EEPROM.
- *
- * @param ReadAddr - Read frist address.
- * Readbuffer - Read data buffer.
- * Num - Size will be read.
- *
- * @return read_count
- */
- u8 AT24CXX_MulitReadBytes(u16 ReadAddr,u8 *Readbuffer, u8 Num )
- {
- u8 read_count=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(Num--)
- {
-
- if(Num==0) //最后一个数据产生停止应答信号
- {
- //应答必须关闭,否则下次IIC将不能用
- I2C_AcknowledgeConfig(I2C2, DISABLE); //需要在接受到最后一位数据前关闭应答
- }
- while(I2C_GetFlagStatus(I2C2, I2C_FLAG_RXNE) == RESET); //等待收到数据
- *Readbuffer++=I2C_ReceiveData(I2C2); //收到数据放入缓存
- read_count++;
- }
- I2C_GenerateSTOP(I2C2, ENABLE); //发送停止信号
- I2C_AcknowledgeConfig(I2C1,ENABLE) ; //开启应答方便下一次使用
-
- return read_count;
- }
-
-
-
- /*********************************************************************
- * @fn AT24CXX_WriteOneByte
- *
- * @brief Write one data to EEPROM.
- *
- * @param 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);
- }
-
- /*********************************************************************
- * @fn AT24CXX_WritePage
- *
- * @brief Write one data to EEPROM.
- *
- * @param WriteAddr - Write frist address.
- * WriteBuffer - data will be write
- * Num - data num 1~8,page is 8 byte
- *
- * @return DataToWrite - Write data.
- */
- void AT24CXX_WritePage(u16 WriteAddr, u8 *WriteBuffer, u8 Num)
- {
- 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
-
- while(!(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE)));
- I2C_SendData(I2C2, *WriteBuffer++);
- while(!(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE)));
- while(Num)
- {
- Num--;
- if(Num==0) break; //全部发送完毕,直接退出
- //还有数据则继续发送
- I2C_SendData(I2C2, *WriteBuffer++);
- while(!(I2C_GetFlagStatus(I2C2,I2C_FLAG_TXE))); //等待数据发送完毕
- }
-
- 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.
- *
- * @return none
- */
- 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.
- *
- * @return none
- */
- void AT24CXX_Write(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite)
- {
- while(NumToWrite--)
- {
- AT24CXX_WriteOneByte(WriteAddr, *pBuffer);
- WriteAddr++;
- pBuffer++;
- Delay_Ms(2);
- }
- }
-
-
- void AT24CXX_MulitWriteBytes(u16 WriteAddr, u8 *pBuffer, u16 NumToWrite)
- {
- BOOL last_time = 0;
- u8 duiqi_count = 0;
- //首先要对齐到页
- if(WriteAddr%PAGE_SIZE !=0 ){
- duiqi_count = ((u8)(WriteAddr/PAGE_SIZE )+1)*PAGE_SIZE -WriteAddr;
- printf("duiqi_count:%d\r\n", duiqi_count);
- AT24CXX_WritePage(WriteAddr, pBuffer,duiqi_count);
- NumToWrite = NumToWrite - duiqi_count;
- WriteAddr = WriteAddr + duiqi_count;
- pBuffer = pBuffer + duiqi_count;
- Delay_Ms(3);
- }
- //将剩余数据写入
- while(!last_time)
- {
- if(NumToWrite <= PAGE_SIZE ) //如果小于页大小,为最后 一次写入
- {
- AT24CXX_WritePage(WriteAddr, pBuffer,NumToWrite);
- last_time = 1;
- }
- else { //连续页写入
- AT24CXX_WritePage(WriteAddr, pBuffer,PAGE_SIZE);
- WriteAddr = WriteAddr + PAGE_SIZE;
- pBuffer = pBuffer + PAGE_SIZE;
- NumToWrite = NumToWrite -PAGE_SIZE;
- }
- Delay_Ms(3);
- }
- }
-
- /*********************************************************************
- * @fn main
- *
- * @brief Main program.
- *
- * @return none
- */
- int main(void)
- {
- u8 data[SIZE];
-
- Delay_Init();
- USART_Printf_Init(115200);
- printf("SystemClk:%d\r\n", SystemCoreClock);
-
- AT24CXX_Init();
-
- printf("Start Write 24Cxx....\r\n");
- //AT24CXX_Write(50, (u8 *)TEXT_Buffer, SIZE); //官方是单个写入,多次重复
- AT24CXX_MulitWriteBytes(WR_Address, (u8 *)TEXT_Buffer, SIZE); //修改后是多次页写入
- printf("24Cxx Write Sucess!\r\n");
-
- Delay_Ms(50);
-
- printf("Start Read 24Cxx....\r\n");
- AT24CXX_MulitReadBytes(WR_Address,data,SIZE); //修改后是直接连续读取
- //AT24CXX_Read(100, data, SIZE); //官方程序是单个读取,多次重复
- printf("The Data Readed Is: \r\n");
- printf("%s\r\n", data);
-
- while(1);
- }