调用Fapi_issueProgrammingCommand(),不报错,但是数据没有存储进去,之后Fapi_getFsmStatus(),报0x30错误,但是flash区域我看过全是0xffff,没有数据
用Fapi_doBlankCheck()函数也校验过这片区域全是0xffff,不应该写入不进去
#ifdef __cplusplus
#pragma CODE_SECTION(".TI.ramfunc");
#else
#pragma CODE_SECTION(FLASH_Write_NoCheck, ".TI.ramfunc");
#endif
uint16_t FLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite)
{
Fapi_StatusType oReturnCheck =0;
oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS,
DEVICE_SYSCLK_FREQ/1000000U);
if(oReturnCheck != Fapi_Status_Success)
{
#ifdef flashdebug
FlashError9++;
#endif
return 1;
}
oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank2);
if(oReturnCheck != Fapi_Status_Success)
{
#ifdef flashdebug
FlashError10++;
#endif
return 2;
}
// Fapi_StatusType oReturnCheck;
uint32 u32Index = 0;
uint16 i = 0;
Fapi_FlashStatusType oFlashStatus;
//Fapi_FlashStatusWordType oFlashStatusWord;
//
// A data buffer of max 8 16-bit words can be supplied to the program
// function.
// Each word is programmed until the whole buffer is programmed or a
// problem is found. However to program a buffer that has more than 8
// words, program function can be called in a loop to program 8 words for
// each loop iteration until the whole buffer is programmed.
//
// Remember that the main array flash programming must be aligned to
// 64-bit address boundaries and each 64 bit word may only be programmed
// once per write/erase cycle. Meaning the length of the data buffer
// (3rd parameter for Fapi_issueProgrammingCommand() function) passed
// to the program function can only be either 4 or 8.
//
// Program data in Flash using "AutoEccGeneration" option.
// When AutoEccGeneration option is used, Flash API calculates ECC for the
// given 64-bit data and programs it along with the 64-bit main array data.
// Note that any unprovided data with in a 64-bit data slice
// will be assumed as 1s for calculating ECC and will be programmed.
//
// Note that data buffer (Buffer) is aligned on 64-bit boundary for verify
// reasons.
//
// Monitor ECC address for Sector6 while programming with AutoEcc mode.
//
// In this example, 0x100 bytes are programmed in Flash Sector6
// along with auto-generated ECC.
//
for(i=0, u32Index = WriteAddr; (u32Index < (WriteAddr+NumToWrite));i+= 8, u32Index+= 8)
{
oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,(uint16_t *)&pBuffer[i],
8, 0, 0, Fapi_AutoEccGeneration);
//
// Wait until the Flash program operation is over
//
while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy);
if(oReturnCheck != Fapi_Status_Success)
{
//
// Check Flash API documentation for possible errors
//
//Example_Error(oReturnCheck);
#ifdef flashdebug
FlashError3++;
#endif
return 3;
}
//
// Read FMSTAT register contents to know the status of FSM after
// program command to see if there are any program operation related
// errors
//
oFlashStatus = Fapi_getFsmStatus();
if(oFlashStatus != 0)
{
//
//Check FMSTAT and debug accordingly
//
//FMSTAT_Fail();
#ifdef flashdebug
FlashError4++;
#endif
return 4;
}
#if 0
//
// Verify the programmed values. Check for any ECC errors.
//
oReturnCheck = Fapi_doVerify((uint32 *)u32Index,
0x4, (UInt32 *)&pBuffer[i],
&oFlashStatusWord);
if(oReturnCheck != Fapi_Status_Success)
{
//
// Check Flash API documentation for possible errors
//
// Example_Error(oReturnCheck);
#ifdef flashdebug
FlashError5++;
#endif
return 5;
}
#endif
}
return 0;
}
WriteAddr地址为0xAFFE0 NumToWrite 为16
MEMORY
{
//BEGIN : origin = 0x00080000, length = 0x00000002
BOOT_RSVD : origin = 0x00000002, length = 0x00000126
RAMM0 : origin = 0x00000128, length = 0x000002D8
RAMM1 : origin = 0x00000400, length = 0x000003F8
// RAMM1_RSVD : origin = 0x000007F8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
RAMLS0 : origin = 0x00008000, length = 0x00000800
RAMLS3 : origin = 0x00008800, length = 0x00000800
//RAMLS3 : origin = 0x00009000, length = 0x00000800
//RAMLS3 : origin = 0x00009800, length = 0x00000800
RAMLS4 : origin = 0x00009000, length = 0x00000200
//RAMLS5 : origin = 0x0000A800, length = 0x00000800
RAMLS5 : origin = 0x00009200, length = 0x00003E00
//RAMLS6 : origin = 0x0000B000, length = 0x00000800
//RAMLS7 : origin = 0x0000B800, length = 0x00000800
RAMGS0 : origin = 0x0000D000, length = 0x00002ff0
//RAMGS1 : origin = 0x0000D000, length = 0x00001000
//RAMGS2 : origin = 0x0000E000, length = 0x00001000
//RAMGS3 : origin = 0x0000F000, length = 0x00000FF8
// RAMGS3_RSVD : origin = 0x0000FFF8, length = 0x00000008 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
BOOTROM : origin = 0x003F8000, length = 0x00007FC0
SECURE_ROM : origin = 0x003F2000, length = 0x00006000
/* Flash sectors */
/* BANK 0 */
FLASH_BANK0_SEC0 : origin = 0x080000, length = 0x001000
FLASH_BANK0_SEC1 : origin = 0x081000, length = 0x001000
FLASH_BANK0_SEC2 : origin = 0x082000, length = 0x001000
FLASH_BANK0_SEC3 : origin = 0x083000, length = 0x001000
FLASH_BANK0_SEC4 : origin = 0x084000, length = 0x001000
FLASH_BANK0_SEC5 : origin = 0x085000, length = 0x001000
FLASH_BANK0_SEC6 : origin = 0x086000, length = 0x001000
FLASH_BANK0_SEC7 : origin = 0x087000, length = 0x001000
FLASH_BANK0_SEC8 : origin = 0x088000, length = 0x001000
FLASH_BANK0_SEC9 : origin = 0x089000, length = 0x001000
FLASH_BANK0_SEC10 : origin = 0x08A000, length = 0x001000
FLASH_BANK0_SEC11 : origin = 0x08B000, length = 0x001000
FLASH_BANK0_SEC12 : origin = 0x08C000, length = 0x001000
FLASH_BANK0_SEC13 : origin = 0x08D000, length = 0x001000
FLASH_BANK0_SEC14 : origin = 0x08E000, length = 0x001000
FLASH_BANK0_SEC15 : origin = 0x08F000, length = 0x001000
/* BANK 1 */
FLASH_BANK1_SEC15 : origin = 0x09F000, length = 0x001000
/* BANK 2 */
FLASH_BANK2_SEC0 : origin = 0x0A0000, length = 0x001000
FLASH_BANK2_SEC1 : origin = 0x0A1000, length = 0x001000
FLASH_BANK2_SEC2 : origin = 0x0A2000, length = 0x001000
FLASH_BANK2_SEC3 : origin = 0x0A3000, length = 0x001000
FLASH_BANK2_SEC4 : origin = 0x0A4000, length = 0x001000
FLASH_BANK2_SEC5 : origin = 0x0A5000, length = 0x001000
FLASH_BANK2_SEC6 : origin = 0x0A6000, length = 0x001000
FLASH_BANK2_SEC7 : origin = 0x0A7000, length = 0x001000
FLASH_BANK2_SEC8 : origin = 0x0A8000, length = 0x001000
FLASH_BANK2_SEC9 : origin = 0x0A9000, length = 0x001000
FLASH_BANK2_SEC10 : origin = 0x0AA000, length = 0x001000
FLASH_BANK2_SEC11 : origin = 0x0AB000, length = 0x001000
FLASH_BANK2_SEC12 : origin = 0x0AC000, length = 0x001000
FLASH_BANK2_SEC13 : origin = 0x0AD000, length = 0x001000
FLASH_BANK2_SEC14 : origin = 0x0AE000, length = 0x001000
FLASH_BANK2_SEC15 : origin = 0x0AF000, length = 0x000FF0
RESET : origin = 0x003FFFC0, length = 0x00000002
#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 20012000
GROUP { /* GROUP memory ranges for crc/checksum of entire flash */
#endif
#endif
BEGIN : origin = 0x090000, length = 0x000002
FLASH_BANK1_SEC0 : origin = 0x090002, length = 0x0019FE
FLASH_BANK1_SEC1 : origin = 0x091A00, length = 0x001000
FLASH_BANK1_SEC2 : origin = 0x092A00, length = 0x000B00
FLASH_BANK1_SEC3 : origin = 0x093500, length = 0x00BB00-0x80
// FLASH_BANK0_SEC15_RSVD : origin = 0x0AFFF0, length = 0x000010 /* Reserve and do not use for code as per the errata advisory "Memory: Prefetching Beyond Valid Memory" */
#ifdef __TI_COMPILER_VERSION__
#if __TI_COMPILER_VERSION__ >= 20012000
} crc(_ccs_flash_checksum, algorithm=CRC16_ALT)
CRC_TABLE : origin = 0x09F000-0x80, length = 0x000080
#endif
#endif
}
SECTIONS
{
codestart : > BEGIN, ALIGN(8)
.text : >> FLASH_BANK1_SEC3, ALIGN(8)
.cinit : > FLASH_BANK1_SEC0, ALIGN(8)
.switch : > FLASH_BANK1_SEC0, ALIGN(8)
.reset : > RESET, TYPE = DSECT /* not used, */
.stack : > RAMM1
#if defined(__TI_EABI__)
.init_array : > FLASH_BANK1_SEC0, ALIGN(8)
.bss : > RAMLS5, ALIGN(2)
.bss:output : > RAMLS3
.bss:cio : > RAMLS0
.data : > RAMLS5, ALIGN(2)
.sysmem : > RAMLS5, ALIGN(2)
.const : > FLASH_BANK1_SEC2, ALIGN(8)
#else
.pinit : > FLASH_BANK1_SEC0, ALIGN(8)
.ebss : >> RAMM0|RAMLS5|RAMLS3, ALIGN(2)
.esysmem : > RAMLS5, ALIGN(2)
.cio : > RAMLS0
.econst : > FLASH_BANK1_SEC2, ALIGN(8)
#endif
ramgs0 : > RAMGS0
ramgs1 : > RAMGS0
/* Allocate IQ math areas: */
IQmath : > FLASH_BANK1_SEC0, ALIGN(8)
IQmathTables : > FLASH_BANK1_SEC1, ALIGN(8)
GROUP
{
.TI.ramfunc
{ -l FAPI_F28003x_COFF_v1.58.10.lib}
}
LOAD = FLASH_BANK1_SEC1,
RUN = RAMGS0,
LOAD_START(_RamfuncsLoadStart),
LOAD_SIZE(_RamfuncsLoadSize),
LOAD_END(_RamfuncsLoadEnd),
RUN_START(_RamfuncsRunStart),
RUN_SIZE(_RamfuncsRunSize),
RUN_END(_RamfuncsRunEnd),
ALIGN(8)
/* crc/checksum section configured as COPY section to avoid including in executable */
//.TI.memcrc : type = COPY
.TI.memcrc > CRC_TABLE
}
FSM值0x30表示用户尝试编程"1",其中已存在"0"。
您能否删除它并重新编程,看看您是否面临同样的问题?
您是否首先使用0xFF对该区域进行编程,然后尝试使用不同的值对其进行编程? 因为我在您的编程位置后看到0x55AA值。
/*写一个字节数据,但是DSP特殊结构相当于二个字节*/ #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(FLASH_Write, ".TI.ramfunc"); #endif /* * 地址:0XAF000---0xAFFFF * WriteAddr :地址 * pBuffer :要写入的数据地址 * NumToWrite :要写入数据的长度 */ void FLASH_Write(uint32_t WriteAddr,uint16_t* pBuffer,uint16_t NumToWrite) { uint16 FlashFlag =0; uint32_t sec_addr;//扇区地址 uint16_t sec_off; //扇区内偏移地址(16位字计算) uint16_t sec_remain;//扇区内剩余地址(16位字计算) uint16_t i; uint32_t offaddr; //去掉0xAE000U的地址 0x1000 1 if(WriteAddr<EEPROM_BASE||(WriteAddr>=(EEPROM_BASE+(uint32_t)EEPROM_SECTOR_SIZE*EEPROM_SIZE)))return;//非法地址 if(NumToWrite ==0) return; // Btwo_Sector15_start 0xAF000U 0x1000 1 if(WriteAddr + NumToWrite >= (EEPROM_BASE+(uint32_t)EEPROM_SECTOR_SIZE*EEPROM_SIZE)) return; offaddr=WriteAddr-EEPROM_BASE; //实际偏移地址. sec_addr= offaddr/EEPROM_SECTOR_SIZE; //扇区地址 0 sec_off = offaddr%EEPROM_SECTOR_SIZE; //扇区内的偏移地址(2个字节为基本单位) sec_remain=EEPROM_SECTOR_SIZE-sec_off; //以两个字节为基本单位的话,所以一页内有STM_SECTOR_SIZE个基本单位。 //一页内剩余多少个基本单位呢?直接减去一页内的偏移地址就可以了 if(NumToWrite<=sec_remain)sec_remain=NumToWrite;//不大于该扇区范围 if(NumToWrite ==1) { #ifdef flashdebug test3++; #endif FLASH_Write_HalfWord(WriteAddr,pBuffer[0]); return ; } else { while(1) { memset(FLASH_BUF,0,EEPROM_SECTOR_SIZE); FLASH_ReadHalfData(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE); for(i=0;i<sec_remain;i++) { if(FLASH_BUF[sec_off+i]!=0xffff)break;//当检查到有地址内地数据不为0xffff,那么就跳出for循环; } if(i<sec_remain)//判断i的值是否小于该页的剩余量,如果小于,则说明要擦除整页。 { #ifdef flashdebug test4++; #endif FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区 for(i=0;i<sec_remain;i++) { FLASH_BUF[i+sec_off]=pBuffer[i]; } FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页) } else { //写已经擦除了的,直接写入扇区剩余区间. if(sec_off %8 ==0) // 写入地址对齐 { for(i=0;i<sec_remain;i++) { FLASH_BUF[i+sec_off]=pBuffer[i]; } if(sec_remain %8 !=0) // 存储的数据不是8的倍数 { for(i=0;i< (8- sec_remain%8);i++) //数据会补齐,先检测是否全为0Xffff { if(FLASH_BUF[i+sec_off+sec_remain]!=0xffff) { #ifdef flashdebug test5++; #endif FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区 break; } } } if(sec_remain %8 ==0) { #ifdef flashdebug test6++; #endif // 如果写2个扇区里面内容会进入这条语句 FLASH_Write_NoCheck(WriteAddr,&FLASH_BUF[sec_off],sec_remain);//写已经擦除了的,直接写入扇区剩余区间 } else { #ifdef flashdebug test7++; #endif FlashFlag=FLASH_Write_NoCheck(WriteAddr,&FLASH_BUF[sec_off],(sec_remain/8+1)*8);//写已经擦除了的,直接写入扇区剩余区间 } } else // 写入地址不对齐 { if((sec_off % 8 +sec_remain) >8) // 以8个地址对齐 , 偏移地址+要写入的数据的长度 { for(i=0;i< ((sec_remain/8+2)*8);i++) //数据会补齐,先检测是否全为0Xffff { if(FLASH_BUF[i+(sec_off/8)*8] !=0xffff) { #ifdef flashdebug test8++; #endif FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区 break; } } if(i<((sec_remain/8+2)*8)) { #ifdef flashdebug test9++; #endif for(i=0;i<sec_remain;i++) { FLASH_BUF[i+sec_off]=pBuffer[i]; } FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页) } else { #ifdef flashdebug test10++; #endif for(i=0;i<sec_remain;i++) { FLASH_BUF[i+sec_off]=pBuffer[i]; } // 如果写2个扇区里面内容会进入这条语句 FlashFlag=FLASH_Write_NoCheck((WriteAddr/8)*8,&FLASH_BUF[(sec_off/8) *8],(sec_remain/8+2)*8);//写已经擦除了的,直接写入扇区剩余区间 } } else { for(i=0;i< ((sec_remain/8+1)*8);i++) //数据会补齐,先检测是否全为0Xffff { if(FLASH_BUF[i+(sec_off/8)*8] !=0xffff) { #ifdef flashdebug test11++; #endif FlashFlag=FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区 break; } } if(i<((sec_remain/8+1)*8)) { #ifdef flashdebug test12++; #endif for(i=0;i<sec_remain;i++) { FLASH_BUF[i+sec_off]=pBuffer[i]; } FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页) } else { #ifdef flashdebug test13++; #endif for(i=0;i<sec_remain;i++) { FLASH_BUF[i+sec_off]=pBuffer[i]; } FlashFlag=FLASH_Write_NoCheck((WriteAddr/8)*8,&FLASH_BUF[(sec_off/8) *8],((sec_remain/8+1)*8));//写已经擦除了的,直接写入扇区剩余区间 } } } } if(NumToWrite==sec_remain)break;//写入结束了,跳出while循环 else//写入未结束 { sec_addr++; //扇区地址增1 sec_off=0; //偏移位置为0 pBuffer+=sec_remain; //指针偏移 WriteAddr+=sec_remain; //写地址偏移 NumToWrite-=sec_remain; //字节(16位)数递减 if(NumToWrite>(EEPROM_SECTOR_SIZE)) { sec_remain=EEPROM_SECTOR_SIZE;//下一个扇区还是写不完 } else { sec_remain=NumToWrite;//下一个扇区可以写完了 } } } } }
FLASH_Write()函数就是模拟EEPROM的函数接口,在函数里面我调用的是FLASH_Write_NoCheck()
uint16_t *EEpromTemp =(uint16_t *) 0x9010;
#define SelfLearn_ADDRESS 0x0AFFE0
一:擦除和编程总是成功的,
是整个扇区擦除
FLASH_ErasePage(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE);//擦除这个扇区
#ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(FLASH_ErasePage, ".TI.ramfunc"); #endif uint16_t FLASH_ErasePage(uint32_t WriteAddr) { //uint16 i = 0; uint16 sectorNo =0; Fapi_StatusType oReturnCheck; oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, DEVICE_SYSCLK_FREQ/1000000U); if(oReturnCheck != Fapi_Status_Success) { #ifdef flashdebug FlashError1++; #endif return 1; } oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank2); if(oReturnCheck != Fapi_Status_Success) { #ifdef flashdebug FlashError2++; #endif return 2; } sectorNo = (WriteAddr-EEPROM_BASE)/EEPROM_SECTOR_SIZE +15; Example_EraseAppBackSector(sectorNo); return 0; }
FlashFlag=FLASH_Write_NoCheck(sec_addr*EEPROM_SECTOR_SIZE+EEPROM_BASE,FLASH_BUF,EEPROM_SECTOR_SIZE);//写入整个扇区(页)
// 不检查的写入 // WriteAddr:起始地址 // pBuffer:数据指针 // NumToWrite:半字(16位)数 #ifdef __cplusplus #pragma CODE_SECTION(".TI.ramfunc"); #else #pragma CODE_SECTION(FLASH_Write_NoCheck, ".TI.ramfunc"); #endif uint16_t FLASH_Write_NoCheck(uint32_t WriteAddr,uint16_t *pBuffer,uint16_t NumToWrite) { Fapi_StatusType oReturnCheck =0; oReturnCheck = Fapi_initializeAPI(F021_CPU0_BASE_ADDRESS, DEVICE_SYSCLK_FREQ/1000000U); if(oReturnCheck != Fapi_Status_Success) { #ifdef flashdebug FlashError9++; #endif return 1; } oReturnCheck = Fapi_setActiveFlashBank(Fapi_FlashBank2); if(oReturnCheck != Fapi_Status_Success) { #ifdef flashdebug FlashError10++; #endif return 2; } // Fapi_StatusType oReturnCheck; uint32 u32Index = 0; uint16 i = 0; Fapi_FlashStatusType oFlashStatus; //Fapi_FlashStatusWordType oFlashStatusWord; // // A data buffer of max 8 16-bit words can be supplied to the program // function. // Each word is programmed until the whole buffer is programmed or a // problem is found. However to program a buffer that has more than 8 // words, program function can be called in a loop to program 8 words for // each loop iteration until the whole buffer is programmed. // // Remember that the main array flash programming must be aligned to // 64-bit address boundaries and each 64 bit word may only be programmed // once per write/erase cycle. Meaning the length of the data buffer // (3rd parameter for Fapi_issueProgrammingCommand() function) passed // to the program function can only be either 4 or 8. // // Program data in Flash using "AutoEccGeneration" option. // When AutoEccGeneration option is used, Flash API calculates ECC for the // given 64-bit data and programs it along with the 64-bit main array data. // Note that any unprovided data with in a 64-bit data slice // will be assumed as 1s for calculating ECC and will be programmed. // // Note that data buffer (Buffer) is aligned on 64-bit boundary for verify // reasons. // // Monitor ECC address for Sector6 while programming with AutoEcc mode. // // In this example, 0x100 bytes are programmed in Flash Sector6 // along with auto-generated ECC. // for(i=0, u32Index = WriteAddr; (u32Index < (WriteAddr+NumToWrite));i+= 8, u32Index+= 8) { oReturnCheck = Fapi_issueProgrammingCommand((uint32 *)u32Index,(uint16_t *)&pBuffer[i], 8, 0, 0, Fapi_AutoEccGeneration); // // Wait until the Flash program operation is over // while(Fapi_checkFsmForReady() == Fapi_Status_FsmBusy); if(oReturnCheck != Fapi_Status_Success) { // // Check Flash API documentation for possible errors // //Example_Error(oReturnCheck); #ifdef flashdebug FlashError3++; #endif return 3; } // // Read FMSTAT register contents to know the status of FSM after // program command to see if there are any program operation related // errors // oFlashStatus = Fapi_getFsmStatus(); if(oFlashStatus != 0) { // //Check FMSTAT and debug accordingly // //FMSTAT_Fail(); #ifdef flashdebug FlashError4++; #endif return 4; } #if 0 // // Verify the programmed values. Check for any ECC errors. // oReturnCheck = Fapi_doVerify((uint32 *)u32Index, 0x4, (UInt32 *)&pBuffer[i], &oFlashStatusWord); if(oReturnCheck != Fapi_Status_Success) { // // Check Flash API documentation for possible errors // // Example_Error(oReturnCheck); #ifdef flashdebug FlashError5++; #endif return 5; } #endif } return 0; }
我们要存储的数据更新在FLASH_BUF数组中,EEPROM_SECTOR_SIZE 大小长度为0x1000
但是这样整体擦除,在整体写入,会应用flash使用次数,因为我们当作模拟EEPROM使用的,
二:第一次使用0xffff值对位置进行编程并使用其他值重新编程时,编程会给fmstat错误0x30。
这个没有使用整个扇区擦除,整体扇区写入的方式,而是指令地址写入
uint16_t *EEpromTemp =(uint16_t *) 0x9010; ,
memcpy((uint16_t *)EEpromTemp,(uint16_t *)TxFlashbuff,16);
FLASH_Write(SelfLearn_ADDRESS,EEpromTemp,10);
TxFlashbuff 数组里面数据全为0xFFFF
这样调用FLASH_Write()这个模拟EEPROM的函数,没有报错
之后更改TxFlashbuff 数组数据
再次调用FLASH_Write()这个模拟EEPROM的函数,报错了
因为我也判断了,SelfLearn_ADDRESS地址flash里面数据全是0XFFFF,不要擦除,可以直接写入
FlashFlag=FLASH_Write_NoCheck(WriteAddr,&FLASH_BUF[sec_off],(sec_remain/8+1)*8);//写已经擦除了的,直接写入扇区剩余区间
通过仿真查看这个变量报错,flash也没有写入进去