各位大侠,斑竹大人: 您们好!我的这个问题已经困扰我好多天了
我现在的应用环境如下:单片机是MC9S12D64,上面运行的程序是由uCOS进行任务调度的。运用的内存模式是Small,总线频率是20MHZ。我写EEPROM没有任何问题,写FLASH就总是复位,当我把看门狗关掉后,写FLASH就造成单片机死机。我的程序都放到了其它区域了,留下了ROM_4000专门用来进行FLASH写入的。因为我写的数据较多,有10多K,所以必须用一块FLASH来存储这些数据,且这些数据必须要能够时常更新。 我的相关PRM文件和FLASH操作代码在下面。请帮我分析下问题,谢谢! prm: ///======================================= /// <summary> /// RAM location /// </summary> ///======================================= RAM = READ_WRITE 0x0400 TO 0x0FFF; ///======================================= /// <summary> /// EEPROM location /// </summary> ///======================================= EEPROM = READ_ONLY 0x2800 TO 0x2BEF;
///======================================= /// <summary> /// non-paged FLASHs /// </summary> ///======================================= ROM_4000 = READ_ONLY 0x4000 TO 0x7FFF; ROM_C000 = READ_ONLY 0xC000 TO 0xFEFF;
///======================================= /// <summary> /// paged FLASHs /// </summary> ///======================================= PAGE_3C = READ_ONLY 0x3C8000 TO 0x3CBFFF; PAGE_3D = READ_ONLY 0x3D8000 TO 0x3DBFFF; END ///======================================= /// <summary> /// here all predefined and user segments are placed into the SEGMENTS defined above. /// </summary> ///======================================= PLACEMENT _PRESTART, /* Used in HIWARE format: jump to _Startup at the code start */ STARTUP, /* startup data structures */ VIRTUAL_TABLE_SEGMENT, /* C++ virtual table segment */ NON_BANKED, /* runtime routines which must not be banked */ COPY /* copy down information: how to initialize variables */ /* in case you want to use ROM_4000 here as well, make sure that all files (incl. library files) are compiled with the option: -OnB=b */ INTO ROM_C000/*, ROM_4000*/;
STRINGS, /* string literals */ DEFAULT_ROM, ROM_VAR INTO PAGE_3C,PAGE_3D; /* constant variables */
EE_DATA INTO EEPROM;
SSTACK, /* allocate stack first to avoid overwriting variables on overflow */ DEFAULT_RAM INTO RAM; END
///======================================= /// <summary> /// ENTRIES 我的FLASH操作代码: void FLASH_Init(void) { FCLKDIV = 77; // Set up Clock Divider Register FCNFG=0x00; //disable FLASH interrupts! while(FCLKDIV_FDIVLD==0) ; //wait until the clock is succeful set.
FPROT_FPOPEN=1; //enable erase and programe on FLASH FPROT_FPLDIS=1; //disable FLASH low address protection } static byte EraseFLASHSector(word address) { while(!(FCLKDIV&0x80)) ; //modified clock divider? while(FSTAT_CBEIF == 0); //Is command buffer empty ?
FSTAT= 0x30; /* Clear all flags */ while(!(FPROT&0x80)) ; //enable erase? *(volatile word*) (address&0xFFFF)= 0x0000; /* Write any word to FLASH buffer */ FCMD = 0x40; /* Initiate Sector Erase commamd */ FSTAT = 0x80; /* Clear flag command buffer empty */ _asm NOP;_asm NOP;_asm NOP;_asm NOP;
while (FSTAT_CBEIF == 0); /* Wait to buffer empty */ while (FSTAT_CCIF == 0); /* Wait to command complete */ return ERR_OK; /* OK */ } static byte WriteWordToFLASH(word data,word address) { while(!(FCLKDIV&0x80)) ; //modified clock divider? while(FSTAT_CBEIF == 0); //Is command buffer empty ?
FSTAT= 0x30; /* Clear all flags */ while(!(FPROT&0x80)); //enable erase? *(volatile word *)address = data; /* Array address and program data */ FCMD = 0x20; /* Word program command */ FSTAT = 0x80; /* Clear flag command buffer empty */ _asm NOP;_asm NOP;_asm NOP;_asm NOP;
while (FSTAT_CBEIF == 0); /* Wait to buffer empty */ while (FSTAT_CCIF == 0); /* Wait to command complete */
if (*(word *) address != data) /* Was attempt to write data to the given address errorneous? */ return ERR_VALUE; /* If yes then error */ return ERR_OK; /* OK */ } void StoreDataToFlash(word data,word address) { if (address & 1) return ; while(FSTAT_CCIF == 0) ; /* Wait to command complete */
if (*(word *) address != 0xFFFF) //need erased? { FSTAT = 0x30; // Clear all flags *(volatile word *) (address&0xFFFF) = 0x0000; // Write any word to FLASH buffer FCMD = 0x40; // Initiate Sector Erase command FSTAT = 0x80; // Clear flag command buffer empty while (FSTAT_CBEIF == 0); // Wait to buffer empty while (FSTAT_CCIF == 0); // Wait to command complete }
FSTAT= 0x30; //clear used flags *(volatile word*)address=data; FCMD= 0x20; FSTAT= 0x80; //clear command buffer flag
while(FSTAT_CBEIF==0); while(FSTAT_CCIF==0); } word ReadDataFromFlash(word address) { if (address & 1) /* Aligned address ? */ return ERR_NOTAVAIL; while(FSTAT_CCIF == 0) ; /* Is previous command complete ? */ return *(volatile word *) address; /* Get word form Flash */ }
|