XET256芯片PFlash读写功能问题

2019-07-15 17:17发布

      最近在做将控制器上的XDP512更换成XET256芯片后的代码调试,关于PFlash的擦除、读写功能均按照官方demo编写,且代码段运行时放在RAM段执行,现在遇到的问题是,使用PE调试全速运行到Pflash函数时,程序就会跳转到不正确地址运行,但如果在进入该函数时单步调试,PFlash写入和读写都正确,在读写前增加延时的方法也试了还是不行,我把测试PFLASH功能的代码贴出来,希望各位大神指点以下,不胜感激~~
#define DFLASH_LOWEST_START_PAGE        0x00        //定义data flash的起始页
#define DFLASH_START                    0x00100000  //定义data flash的起始地址
#define DFLASH_PAGE_SIZE                0x0400      //定义data flash的大小为1K.
#define DFLASH_PAGE_WINDOW_START        0x0800      //定义data flash页面窗口的起始地址
unsigned int    Buffer1[4]={0x1111,0x2222,0x3333,0x4444};//数据缓存区,只能一次写入四个数据
unsigned int    data_Address=0x0000;
unsigned char   date_read[8];

#pragma CODE_SEG Flash_Driver_FLASH//在PRM文件中该Flash段关联到RAM区0x2E00开始
void PFlash_Erase(word ADDR16)
{     
  while(FSTAT_CCIF==0);
  if(FSTAT_ACCERR)           //判断并清除标志位;
      FSTAT_ACCERR=1;
  if(FSTAT_FPVIOL)           //判断并清除标志位;
      FSTAT_FPVIOL=1;
  
  FCCOBIX_CCOBIX=0x00;
  FCCOB=0x0A7E;           //写入擦除命令和高位地址
  FCCOBIX_CCOBIX=0x01;   
  FCCOB=ADDR16;           //写入低16位的地址
  FSTAT_CCIF=1;           //启动执行命令
  while(FSTAT_CCIF==0);   //等待执行完成
}
void PFlash_Write(UInt16 ADDR16,UInt16 *Buffer)
{   
    while(FSTAT_CCIF==0);
    if(FSTAT_ACCERR)           //判断并清除标志位;
        FSTAT_ACCERR=1;
    if(FSTAT_FPVIOL)           //判断并清除标志位;
        FSTAT_FPVIOL=1;
    FCCOBIX_CCOBIX=0x00;
    FCCOB=0x067E;         //写入命令和高位地址
    FCCOBIX_CCOBIX=0x01;  //地址后16位
    FCCOB=ADDR16;         //写入低16位地址
    FCCOBIX_CCOBIX=0x02;  //写入第一个数据
    FCCOB=*Buffer;
    FCCOBIX_CCOBIX=0x03;  //写入第二个数据
    FCCOB=*(Buffer+1);
    FCCOBIX_CCOBIX=0x04;  //写入第三个数据
    FCCOB=*(Buffer+2);
    FCCOBIX_CCOBIX=0x05;  //写入第四个数据
    FCCOB=*(Buffer+3);         
    FSTAT_CCIF=1;         //写入执行命令
}  
//#pragma CODE_SEG  DEFAULT
/*************************************************************/
/*                     向DFLASH写入数据                      */
/*************************************************************/
void DFlash_Write(UInt16 ADDR16,UInt16 *Buffer)
{
    while(FSTAT_CCIF==0);
    if(FSTAT_ACCERR)           //判断并清除标志位;
        FSTAT_ACCERR=1;
    if(FSTAT_FPVIOL)           //判断并清除标志位;
        FSTAT_FPVIOL=1;
    FCCOBIX_CCOBIX=0x00;
    FCCOB=0x1110;         //写入命令和高位地址
    FCCOBIX_CCOBIX=0x01;  //地址后16位
    FCCOB=ADDR16;         //写入低16位地址
    FCCOBIX_CCOBIX=0x02;  //写入第一个数据
    FCCOB=*Buffer;
    FCCOBIX_CCOBIX=0x03;  //写入第二个数据
    FCCOB=*(Buffer+1);
    FCCOBIX_CCOBIX=0x04;  //写入第三个数据
    FCCOB=*(Buffer+2);
    FCCOBIX_CCOBIX=0x05;  //写入第四个数据
    FCCOB=*(Buffer+3);         
    FSTAT_CCIF=1;         //写入执行命令
    while(FSTAT_CCIF==0); //等待执行完毕
}
/*************************************************************/
/*                    擦除DFLASH的一个分区                   */
/*************************************************************/
void DFlash_Erase(word ADDR16)
{   
  while(FSTAT_CCIF==0);
  if(FSTAT_ACCERR)           //判断并清除标志位;
      FSTAT_ACCERR=1;
  if(FSTAT_FPVIOL)           //判断并清除标志位;
      FSTAT_FPVIOL=1;
  FCCOBIX_CCOBIX=0x00;
  FCCOB=0x1210;           //写入擦除命令和高位地址
  FCCOBIX_CCOBIX=0x01;   
  FCCOB=ADDR16;           //写入低16位的地址
  FSTAT_CCIF=1;           //启动执行命令
  while(FSTAT_CCIF==0);   //等待执行完成
}
/*************************************************************/
/*                     由DFLASH读取数据                      */
/*************************************************************/
word DFlash_Read (word destination)
{
    byte   lastepage;          //用于存储EPAGE的值
    byte   epage;              //用于计算EPAGE的值
    unsigned int data;         //读取出的数据
    lastepage = EPAGE;   //保存EPAGE的值
    epage = (byte)((DFLASH_LOWEST_START_PAGE)+(destination >>10));   //计算EPAGE
    EPAGE=epage;                                                     //给EPAGE赋值

    data = READword((destination & (DFLASH_PAGE_SIZE - 1)) + DFLASH_PAGE_WINDOW_START);  //读取页面窗口中的数据
    EPAGE= lastepage;       //恢复EPAGE的值
    return(data);
}
#pragma CODE_SEG HCS12_Main_FLASH
//#pragma CODE_SEG  PwrOff_RAM
void main(void)
{       UInt8 i;
        unsigned char *far Addr ;   
        Addr = (unsigned char *far)0x7e0000;
        DisableInterrupts            ;//关闭中断  
        ECT_TSCR2_TOI = 0 ;
        MainInit()                   ;//初始化函数,包括硬件初始化及变量初始化  /  /放入Main_Init_FLASH
        FlashDriver2RAM()            ;//FLash的CCP相关驱动映射到RAM区  
        PowerOn_ValueInit()          ;//控制板上电初始化  标定量及掉电保护区变量赋值
        EnableInterrupts             ;//开启中断     
        OSEK_Startcall()            ;  
         DFlash_Erase(data_Address);  
          DFlash_Write(data_Address,Buffer1);
          PFlash_Erase(data_Address);     //确保先擦除后写入
          PFlash_Write(data_Address,Buffer1);
            date_read[0]=*(Addr);
            date_read[1]=*(Addr+1);
            date_read[2]=*(Addr+2);
            date_read[3]=*(Addr+3);
            date_read[4]=*(Addr+4);
            date_read[5]=*(Addr+5);
            date_read[6]=*(Addr+6);
            date_read[7]=*(Addr+7);
            MSCAN4Trans(ID_TCUandVCU,date_read)             ;//     
         
        for(;;)
        {
             // _FEED_COP(); /* feeds the dog */
              if(CCP_ProgramingFlg==0)
              {     
                //  MainProgram()           ;//循环调用主控制策略     
              }
        } /* loop forever */
        /* please make sure that you never leave main */
}
#pragma CODE_SEG  DEFAULT

问题截图_LI.jpg
问题截图1_LI.jpg
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
8条回答
结界菲菲
1楼-- · 2019-07-16 21:51
 精彩回答 2  元偷偷看……
嘻哈二
2楼-- · 2019-07-16 23:24
结界菲菲 发表于 2017-6-5 11:21
中断向量引入 怎么做? 不是很明白,能详细讲解一下吗

不清楚你用的什么中断,但是,开启了中断,得给出一下指向向量,我一般是放在.prm文件中,不过不是很好。对了,最近我也在做bootloader的固件更新,表示一脸懵逼,还想请教一下,具体怎么操作?

一周热门 更多>