首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

请教S12D64单片机FLASH写入的问题,谢谢!

请教S12D64单片机FLASH写入的问题,谢谢!

各位大侠,斑竹大人:

您们好!我的这个问题已经困扰我好多天了

我现在的应用环境如下:单片机是MC9S12D64,上面运行的程序是由uCOS进行任务调度的。运用的内存模式是Small,总线频率是20MHZ。我写EEPROM没有任何问题,写FLASH就总是复位,当我把看门狗关掉后,写FLASH就造成单片机死机。我的程序都放到了其它区域了,留下了ROM_4000专门用来进行FLASH写入的。因为我写的数据较多,有10K,所以必须用一块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

Bootloader,TCP/IP, 数字化电源控制 MCU应用专家 QQ:524673287
返回列表