说明,主程序中先判断上次写操作是否完成,如果完成了则调用“更新eeprom内容”程序。 在“更新eeprom内容”程序中,每次只操作一个单元。先把要修改的单元读出来校验,如果读出数据与待写入数据一致,则切换到下一单元。如果连续N次不一致,代表该单元写失败,跳过。 在执行写操作时,中断已经关闭了。 相关程序如下: //-------------------------------------------------------- //主函数 //-------------------------------------------------------- void main(void) { init(); //====初始化
//====循环主体 while (1) { //......略 if ( (EEPROM_NEW_FLAGS!=0) && (WR==0) && (NO_KEY_JSQ>2) ) new_eeprom() ; //如果EEPROM数据更新标志<>0,且上次的写操作结束,且无按键计数器>2,则更新eeprom内容
} }
//-------------------------------------------------------- //更新eeprom内容 //-------------------------------------------------------- void new_eeprom ( void ) { //====显示列计数器 角度校正值(0~179) (用于校正盘面角度) if ( DISP_LINE_ADJ_FLAG ) { //......略 }
//......略
//====自定义点阵图片 else if ( PICTURE_FLAG ) { if ( EEP_SAVE_ID <= 90 ) //保存自定义点阵图片上部 { //读出校验 EEADR = PICTURE1_ADR + EEP_SAVE_ID ; //地址 read_eeprom() ; //EEPROM字节读程序 if ( EEDATA == DISP_QUEUE1[EEP_SAVE_ID] ) //如果校验一致 { EEPROM_ERR_JSQ = 0 ; //EPPROM写失败计数器=0 EEP_SAVE_ID ++ ; //EEPROM存储指针+1 } else if ( ++EEPROM_ERR_JSQ > 3 ) //如果连续n次写入失败 { EEPROM_ERR_JSQ = 0 ; //EPPROM写失败计数器=0 EEPROM_ERR_FLAG = 1 ; //EPPROM写失败标志=1 EEP_SAVE_ID ++ ; //EEPROM存储指针+1 } else //否则,更新数据 { EEDATA = DISP_QUEUE1[EEP_SAVE_ID] ; //数据 write_eeprom() ; //EEPROM字节写程序 } } if ( EEP_SAVE_ID <= 180 ) //保存自定义点阵图片下部 { //读出校验 EEADR = PICTURE2_ADR + EEP_SAVE_ID - 90 ; //地址 read_eeprom() ; //EEPROM字节读程序 if ( EEDATA == DISP_QUEUE2[EEP_SAVE_ID - 90] ) //如果校验一致 { EEPROM_ERR_JSQ = 0 ; //EPPROM写失败计数器=0 EEP_SAVE_ID ++ ; //EEPROM存储指针+1 } else if ( ++EEPROM_ERR_JSQ > 3 ) //如果连续n次写入失败 { EEPROM_ERR_JSQ = 0 ; //EPPROM写失败计数器=0 EEPROM_ERR_FLAG = 1 ; //EPPROM写失败标志=1 EEP_SAVE_ID ++ ; //EEPROM存储指针+1 } else //否则,更新数据 { EEDATA = DISP_QUEUE2[EEP_SAVE_ID - 90] ; //数据 write_eeprom() ; //EEPROM字节写程序 } } else //保存自定义点阵图片有效标志(0X5A=有效,否则=无效) { //读出校验 EEADR = PICTURE_EN_ADR ; //地址 read_eeprom() ; //EEPROM字节读程序 if ( EEDATA == 0X5A ) //如果校验一致 { EEPROM_ERR_JSQ = 0 ; //EPPROM写失败计数器=0 PICTURE_FLAG = 0 ; //自定义点阵图片更新标志=0 EEP_SAVE_ID = 0 ; //EEPROM存储指针=0 } else if ( ++EEPROM_ERR_JSQ > 3 ) //如果连续n次写入失败 { EEPROM_ERR_JSQ = 0 ; //EPPROM写失败计数器=0 EEPROM_ERR_FLAG = 1 ; //EPPROM写失败标志=1 PICTURE_FLAG = 0 ; //自定义点阵图片更新标志=0 EEP_SAVE_ID = 0 ; //EEPROM存储指针=0 } else //否则,更新数据 { EEDATA = 0X5A ; //数据 write_eeprom() ; //EEPROM字节写程序 } } }
//====异常处理 else { EEPROM_NEW_FLAGS = 0 ; //EEPROM数据更新标志=0 } }
//-------------------------------------------------------- //EEPROM字节写程序 //功能: 写一个字节到内部EEPROM //入口: EEADR =地址 // EEDATA =数据 //-------------------------------------------------------- void write_eeprom ( void ) { EEPGD = 0 ; //设置访问目标为EEPROM WREN = 1 ; //允许进行写操作 GIE = 0 ; //禁止中断 EECON2 = 0x55 ; EECON2 = 0xAA ; WR = 1 ; //启动一次写操作 GIE = 1 ; //使能中断 WREN = 0 ; //关闭写操作 }
//-------------------------------------------------------- //EEPROM字节读程序 //功能: 从内部EEPROM读一个字节 //入口: EEADR =地址 //出口: EEDATA =数据 //-------------------------------------------------------- void read_eeprom( void ) { EEPGD = 0 ; //设置访问目标为EEPROM RD = 1 ; //启动一次读操作 } |