分享

STM学习笔记

 ada_lib 2014-12-05

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());
}


附件为工程文件。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多