- /**
- ********************************************************************
- * 文件名 EEPROM_24LC256.c
- * 作 者 ChipON_AE/FAE_Group
- * 版 本 V2.1
- * 日 期 2019-11-16
- * 描 述 该文件提供了EERPOM读写功能函数等相关函数。
- *
- *********************************************************************
- */
- #include "system_init.h"
- #include "EEPROM_24LC256.h"
- #include "Usart.h"
- I2C_SFRmap* I2C_Choose;
- //延时函数 局部变量用volatile声明,否则可能会被优化
- void Delay(volatile uint32_t cnt)
- {
- while(cnt--);
- }
- /**
- * 描述 eeprom 写入单字节数据。
- * 输入 write_address:eeprom 16位寄存器地址
- * p_buffer: 写入数据,取值为10位数据。
- * 返回 无。
- */
- void eeprom_byte_write(uint16_t write_address,uint32_t p_buffer)
- {
- I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR
- static uint8_t EEPROM_AddH=0;
- static uint8_t EEPROM_AddL=0;
- EEPROM_AddL=write_address& 0xff; //低8位寄存器地址
- EEPROM_AddH=(write_address>>8)& 0xff; //高8位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Cmd(I2C_Choose,TRUE); //使能I2C模块
- /*起始位*/
- I2C_Generate_START(I2C_Choose,TRUE); //使能起始信号
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待起始位稳定
- /*发送I2C从机地址*/
- I2C_SendData(I2C_Choose,EEPROM_I2C_ADDRESS); //发送从机I2C地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /*发送高位地址*/
- I2C_SendData(I2C_Choose,EEPROM_AddH); //发送从机高位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /*发送低位地址*/
- I2C_SendData(I2C_Choose,EEPROM_AddL); //发送从机低位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /*发送数据*/
- I2C_SendData(I2C_Choose, p_buffer); //发送8位数据
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /*停止位*/
- I2C_Generate_STOP(I2C_Choose,TRUE); //使能停止信号
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Clear_Stop_Flag(I2C_Choose); //清I2C停止标志位PIF位
- I2C_Cmd(I2C_Choose,FALSE); //关闭I2C模块
- }
- /**
- * 描述 eeprom 写入多字节数据。
- * 输入 write_address:eeprom 16位寄存器地址
- * p_buffer: 写入数据指针
- * number_of_byte:写入数据长度
- * 返回 无。
- */
- void eeprom_buffer_write(uint16_t Write_address,uint8_t *p_buffer,uint16_t number_of_byte)
- {
- I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR
- static uint8_t EEPROM_AddH=0;
- static uint8_t EEPROM_AddL=0;
- EEPROM_AddL=Write_address& 0xff; //低8位寄存器地址
- EEPROM_AddH=(Write_address>>8)& 0xff; //高8位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Cmd(I2C_Choose,TRUE); //使能I2C模块
- /*起始位*/
- I2C_Generate_START(I2C_Choose,TRUE); //使能起始信号
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
- /*发送I2C从机地址*/
- I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS); //发送从机I2C地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- while(I2C_Get_Ack_Fail_Flag(I2C_Choose)); //判断是否有ACK应答,如没有则停止,如果有则继续发
- /*发送高位地址*/
- I2C_SendData8(I2C_Choose,EEPROM_AddH); //发送从机高位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /*发送低位地址*/
- I2C_SendData8(I2C_Choose,EEPROM_AddL); //发送从机低位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /* 循环写数据操作 */
- while(number_of_byte--){
- I2C_SendData8(I2C_Choose, *p_buffer); //发送8位数据
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- /* 指向下一个所要写的字节 */
- p_buffer++;
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- }
- /*停止位*/
- I2C_Generate_STOP(I2C_Choose,TRUE); //使能停止信号
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Clear_Stop_Flag(I2C_Choose); //清I2C停止标志位PIF位
- I2C_Cmd(I2C_Choose,FALSE); //关闭I2C模组
- }
- /**
- * 描述 eeprom 读出单字节数据。
- * 输入 write_address:eeprom 16位寄存器地址
- * p_buffer: 读出数据,取值为8位数据。
- * 返回 无。
- */
- void eeprom_byte_read(uint16_t Write_address,uint8_t p_buffer)
- {
- I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR
- static uint8_t EEPROM_AddH=0;
- static uint8_t EEPROM_AddL=0;
- EEPROM_AddL=Write_address& 0xff;//低8位寄存器地址
- EEPROM_AddH=(Write_address>>8)& 0xff; //高8位寄存器地址
- I2C_Cmd(I2C_Choose,TRUE);
- /*起始位*/
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Generate_START(I2C_Choose,TRUE); //使能起始信号
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待起始位稳定
- /*发送I2C从机地址*/
- I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS); //发送从机I2C地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- while(I2C_Get_Ack_Fail_Flag(I2C_Choose)); //判断是否有ACK应答,如没有则停止,如果有则继续发
- /*发送要读寄存器高位地址*/
- I2C_SendData8(I2C_Choose,EEPROM_AddH); //发送从机高位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /*发送要读寄存器低位地址*/
- I2C_SendData8(I2C_Choose,EEPROM_AddL); //发送从机低位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- I2C_Cmd(I2C_Choose,FALSE); //关I2C模块
- I2C_Clear_Start_Flag(I2C_Choose); //清I2C起始标志位SIF位
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Cmd(I2C_Choose,TRUE); //使能I2C模块
- /*起始位*/
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF
- I2C_Generate_START(I2C_Choose,TRUE); //使能起始信号
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待起始信号稳定
- /*发送读指令*/
- I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS|0x01);//发送从机地址及读操作
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成ISIF会置1
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //然后完成清标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待读取Buff完成ISIF会置1
- if(I2C_Get_Receive_Buff_Flag(I2C_Choose)) //判断Buff是否为满
- {
- I2C_Ack_DATA_Config(I2C_Choose,I2C_ACKDATA_ACK);//回复ACK
- p_buffer = I2C_ReceiveData(I2C_Choose);
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //然后读完后清标志位ISIF位
- }
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose));
- /*停止位*/
- I2C_Generate_STOP(I2C_Choose,TRUE); //使能停止信号
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Clear_Stop_Flag(I2C_Choose); //清I2C停止标志位PIF位
- I2C_Cmd(I2C_Choose,FALSE); //关闭I2C模组
- }
- /**
- * 描述 eeprom 读出多字节数据。
- * 输入 write_address:eeprom 16位寄存器地址
- * p_buffer: 读出数据指针
- * number_of_byte:读出数据长度
- * 返回 无。
- */
- void eeprom_buffer_read(uint16_t Write_address,uint8_t *p_buffer,uint16_t number_of_byte)
- {
- I2C_Choose=I2C0_SFR;//选择I2C0_SFR I2C1_SFR I2C2_SFR I2C3_SFR
- static uint8_t EEPROM_AddH=0;
- static uint8_t EEPROM_AddL=0;
- EEPROM_AddL=Write_address& 0xff; //低8位寄存器地址
- EEPROM_AddH=(Write_address>>8)& 0xff; //高8位寄存器地址
- I2C_Cmd(I2C_Choose,TRUE); //使能I2C3模块
- /*起始位*/
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Generate_START(I2C_Choose,TRUE); //使能起始信号
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待起始位稳定
- /*发送I2C从机地址*/
- I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS); //发送从机I2C地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- while(I2C_Get_Ack_Fail_Flag(I2C_Choose)); //判断是否有ACK应答,如没有则停止,如果有则继续发
- /*发送要读寄存器高位地址*/
- I2C_SendData8(I2C_Choose,EEPROM_AddH); //发送从机高位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- /*发送要读寄存器低位地址*/
- I2C_SendData8(I2C_Choose,EEPROM_AddL); //发送从机低位寄存器地址
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成
- I2C_Cmd(I2C_Choose,FALSE); //关I2C模块
- I2C_Clear_Start_Flag(I2C_Choose); //清I2C起始标志位SIF位
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清标志位ISIF位
- I2C_Cmd(I2C_Choose,TRUE); //打开I2C模块
- /*起始位*/
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清中断标志位ISIF位
- I2C_Generate_START(I2C_Choose,TRUE); //起始信号
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待起始位稳定
- /*发送读指令*/
- I2C_SendData8(I2C_Choose,EEPROM_I2C_ADDRESS|0x01);//发送从机地址及读操作
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待发送完成ISIF会置1
- while(I2C_Get_Ack_Fail_Flag(I2C_Choose)); //判断是否有ACK应答,如没有则停止,如果有则继续发
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //然后完成清标志位ISIF位
- while(number_of_byte)
- {
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待读取Buff完成ISIF会置1
- if(I2C_Get_Receive_Buff_Flag(I2C_Choose)) //判断Buff是否为满
- {
- *p_buffer = I2C_ReceiveData(I2C_Choose);
- I2C_Ack_DATA_Config(I2C_Choose,I2C_ACKDATA_ACK);//回复ACK
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //然后读完后清标志位ISIF位
- p_buffer++; /* 指向下一个被读取的字节将被保存的位置 */
- /* 递减读取字节计数器 */
- number_of_byte--;
- }
- }
- /*停止位*/
- I2C_Generate_STOP(I2C_Choose,TRUE); //使能停止信号
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- while(!I2C_Get_INTERRUPT_Flag(I2C_Choose)); //等待停止完成
- I2C_Clear_INTERRUPT_Flag(I2C_Choose); //清I2C中断标志位ISIF位
- I2C_Clear_Stop_Flag(I2C_Choose); //清I2C停止标志位PIF位
- I2C_Cmd(I2C_Choose,FALSE); //关闭I2C模组
- }
- /**
- * 描述 先写64个字节数据并读出64个字节数据进行比较。
- * 输入 无
- * 返回 1 :数据对比匹配。
- * 0 :数据对比不匹配。
- */
- uint8_t AT24LC256_TEST(void)
- {
- static volatile uint16_t i;
- static volatile uint16_t j;
- i=0;
- j=0;
- /* 初始化i2c写缓冲区 */
- for(i = 0;i < BUFFER_SIZE;i++)
- {
- i2c_buffer_write[i]=i;
- }
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- /* EEPROM 数据写入 */
- eeprom_buffer_write(EEP_FIRST_PAGE,i2c_buffer_write,sizeof(i2c_buffer_write));
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- /* EEPROM 数据读取 */
- eeprom_buffer_read(EEP_FIRST_PAGE,i2c_buffer_read,sizeof(i2c_buffer_read));
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- Delay(0XFFFF);
- for(j = 0;j < BUFFER_SIZE;j++)
- {
- if(i2c_buffer_read[j] != i2c_buffer_write[j])
- {
- return I2C_FAIL;
- }
- }
- return I2C_OK;
- }