/* * eeprom.c * * Created on: Aug 8, 2021 * Author: wuwenfeng */ #include "eeprom.h" //iic硬件接口 extern I2C_HandleTypeDef hi2c2; void IIC_SAND_DATE(uint16_t DEVICE_ADD,uint16_t IN_DEVICE_ADD,char *DATAS,uint16_t LONG) { HAL_I2C_Mem_Write(&hi2c2,DEVICE_ADD,IN_DEVICE_ADD,I2C_MEMADD_SIZE_8BIT,DATAS,LONG,100); } void IIC_READ_DATE(uint16_t DEVICE_ADD,uint16_t IN_DEVICE_ADD,char *DATAS,uint16_t LONG) { HAL_I2C_Mem_Read(&hi2c2,DEVICE_ADD,IN_DEVICE_ADD,I2C_MEMADD_SIZE_8BIT,DATAS,LONG,100); } //因为eeprom芯片的写入速度有限,每写入一个字符都需要等待一段时间才能完成写入 //整个系统不可能等它一个的,传统的解决方法可以使用定时器中断或者多线程开辟子任务在后台保存, //这里的解决方法是使用状态机,通过一个链表将要保存的数据串起来,再通过状态循环一个个保存,保存延时等于循环用时。 eeprom_write_buff_info eeprom_write_buffer; //创建链表 void EPPROM_SLOWWRITE_INIT() //初始化链表 { eeprom_write_buffer.buff=NULL; eeprom_write_buffer.end=NULL; eeprom_write_buffer.head=NULL; eeprom_write_buffer.save_timeout=5; //避免状态机循环过快导致的保存失败,这个是最少延时。(感觉没必要写在这里,太浪费空间了) eeprom_write_buffer.save_busy=0; //最小延时内为忙状态 } //循环保存服务,检查链表头是否有数据是否忙。 void EEPROM_SLOWWRITE_SERVER() { eeprom_write_buff *buff; char data; if(eeprom_write_buffer.save_busy) { if(HAL_GetTick()>eeprom_write_buffer.save_time) { eeprom_write_buffer.save_busy=0; } }else { if(eeprom_write_buffer.head!=NULL) { eeprom_write_buffer.save_busy=1; eeprom_write_buffer.save_time=HAL_GetTick()+eeprom_write_buffer.save_timeout; buff=eeprom_write_buffer.head->next; data=eeprom_write_buffer.head->date; IIC_SAND_DATE(EEPROM_ADDRESS,eeprom_write_buffer.head->add,&data,1); free(eeprom_write_buffer.head); eeprom_write_buffer.head=buff; } } } //从eeprom读取数据 void EEPROM_READ_BATY(uint16_t IN_DEVICE_ADD,char *DATAS,uint16_t LONG) { IIC_READ_DATE(EEPROM_ADDRESS,IN_DEVICE_ADD,DATAS,LONG); } //向eeprom写入数据 void EEPROM_WRITE_BATY(uint16_t IN_DEVICE_ADD,char *DATAS,uint16_t LONG) { //IIC_SAND_DATE(EEPROM_ADDRESS,IN_DEVICE_ADD,DATAS,LONG); uint16_t addoffset=0; eeprom_write_buff *buff; eeprom_write_buff *buff2; while(LONG--) { buff =(eeprom_write_buff*)malloc(sizeof(eeprom_write_buff)); if(buff!=NULL) { buff->add=IN_DEVICE_ADD+addoffset; buff->date=DATAS[addoffset]; buff->next=NULL; }else{return ;} if(eeprom_write_buffer.head==NULL) { eeprom_write_buffer.head=buff; eeprom_write_buffer.end=buff; }else { buff2=eeprom_write_buffer.end; buff2->next=buff; eeprom_write_buffer.end=buff; } addoffset++; } }