飞思卡尔MC9S12XS128的DFLASH问题求助?(已解决)

2020-02-21 20:56发布

本帖最后由 NC_Zyang 于 2014-8-20 15:02 编辑

这个是在网上找的例程,有些不懂的地方望大侠们帮帮忙:
  1. #define READword(address)     ((unsigned int)(*(volatile unsigned int *__near)(address)))

  2. #define DFLASH_LOWEST_START_PAGE        0x00        //定义data flash的起始页
  3. #define DFLASH_START                    0x00100000  //定义data flash的起始地址
  4. #define DFLASH_PAGE_SIZE                0x0400      //定义data flash的大小为1K.
  5. #define DFLASH_PAGE_WINDOW_START        0x0800      //定义data flash页面窗口的起始地址
  6. #define LEDCPU PORTK_PK4
  7. #define LEDCPU_dir DDRK_DDRK4

  8. unsigned int    Buffer[]={0x1111,0x2222,0x3333,0x4444};//数据缓存区,只能一次写入四个数据
  9. unsigned int    data_Address=0x0000;
  10. unsigned int    date_read[4];
复制代码
  1. void DFlash_Init(void)
  2. {
  3.    while(FSTAT_CCIF==0);            //等待正在处理的FLASH操作完成
  4.    FCLKDIV=0x0F;                    //外部晶振为16M.FLASH时钟不超过1M,具体参照手册
  5.    FCNFG=0x00;                      //禁止中断
  6.    while(FCLKDIV_FDIVLD==0);        //等待时钟设置成功
  7. }
复制代码
  1. void DFlash_Write(word ADDR16)
  2. {
  3.     while(FSTAT_CCIF==0);
  4.     if(FSTAT_ACCERR)           //判断并清除标志位;
  5.         FSTAT_ACCERR=1;
  6.     if(FSTAT_FPVIOL)           //判断并清除标志位;
  7.         FSTAT_FPVIOL=1;
  8.     FCCOBIX_CCOBIX=0x00;
  9.     FCCOB=0x1110;         //写入命令和高位地址
  10.     FCCOBIX_CCOBIX=0x01;  //地址后16位
  11.     FCCOB=ADDR16;         //写入低16位地址
  12.     FCCOBIX_CCOBIX=0x02;  //写入第一个数据
  13.     FCCOB=Buffer[0];
  14.     FCCOBIX_CCOBIX=0x03;  //写入第二个数据
  15.     FCCOB=Buffer[1];
  16.     FCCOBIX_CCOBIX=0x04;  //写入第三个数据
  17.     FCCOB=Buffer[2];
  18.     FCCOBIX_CCOBIX=0x05;  //写入第四个数据
  19.     FCCOB=Buffer[3];  
  20.       
  21.     FSTAT_CCIF=1;         //写入执行命令
  22.     while(FSTAT_CCIF==0); //等待执行完毕
  23. }
复制代码
  1. word DFlash_Read (word destination)
  2. {
  3.     byte   lastepage;          //用于存储EPAGE的值
  4.     byte   epage;              //用于计算EPAGE的值
  5.     unsigned int data;         //读取出的数据

  6.     lastepage = EPAGE;   //保存EPAGE的值

  7.     epage = (byte)((DFLASH_LOWEST_START_PAGE)+(destination >>10));   //计算EPAGE
  8.     EPAGE=epage;                                                     //给EPAGE赋值

  9.     data = READword((destination & (DFLASH_PAGE_SIZE - 1)) + DFLASH_PAGE_WINDOW_START);  //读取页面窗口中的数据

  10.     EPAGE= lastepage;       //恢复EPAGE的值

  11.     return(data);
  12. }
复制代码
  1. void DFlash_Erase(word ADDR16)
  2. {   
  3.   while(FSTAT_CCIF==0);
  4.   if(FSTAT_ACCERR)           //判断并清除标志位;
  5.       FSTAT_ACCERR=1;
  6.   if(FSTAT_FPVIOL)           //判断并清除标志位;
  7.       FSTAT_FPVIOL=1;
  8.   
  9.   FCCOBIX_CCOBIX=0x00;
  10.   FCCOB=0x1210;           //写入擦除命令和高位地址
  11.   FCCOBIX_CCOBIX=0x01;   
  12.   FCCOB=ADDR16;           //写入低16位的地址
  13.   FSTAT_CCIF=1;           //启动执行命令
  14.   while(FSTAT_CCIF==0);   //等待执行完成
  15. }
复制代码
  1. void main(void)
  2. {
  3.     DisableInterrupts;
  4.     LEDCPU_dir=1;
  5.     LEDCPU=1;
  6.     EnableInterrupts;
  7.    
  8.     DFlash_Init();                  //初始化Flash
  9.     DFlash_Erase(data_Address);     //确保先擦除后写入
  10.     DFlash_Write(data_Address);
  11.     date_read[0]=DFlash_Read(data_Address);
  12.     date_read[1]=DFlash_Read(data_Address+2);
  13.     date_read[2]=DFlash_Read(data_Address+4);
  14.     date_read[3]=DFlash_Read(data_Address+6);

  15.     if(date_read[0]==0x1111&&date_read[1]==0x2222&&date_read[2]==0x3333&&date_read[3]==0x4444)  //判断数据是否正确
  16.         LEDCPU=0;           //点亮指示灯
  17.   for(;;)
  18.   {
  19.   }
  20. }
复制代码

这个DFlash_Write是写DFLASH的函数,从datasheet的599页知道这个全局地址是0x100000+ADDR16,这里的ADDR16写的是0x0000;那么这个起始写的地址就是0X100000吧,datasheet已经截图了。
从主函数可以知道第一个数据0x1111在地址0x100000里,0x2222在地址0x100002里,0x3333在地址0x100004里,0x4444在地址0x100006里,通过仿真也验证了全局地址里面存的数据就是对应的数据;
但是在 DFlash_Read读DLFASH函数中,(destination & (DFLASH_PAGE_SIZE - 1)) + DFLASH_PAGE_WINDOW_START这个却是0x8000,起始读地址就是从0x108000开始的?
#define READword(address)     ((unsigned int)(*(volatile unsigned int *__near)(address)))这个用near指针,说明是在64k内,那么它所取地址范围就是0~0XFFFF内咯?怎么会知道0x100000里呢?
此外,在datasheet第137页里面可知道1KB的FLASH地址是从0x100800~0x100BFF的,但是上面的起始地址却是0x100000开始的?
上面的代码都是仿真过了的,而且正确。
请了解这个的帮我解答解答上面的疑问,谢谢。
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
该问题目前已经被作者或者管理员关闭, 无法添加新回复
12条回答
FSL_TICS_ZJJ
1楼-- · 2020-02-21 23:08
 精彩回答 2  元偷偷看……
NC_Zyang
2楼-- · 2020-02-22 04:24
FSL_TICS_ZJJ 发表于 2014-8-20 11:27
楼主你确定你的0x1111,0x2222,0x3333,0x4444都写进了DFLASH的0x100000这个地址开始?
你有没有仿真看看这个 ...

全部都是通过仿真器看了地址里的数据的,都是对的。
NC_Zyang
3楼-- · 2020-02-22 07:02
终于解决了,不好好理解第一幅图的话还真不知道其原理,在第一幅图中,DFLASH在Global Memory Map的地址是0x100000~0x13FFFF,对应到Local Memory Map是0x0800~0x0c00,DFLASH一共256KB,在Local Memory Map却只有1KB,所以就会有EPAGE来配置,EPAGE来配置页地址,每页为1KB,这样就可以寻址到Global Memory Map的256KB了。
操作DFLASH写的是写Global Memory Address,所以是从0x100000开始的,读DFLASH是从Local Memory Address读的,所以开始地址是0x0800,如果起始写地址是0X100400,读数据的地址也是0x0800,只不过EPAGE变成1了,而前一个EPAGE为0.
FSL_TICS_ZJJ
4楼-- · 2020-02-22 12:38
NC_Zyang 发表于 2014-8-20 13:45
全部都是通过仿真器看了地址里的数据的,都是对的。

那你现在的问题就是起始地址从0x100000开始,而实际操作却是从0x000000开始对吧。
这样吧,我不是16位的工程师,所以不是太熟悉这款芯片。
你到我们官网提交一个技术服务请求,会有相关的16位工程师帮你解答。
建立服务请求的链接:http://www.amobbs.com/thread-5570020-1-1.html
点击提交服务请求(service request)按钮,然后按照流程走。
NC_Zyang
5楼-- · 2020-02-22 13:24
FSL_TICS_ZJJ 发表于 2014-8-20 13:59
那你现在的问题就是起始地址从0x100000开始,而实际操作却是从0x000000开始对吧。
这样吧,我不是16位的 ...

谢谢哈,现在已经解决了,主要的问题是DFLASH写操作的时候地址是GLOCAL ADDRESS开始,DFLASH读操作是LOCAL ADDRESS开始的,以前一位读写地址都是从GLOCAL开始的,主要是英文水平不过关,看英文资料没有理解清楚。
FSL_TICS_ZJJ
6楼-- · 2020-02-22 14:15
 精彩回答 2  元偷偷看……

一周热门 更多>