各位大侠,斑竹大人:
您们好!我的这个问题已经困扰我好多天了
我现在的应用环境如下:单片机是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 */
}
把程序拷到RAM里执行,D64只有一个BLOCK!
关注ing...........
Note: Flash擦写代码和要擦除的block必需分开啊!最好的办法是将其调到RAM中运行,我以前写Bootloader的时候遇到类似问题。QQ:524673287
欢迎光临 电子技术论坛_中国专业的电子工程师学习交流社区-中电网技术论坛 (http://bbs.eccn.com/) | Powered by Discuz! 7.0.0 |