原创 STM学习笔记——nandflsh的操作(K9F1G08)

2010-1-27 19:14 6545 10 16 分类: MCU/ 嵌入式

STM32学习笔记 STM32操作K9F1G08



 


 


 


     最近一个多礼拜都在搞这方面的东西,买了一块深圳英贝特的开发板,不过里面的例程是对小页的nandflsh的操作,所以与K9F1G08多少有点不同,网上也有很多版本,比如圈圈的K9F1G08驱动很是详细,但改动比较大,所以整合到我的程序里很费劲,还有一些其他的改进的版本,但经过试验,感觉能实现部分的操作,但不是很完整,比如读写多页的操作,就会出现bug,今天在网上搜到了红牛的开发板的例程,试了一下很是不错,根据他的例子和本人的例子相结合,整理如下:


fsmc_nand.h中应该改动的代码:(注释没有及时更新)


/* Exported constants --------------------------------------------------------*/
/* NAND Area definition  for STM3210E-EVAL Board RevD */
#define CMD_AREA                   (u32)(1<<16)  /* A16 = CLE  high */
#define ADDR_AREA                  (u32)(1<<17)  /* A17 = ALE high */


#define DATA_AREA                  ((u32)0x00000000)


/* FSMC NAND memory command */
#define NAND_CMD_READ_1             ((u8)0x00)
#define NAND_CMD_READ_TRUE          ((u8)0x30)


#define NAND_CMD_RDCOPYBACK         ((u8)0x00)
#define NAND_CMD_RDCOPYBACK_TRUE    ((u8)0x35)


#define NAND_CMD_PAGEPROGRAM        ((u8)0x80)
#define NAND_CMD_PAGEPROGRAM_TRUE   ((u8)0x10)


#define NAND_CMD_COPYBACKPGM        ((u8)0x85)
#define NAND_CMD_COPYBACKPGM_TRUE   ((u8)0x10)
 
#define NAND_CMD_ERASE0             ((u8)0x60)
#define NAND_CMD_ERASE1             ((u8)0xD0) 


#define NAND_CMD_READID             ((u8)0x90) 
#define NAND_CMD_STATUS             ((u8)0x70)
#define NAND_CMD_RESET              ((u8)0xFF)


#define NAND_CMD_CACHEPGM           ((u8)0x80)
#define NAND_CMD_CACHEPGM_TRUE      ((u8)0x15)


#define NAND_CMD_RANDOMIN           ((u8)0x85)
#define NAND_CMD_RANDOMOUT          ((u8)0x05)
#define NAND_CMD_RANDOMOUT_TRUE     ((u8)0xE0)


#define NAND_CMD_CACHERD_START      ((u8)0x00)
#define NAND_CMD_CACHERD_START2     ((u8)0x31)
#define NAND_CMD_CACHERD_EXIT       ((u8)0x34)


/* NAND memory status */
#define NAND_VALID_ADDRESS         ((u32)0x00000100)
#define NAND_INVALID_ADDRESS       ((u32)0x00000200)
#define NAND_TIMEOUT_ERROR         ((u32)0x00000400)
#define NAND_BUSY                  ((u32)0x00000000)
#define NAND_ERROR                 ((u32)0x00000001)
#define NAND_READY                 ((u32)0x00000040)


/* FSMC NAND memory parameters */
#define NAND_PAGE_SIZE             ((u16)0x0800) /* 512 bytes per page w/o Spare Area */
#define NAND_BLOCK_SIZE            ((u16)0x0040) /* 32x512 bytes pages per block */
#define NAND_ZONE_SIZE             ((u16)0x0400) /* 1024 Block per zone */
#define NAND_SPARE_AREA_SIZE       ((u16)0x0040) /* last 16 bytes as spare area */
#define NAND_MAX_ZONE              ((u16)0x0001) /* 4 zones of 1024 block */


fsmc_nand.c 中应该改动的地方:


u32 FSMC_NAND_WriteSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToWrite)
{        //   要写入的数              页地址       要写入多少页
  u32 index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
  u32 status = NAND_READY, size = 0; 


  while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
  {
     /* Page write command and address */
    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_PAGEPROGRAM;


    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00; 
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0X00; 
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);  


/*    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);//ADDR_3rd_CYCLE(ROW_ADDRESS); //更改
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);//ADDR_4th_CYCLE(ROW_ADDRESS); //
 *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);  
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS);     */ 


    /* Calculate the size */


    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);


    /* Write data */
    for(; index < size; index++)
    {
      *(vu8 *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
   printf(" 0x%x\n",pBuffer[index]);
    }
   
    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_PAGEPROGRAM_TRUE;
 
   while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );


    /* Check status for successful operation */
    status = FSMC_NAND_GetStatus();
   
    if(status == NAND_READY)
    {
      numpagewritten++;


      NumPageToWrite--;


      /* Calculate Next small page Address */
      addressstatus = FSMC_NAND_AddressIncrement(&Address);   
    }   
  }
   return (status | addressstatus);
}


u32 FSMC_NAND_ReadSmallPage(u8 *pBuffer, NAND_ADDRESS Address, u32 NumPageToRead)
{        
  u32 index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
  u32 status = NAND_READY, size = 0, i = 0,temp = 0;


 


  while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
  {   
    /* Page Read command and page address */
    /* Page Read command and page address */
    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ_1;
  
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = 0X00;
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS); 
   
/*   
  *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);//ADDR_3rd_CYCLE(ROW_ADDRESS); //更改
   *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);//ADDR_4th_CYCLE(ROW_ADDRESS); //
 *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);  
    *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS);     */ 


    *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_READ_TRUE;    


     while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );


  /* Calculate the size */
  size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
 //  for(i = 0; i <= 10000; i++);
   
    /* Get Data into Buffer */   
    for(; index < size; index++)
    {
      pBuffer[index]= *(vu8 *)(Bank_NAND_ADDR | DATA_AREA);
   printf(" 0x%x\n",pBuffer[index]);
    }


    numpageread++;
   
    NumPageToRead--;


    /* Calculate page address */              
    addressstatus = FSMC_NAND_AddressIncrement(&Address);
  }
  
  status = FSMC_NAND_GetStatus();
 
  return (status | addressstatus);
}


对块的擦出,注意:只对前两个周期进行操作


u32 FSMC_NAND_EraseBlock(NAND_ADDRESS Address)
{
  *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;


  *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS); 
  *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  
  *(vu8 *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1;


      while( GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_6) == 0 );


  return (FSMC_NAND_GetStatus());
}


附件为工程文件。

PARTNER CONTENT

文章评论6条评论)

登录后参与讨论

潜龙思瑞 2015-6-21 07:45

怎么没有坏块管理,你这么搞工程是有缺点的

用户377235 2015-5-12 11:28

发我邮箱,感激不尽1065391689@qq.com

用户1773720 2014-7-15 10:30

楼主,你的程序不是一个完整的工程啊,你在上面修改的地方不是很明确, /* *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);//ADDR_3rd_CYCLE(ROW_ADDRESS); //更改 *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);//ADDR_4th_CYCLE(ROW_ADDRESS); // *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS); *(vu8 *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_4th_CYCLE(ROW_ADDRESS); */ 这里需要修改吗

用户263532 2013-7-3 15:29

点评不错

用户512436 2011-11-10 10:56

点评一下,不错

用户290136 2010-6-22 09:34

不错 谢谢LZ

用户9190 2008-1-23 17:23

想看关于第8项的详细解释

相关推荐阅读
用户89529 2010-09-25 17:03
stm32 malloc:动态分配内存函数
函数原型:void *malloc(unsigned size)头文件:#include<stdlib.h>是否是标准函数:是函数功能:动态分配一块内存空间,size为指定的分配空间的大小...
用户89529 2010-08-09 14:13
SD卡的读写和FatFS文件系统
因为要用,学习了一下SPI操作SD卡,同时移植了一个免费开源的FAT文件系统:FatFS。感觉挺好,在单片机上实现了读写文件的操作,接下来就可以解释我的G代码咯!  我的SD卡底层操作参考了网上几种常...
用户89529 2010-08-09 14:11
转一篇比较详细介绍FatFs文件系统移植的文章
FatFs文件系统的移植    因为需要,又不想自己写,所以就移植了一个文件系统。    说下我的硬件和开发工具:接成 TRUE IDE 模式下的CF卡(也就是相当于一块硬盘了),三星S3C2440的...
用户89529 2010-08-05 11:53
关于STM32的systick定时器的详细说明
我不得不说意法半导体确实有点风骚!甚至有点变态。我对ST文档 STM32F10XXX参考手册的编辑水平真是不敢恭维。手册中好多说明都是含糊不清,甚至将好多对初学者来说很重要的地方都一笔带过,让人着实摸...
用户89529 2010-05-11 19:40
stm32 fsmc数据地址线的关系
      stm32的fsmc接口设置的资料很少,所以现在对各个寄存器的具体应用还不是很明白,最近写了一个程序是把以前8位数据线读写sram的程序,改为16位数据线。有了一个小小的发现,现在把它写出...
用户89529 2010-05-07 11:59
stm32关于BOOT0和BOOT1
BOOT0和BOOT1STM32三种启动模式对应的存储介质均是芯片内置的,它们是:1)用户闪存 = 芯片内置的Flash。2)SRAM = 芯片内置的RAM区,就是内存啦。3)系统存储器 = 芯片内部...
EE直播间
更多
我要评论
6
10
关闭 站长推荐上一条 /3 下一条