看下面贴子:在RAM中执行程序对FLASH擦写,并且在擦写FLASH之前关闭所有中断。
问:
一直不是很清楚逻辑地址、全局地址和物理地址之间的关系,这里向各位大大请教。我用的是9s12hy48,程序大概20多k。需要将存储区一块12k的空间单独拿出来,用以存储点阵信息,这个需要是可变的,不过擦写次数不会很频繁。先用D-FLASH实验,是好的。
DFlash擦写时使用地址0x4400,调用的时候 用 uint8 *disa; disa = (uint8*)0x10400; 可以实现功能,不过就是DFLASH只有4k,太小。(擦写时用地址0x4400,而调用时要用地址0x10400,这之间什么关系?)
但是我换用PFLASH时,就不行了。我先定义一个数组:
const uint8 Disf[10000] @0xe8000 = {0x00,0x11,0x22,0x33,0x00,0xff,0x00,0xff,0x00,0xff}; 然后按地址 0x38000擦写,不成功?
请问按是不是按页地址的话就是写PPAGE = 0e 再写0x8000?我真是不知道他们之间的关系,请大侠帮忙看看程序,程序如下:
#include "main.h"
#include "config.h"
#include "flash.h"
#define FLASH_GLOBAL_ADDRESS 0x4400
#define FLASH_PHYSICAL_ADDRESS 0x10400
#define PFLASH_GLOBAL_ADDRESS 0x8000
#define PFLASH_PHYSICAL_ADDRESS 0xe8000
#define PFLASH_CMD_ERASE_VERITY 0x0303 // 命令码 + HI地址
#define PFLASH_CMD_WRITE 0x0603 // 命令码 + HI地址
#define PFLASH_CMD_ERASE 0x0a03 // 命令码 + HI地址
#define FLASH_CMD_ERASE_VERITY 0x1000
#define FLASH_CMD_WRITE 0x1100
#define FLASH_CMD_ERASE 0x1200
//#pragma MESSAGE DISABLE C2705
//#pragma 0x34000 //OTHER_ROM1
/******************************************************************************
功 能:void FLASH_Init(void)
描 述:FLASH初化
参 数: 无
返 回:无
******************************************************************************/
//static void Cpu_FlashInit(void)
void Cpu_FlashInit(void)
{
FSTAT = 0x30; /* clear ACCERR & FPVIOL flag in flash status register */
FERSTAT = 0x03; /* clear DFDIF,SFDIF & EPVIOLIF flag in flash error status register */
FCNFG = 0x10; /* Set the ignore single bit fault value, so that the single bit faults are ignored */
if(!FCLKDIV_FDIVLD) /* clock not set */
{
FCLKDIV = 0x44;
}
}
/******************************************************************************
功 能:void FLASH_EraseVerify(uint16 frist_add)
描 述:擦除校验P-FLASH
参 数: 无
返 回:无
******************************************************************************/
void PFLASH_EraseVerify(uint16 frist_add)
{
while(!FSTAT_CCIF); // check CCIF bit
FSTAT = 0x30;
// clear ACCERR and FPVIOL bits
FCCOBIX = 0;
FCCOB = PFLASH_CMD_ERASE_VERITY; // 命令码 + 地址高
FCCOBIX = 1;
FCCOB = frist_add+PFLASH_GLOBAL_ADDRESS;
PPAGE = 0x0d;
FSTAT_CCIF = 1; // clear CCIF bit
while(!FSTAT_CCIF); // check CCIF bit
}
/******************************************************************************
功 能:void PFLASH_Erase(void)
描 述:擦除PFLASH
参 数: 无
返 回:无
******************************************************************************/
void PFLASH_Erase(uint16 frist_add)
{
while(!FSTAT_CCIF); // check CCIF bit /
FSTAT = 0x30; // clear ACCERR and FPVIOL bits /
FCCOBIX = 0;
FCCOB = PFLASH_CMD_ERASE; // 命令码 + 地址高
FCCOBIX = 1;
FCCOB = frist_add + PFLASH_GLOBAL_ADDRESS; //
PPAGE = 0x0d;
//FSTAT = 0xFF;
FSTAT_CCIF = 1; // clear CCIF bit /
while(!FSTAT_CCIF); // check CCIF bit /
}
/******************************************************************************
功 能:void PFLASH_Write(uint16 frist_add,uint16 *pdata)
描 述:写P-FLASH
参 数: 无
返 回:无
******************************************************************************/
void PFLASH_Write(uint16 frist_add,uint16 *pdata)
{
uint16 command_array[6];
uint8 i;
// FSEC = 0x82;
// FPROT = 0xA8; // 不保护
command_array[0] = PFLASH_CMD_WRITE;
command_array[1] = frist_add + PFLASH_GLOBAL_ADDRESS;
command_array[2] = *pdata++;
command_array[3] = *pdata++;
command_array[4] = *pdata++;
command_array[5] = *pdata++;
while(!FSTAT_CCIF); // check CCIF bit
FSTAT = 0xFF; // clear ACCERR and FPVIOL bits
for(i=0;i<6;i++)
{
FCCOBIX = i;
FCCOB = command_array[i];
// PPAGE = 0x0d;
}
//FSTAT = 0xFF;
FSTAT_CCIF = 1; // clear CCIF bit
while(!FSTAT_CCIF); // check CCIF bit
}
或者说我想在PFLASH区开一个数组空间,我该如何对其读和写?擦写和引用的地址如何定,PRM文件该如何定义?请知道的能不吝指教,谢谢了。
答:
RE:请帮忙看看程序,9s12HY PFLASH的全局地址和逻辑地址和物理地址? |
首先PFLASH的只是在页0x3_8000到0x3_FFFF之间,而又是16位总线的方式,操作不同于DFLASH,你对这段代码之间的地址操作可以了。不用考虑也地址。如果超过这个区域,操作就要安装DFLASH的步骤了。
|
问:
谢谢斑竹。是standard setting 某个设置什么时候改动过了,改过来就可以写了。不过只能单步工作,连续工作时就跳出去了,堆栈不对了。
|
是不是执行 FSTAT_CCIF = 1;后的while(!FSTAT_CCIF);这条语句有什么问题呢?
void PFLASH_Erase(uint16 frist_add)
{
while(!FSTAT_CCIF) ;
FSTAT = 0x30;
FCCOBIX = 0;
FCCOB = PF_CMD_ERASE;
FCCOBIX = 1;
FCCOB = frist_add + PF_GLOBAL_ADDRESS;
FSTAT_CCIF = 1;
while(!FSTAT_CCIF) MDelay(5);
}
| |