STM32 FSMC NAND控制器 驱动NAND FLASH 注意事项

1、初始化

void FSMC_NAND_Init(void)
{

  GPIO_InitTypeDef GPIO_InitStructure;
  FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
  FSMC_NAND_PCCARDTimingInitTypeDef  p;
 
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_FSMC, ENABLE);   
 
/*-- GPIO Configuration ------------------------------------------------------*/
/* CLE, ALE, D0->D3, NOE, NWE and NCE2  NAND pin configuration  */
  GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 | 
                                 GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |
                                 GPIO_Pin_7;                                 
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

/* D4->D7 NAND pin configuration  */ 
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;

  GPIO_Init(GPIOE, &GPIO_InitStructure);


/* NWAIT NAND pin configuration 读/忙输出引脚定义可能不一样*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;                                
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;

  GPIO_Init(GPIOD, &GPIO_InitStructure);

  /*-- FSMC Configuration ------------------------------------------------------*/
  p.FSMC_SetupTime = 0x1;
  p.FSMC_WaitSetupTime = 0x3;
  p.FSMC_HoldSetupTime = 0x2;
  p.FSMC_HiZSetupTime = 0x1;

  FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND;
  FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Disable;
  FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b;
  FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Disable;    //FSMC_ECC_Enable;   //
  FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_512Bytes;
  FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;      //×?éù10ns,????oóμ??μê?(1+1+4)*HCLK=82.8ns
  FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;       //×?éù10ns,????oóμ??μê?(1+1+4)*HCLK=82.8ns
  FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
  FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;

  FSMC_NANDInit(&FSMC_NANDInitStructure);


  FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);
   

    FSMC_NAND_Reset();

}


2、HY27US08561A 页、块 大小定义


/* FSMC NAND memory parameters */
//HY27US08561A  512bit*32page*1024block*2zone
#define NAND_PAGE_SIZE             ((u16)0x0200) /* 512 bytes per page w/o Spare Area */
#define NAND_BLOCK_SIZE            ((u16)0x0020) /* 32x512 bytes pages per block */
#define NAND_ZONE_SIZE             ((u16)0x0400) /* 1024 Block per zone */
#define NAND_SPARE_AREA_SIZE       ((u16)0x0010) /* last 16 bytes as spare area */

#define NAND_MAX_ZONE              ((u16)0x0002) /* 2 zones of 1024 block */


3、寄存器地址定义

#define NAND_FLASH_START_ADDR    0X70000000//地址区0x020000~0x03FFFF软件只需对命令区的任意一个地址写入命令即可

#define CMD_AREA                   1<<16        //发送命令

#define ADDR_AREA                  1<<17        //发送地址


4、测试

#include "fsmc_nand.h"

static u8  RxBuf1[NAND_PAGE_SIZE]={11};//接收数据数组1
static u8  TxBuf1[NAND_PAGE_SIZE]={0};;//fs数据数组2

 NAND_ADDRESS WriteReadAddr;

void FSMC_readdata(NAND_ADDRESS Address)
{
 FSMC_NAND_ReadSmallPage(RxBuf1, Address,1);
}

void textr(){
  WriteReadAddr.Zone = 0x00;
  WriteReadAddr.Block = 0x00;
  WriteReadAddr.Page = 0x00;
 
  FSMC_readdata(WriteReadAddr);   
    SP=RxBuf1[0];//测试一个字节
}

void textw(){
  WriteReadAddr.Zone = 0x00;
  WriteReadAddr.Block = 0x00;
  WriteReadAddr.Page = 0x00;
    TxBuf1[0]=p[PB1];//改变测试数据
    FSMC_NAND_EraseBlock(WriteReadAddr);
FSMC_NAND_WriteSmallPage(TxBuf1, WriteReadAddr, 1);
   
}


5、读写代码

/*读页*/

uint32_t FSMC_NAND_ReadSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToRead)
{
  uint32_t index = 0x00, numpageread = 0x00, addressstatus = NAND_VALID_ADDRESS;
  uint32_t status = NAND_READY, size = 0x00;

  while((NumPageToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
  {      
    /* Page Read command and page address */
    *(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READ_1; //0x00读命令
  
    *(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0x00;//前两字节为column地址
    *(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0X00;
    *(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);//页地址 
    *(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS); 
   
    *(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READ_TRUE;//0x30
  
    /* 读忙脚 */
    while( GPIO_ReadInputDataBit(GPIOD, GPIO_Pin_6) == 0 );
   
    /* Calculate the size */
    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
   
    /* Get Data into Buffer */   
    for(; index < size; index++)
    {
      pBuffer[index]= *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
    }

    numpageread++;
   
    NumPageToRead--;

    /* Calculate page address */                        
    addressstatus = FSMC_NAND_AddressIncrement(&Address);
  }

  status = FSMC_NAND_GetStatus();
 
  return (status | addressstatus);

}



/*写页*/

uint32_t FSMC_NAND_WriteSmallPage(const uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite)

{
  uint32_t index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
  uint32_t status = NAND_READY, size = 0x00;

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

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

    /* Calculate the size */
    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);

    /* Write data */
    for(; index < size; index++)
    {
      *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA) = pBuffer[index];
    }
   
    *(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_PAGEPROGRAM_TRUE;

    /* 读忙脚 */
    while( GPIO_ReadInputDataBit(GPIOD, 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);
}


  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值