你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

跪求STM32F207 FSMC接口的nandflash例子【悬赏问答】

[复制链接]
dfishing 提问时间:2012-8-27 16:42 /
官方好像没有nandflash的实例  跪求好心人发个可用的STM32F2的nandflash例子
收藏 1 评论8 发布时间:2012-8-27 16:42

举报

8个回答
zykzyk-93033 回答时间:2012-8-27 21:18:11

RE:跪求STM32F207 FSMC接口的nandflash例子

官网应该有下载的啊。暂时还没有搞过。
dfishing 回答时间:2012-8-28 09:42:26

回复:跪求STM32F207 FSMC接口的nandflash例子

官方的只有onenand,sram,SRAM_DataMemory这3个例子啊。。。。。。。。?
未命名.jpg
航天航海 回答时间:2012-8-30 14:53:35

RE:跪求STM32F207 FSMC接口的nandflash例子【悬赏问答】

http://blog.csdn.net/licaihuameng/article/details/7758053
这个看看有没有帮助。
dfishing 回答时间:2012-8-30 16:23:08

回复:跪求STM32F207 FSMC接口的nandflash例子【悬赏问答】

我改了些103的关于nandflash例子的驱动程序,做了FSMC接口的配置,但是在运行到读取nandflash() ID的接口void NAND_ReadID(NAND_IDTypeDef* NAND_ID)里的*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;时程序就死了 仿真器提示T-bit of XPSR is 0 but should be 1,这种情况算是我配置没做好还是硬件问题。如果不加*(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00就不会死???

 
 
/**
  ******************************************************************************
  * @file    stm3210e_eval_fsmc_nand.c
  * @author  MCD Application Team
  * @version V4.2.0
  * @date    04/16/2010
  * @brief   This file provides a set of functions needed to drive the
  *          NAND512W3A2 memory mounted on STM3210E-EVAL board.
  ******************************************************************************
  * @copy
  *
  * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
  * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
  * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
  * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
  * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
  * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
  *
  * © COPYRIGHT 2010 STMicroelectronics


  */
/* Includes ------------------------------------------------------------------*/
#include "fsmc_nand.h"
/** @addtogroup Utilities
  * @{
  */
 
/** @addtogroup STM32_EVAL
  * @{
  */
/** @addtogroup STM3210E_EVAL
  * @{
  */
 
/** @addtogroup STM3210E_EVAL_FSMC_NAND
  * @brief      This file provides a set of functions needed to drive the
  *             NAND512W3A2 memory mounted on STM3210E-EVAL board.
  * @{
  */
/** @defgroup STM3210E_EVAL_FSMC_NAND_Private_Types
  * @{
  */
/**
  * @}
  */

/** @defgroup STM3210E_EVAL_FSMC_NAND_Private_Defines
  * @{
  */
/**
  * @brief  FSMC Bank 2
  */
#define FSMC_Bank_NAND     FSMC_Bank3_NAND
#define Bank_NAND_ADDR     Bank3_NAND_ADDR
#define Bank3_NAND_ADDR    ((uint32_t)0x80000000)    
/**
  * @}
  */
/** @defgroup STM3210E_EVAL_FSMC_NAND_Private_Macros
  * @{
  */
#define ROW_ADDRESS (Address.Page + (Address.Block + (Address.Zone * NAND_ZONE_SIZE)) * NAND_BLOCK_SIZE) 
/**
  * @}
  */
 
/** @defgroup STM3210E_EVAL_FSMC_NAND_Private_Variables
  * @{
  */
/**
  * @}
  */

/** @defgroup STM3210E_EVAL_FSMC_NAND_Private_Function_Prototypes
  * @{
  */
/**
  * @}
  */

/** @defgroup STM3210E_EVAL_FSMC_NAND_Private_Functions
  * @{
  */
/**
  * @brief  Configures the FSMC and GPIOs to interface with the NAND memory.
  *         This function must be called before any write/read operation on the
  *         NAND.
  * @param  None
  * @retval None
  */
void NAND_Init(void)
{
  GPIO_InitTypeDef GPIO_InitStructure;
  FSMC_NAND_PCCARDTimingInitTypeDef  p;
  FSMC_NANDInitTypeDef FSMC_NANDInitStructure;
 
  /*FSMC总线使用的GPIO组时钟使能*/
//  RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |
//                         RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);
 
  RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOD | RCC_AHB1Periph_GPIOG | RCC_AHB1Periph_GPIOE, ENABLE);//BM板子上与nandflash有关的引脚
  RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FSMC, ENABLE);
  /* GPIOD configuration */
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource0, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource1, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource3, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_FSMC);
 
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource7, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource8, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource9, GPIO_AF_FSMC);
  GPIO_PinAFConfig(GPIOE, GPIO_PinSource10, GPIO_AF_FSMC);
 
  GPIO_PinAFConfig(GPIOG, GPIO_PinSource9, GPIO_AF_FSMC);           
 /*FSMC CLE, ALE, D0->D3, NOE, NWE 初始化,推挽复用输出*/
  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_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  /*FSMC数据线FSMC_D[4:7]初始化,推挽复用输出*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;
  GPIO_Init(GPIOE, &GPIO_InitStructure);
  /*FSMC NCE3初始化,推挽复用输出*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_Init(GPIOG, &GPIO_InitStructure);
  /*FSMC NWAIT初始化,输入上拉*/
//  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;
//  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_100MHz;
//  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
//  GPIO_Init(GPIOD, &GPIO_InitStructure);
  /*FSMC INT初始化,输入上拉*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;
  GPIO_InitStructure.GPIO_OType = GPIO_OType_OD;
  GPIO_InitStructure.GPIO_PuPd  = GPIO_PuPd_UP;
  GPIO_Init(GPIOD, &GPIO_InitStructure);
  /*--------------FSMC 总线 存储器参数配置------------------------------*/
  p.FSMC_SetupTime = 0x1;         //建立时间
  p.FSMC_WaitSetupTime = 0x3;     //等待时间
  p.FSMC_HoldSetupTime = 0x2;     //保持时间
  p.FSMC_HiZSetupTime = 0x1;      //高阻建立时间
  FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank3_NAND; //使用FSMC BANK3
  FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable; //使能FSMC的等待功能
  FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; //NAND Flash的数据宽度为8位
  FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable;                  //使能ECC特性
  FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_2048Bytes; //ECC页大小2048
  FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;            
  FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;
  FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;
  FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;
  FSMC_NANDInit(&FSMC_NANDInitStructure);
  /*!使能FSMC BANK3 */
  FSMC_NANDCmd(FSMC_Bank3_NAND, ENABLE);
}
/**
  * @brief  Reads NAND memory's ID.
  * @param  NAND_ID: pointer to a NAND_IDTypeDef structure which will hold
  *         the Manufacturer and Device ID. 
  * @retval None
  */
void NAND_ReadID(NAND_IDTypeDef* NAND_ID)
{
  uint32_t data = 0;
  /*!< Send Command to the command area */
  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = 0x90;
  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
//   *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x90;
//   *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = 0x00; 

   /*!< Sequence to read ID from NAND flash */
   data = *(__IO uint32_t *)(FSMC_Bank3_NAND | DATA_AREA);
   NAND_ID->Maker_ID   = ADDR_1st_CYCLE (data);
   NAND_ID->Device_ID  = ADDR_2nd_CYCLE (data);
   NAND_ID->Third_ID   = ADDR_3rd_CYCLE (data);
   NAND_ID->Fourth_ID  = ADDR_4th_CYCLE (data);
}
/**
  * @brief  This routine is for writing one or several 512 Bytes Page size.
  * @param  pBuffer: pointer on the Buffer containing data to be written
  * @param  Address: First page address
  * @param  NumPageToWrite: Number of page to write 
  * @retval New status of the NAND operation. This parameter can be:
  *              - NAND_TIMEOUT_ERROR: when the previous operation generate
  *                a Timeout error
  *              - NAND_READY: when memory is ready for the next operation
  *                And the new status of the increment address operation. It can be:
  *              - NAND_VALID_ADDRESS: When the new address is valid address
  *              - NAND_INVALID_ADDRESS: When the new address is invalid address 
  */
uint32_t NAND_WriteSmallPage(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 */
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
    /*!< Calculate the size */
    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);
    /*!< Write data */
    for(; index < size; index++)
    {
      *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
    }
   
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
    /*!< Check status for successful operation */
    status = NAND_GetStatus();
   
    if(status == NAND_READY)
    {
      numpagewritten++;
      NumPageToWrite--;
      /*!< Calculate Next small page Address */
      addressstatus = NAND_AddressIncrement(&Address);
    }
  }
 
  return (status | addressstatus);
}
/**
  * @brief  This routine is for sequential read from one or several 512 Bytes Page size.
  * @param  pBuffer: pointer on the Buffer to fill
  * @param  Address: First page address
  * @param  NumPageToRead: Number of page to read 
  * @retval New status of the NAND operation. This parameter can be:
  *              - NAND_TIMEOUT_ERROR: when the previous operation generate
  *                a Timeout error
  *              - NAND_READY: when memory is ready for the next operation
  *                And the new status of the increment address operation. It can be:
  *              - NAND_VALID_ADDRESS: When the new address is valid address
  *              - NAND_INVALID_ADDRESS: When the new address is invalid address
  */
uint32_t 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 */
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;
  
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
   
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;
    /*!< Calculate the size */
    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
   
    /*!< Get Data into Buffer */   
    for(; index < size; index++)
    {
      pBuffer[index]= *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
    }
    numpageread++;
   
    NumPageToRead--;
    /*!< Calculate page address */
    addressstatus = NAND_AddressIncrement(&Address);
  }
  status = NAND_GetStatus();
 
  return (status | addressstatus);
}
/**
  * @brief  This routine write the spare area information for the specified
  *         pages addresses. 
  * @param  pBuffer: pointer on the Buffer containing data to be written
  * @param  Address: First page address
  * @param  NumSpareAreaTowrite: Number of Spare Area to write
  * @retval New status of the NAND operation. This parameter can be:
  *              - NAND_TIMEOUT_ERROR: when the previous operation generate
  *                a Timeout error
  *              - NAND_READY: when memory is ready for the next operation
  *                And the new status of the increment address operation. It can be:
  *              - NAND_VALID_ADDRESS: When the new address is valid address
  *              - NAND_INVALID_ADDRESS: When the new address is invalid address
  */
uint32_t NAND_WriteSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaTowrite)
{
  uint32_t index = 0x00, numsparesreawritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
  uint32_t status = NAND_READY, size = 0x00;
  while((NumSpareAreaTowrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))
  {
    /*!< Page write Spare area command and address */
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
    /*!< Calculate the size */
    size = NAND_SPARE_AREA_SIZE + (NAND_SPARE_AREA_SIZE * numsparesreawritten);
    /*!< Write the data */
    for(; index < size; index++)
    {
      *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
    }
   
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
    /*!< Check status for successful operation */
    status = NAND_GetStatus();
    if(status == NAND_READY)
    {
      numsparesreawritten++;
      NumSpareAreaTowrite--;
   
      /*!< Calculate Next page Address */
      addressstatus = NAND_AddressIncrement(&Address);
    }
  }
 
  return (status | addressstatus);
}
/**
  * @brief  This routine read the spare area information from the specified
  *         pages addresses. 
  * @param  pBuffer: pointer on the Buffer to fill
  * @param  Address: First page address
  * @param  NumSpareAreaToRead: Number of Spare Area to read
  * @retval New status of the NAND operation. This parameter can be:
  *              - NAND_TIMEOUT_ERROR: when the previous operation generate
  *                a Timeout error
  *              - NAND_READY: when memory is ready for the next operation
  *                And the new status of the increment address operation. It can be:
  *              - NAND_VALID_ADDRESS: When the new address is valid address
  *              - NAND_INVALID_ADDRESS: When the new address is invalid address
  */
uint32_t NAND_ReadSpareArea(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumSpareAreaToRead)
{
  uint32_t numsparearearead = 0x00, index = 0x00, addressstatus = NAND_VALID_ADDRESS;
  uint32_t status = NAND_READY, size = 0x00;
  while((NumSpareAreaToRead != 0x0) && (addressstatus == NAND_VALID_ADDRESS))
  {    
    /*!< Page Read command and page address */
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_C;
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_TRUE1;
    /*!< Data Read */
    size = NAND_SPARE_AREA_SIZE +  (NAND_SPARE_AREA_SIZE * numsparearearead);
    /*!< Get Data into Buffer */
    for ( ;index < size; index++)
    {
      pBuffer[index] = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
    }
   
    numsparearearead++;
   
    NumSpareAreaToRead--;
    /*!< Calculate page address */
    addressstatus = NAND_AddressIncrement(&Address);
  }
  status = NAND_GetStatus();
  return (status | addressstatus);
}
/**
  * @brief  This routine erase complete block from NAND FLASH
  * @param  Address: Any address into block to be erased
  * @retval New status of the NAND operation. This parameter can be:
  *              - NAND_TIMEOUT_ERROR: when the previous operation generate
  *                a Timeout error
  *              - NAND_READY: when memory is ready for the next operation
  */
uint32_t NAND_EraseBlock(NAND_ADDRESS Address)
{
  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;
  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);
  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);
  *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);
  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1;
  return (NAND_GetStatus());
}
/**
  * @brief  This routine reset the NAND FLASH.
  * @param  None
  * @retval NAND_READY
  */
uint32_t NAND_Reset(void)
{
  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_RESET;
  return (NAND_READY);
}
/**
  * @brief  Get the NAND operation status.
  * @param  None
  * @retval New status of the NAND operation. This parameter can be:
  *              - NAND_TIMEOUT_ERROR: when the previous operation generate
  *                a Timeout error
  *              - NAND_READY: when memory is ready for the next operation
  */
uint32_t NAND_GetStatus(void)
{
  uint32_t timeout = 0x1000000, status = NAND_READY;
  status = NAND_ReadStatus();
  /*!< Wait for a NAND operation to complete or a TIMEOUT to occur */
  while ((status != NAND_READY) &&( timeout != 0x00))
  {
     status = NAND_ReadStatus();
     timeout --;
  }
  if(timeout == 0x00)
  {
    status =  NAND_TIMEOUT_ERROR;
  }
  /*!< Return the operation status */
  return (status);
}
 
/**
  * @brief  Reads the NAND memory status using the Read status command.
  * @param  None
  * @retval The status of the NAND memory. This parameter can be:
  *              - NAND_BUSY: when memory is busy
  *              - NAND_READY: when memory is ready for the next operation
  *              - NAND_ERROR: when the previous operation gererates error
  */
uint32_t NAND_ReadStatus(void)
{
  uint32_t data = 0x00, status = NAND_BUSY;
  /*!< Read status operation ------------------------------------ */
  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;
  data = *(__IO uint8_t *)(Bank_NAND_ADDR);
  if((data & NAND_ERROR) == NAND_ERROR)
  {
    status = NAND_ERROR;
  }
  else if((data & NAND_READY) == NAND_READY)
  {
    status = NAND_READY;
  }
  else
  {
    status = NAND_BUSY;
  }
 
  return (status);
}
/**
  * @brief  Increment the NAND memory address.
  * @param  Address: address to be incremented.
  * @retval The new status of the increment address operation. It can be:
  *              - NAND_VALID_ADDRESS: When the new address is valid address
  *              - NAND_INVALID_ADDRESS: When the new address is invalid address  
  */
uint32_t NAND_AddressIncrement(NAND_ADDRESS* Address)
{
  uint32_t status = NAND_VALID_ADDRESS;
 
  Address-&gtage++;
  if(Address-&gtage == NAND_BLOCK_SIZE)
  {
    Address-&gtage = 0;
    Address->Block++;
   
    if(Address->Block == NAND_ZONE_SIZE)
    {
      Address->Block = 0;
      Address->Zone++;
      if(Address->Zone == NAND_MAX_ZONE)
      {
        status = NAND_INVALID_ADDRESS;
      }
    }
  }
 
  return (status);
}
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */ 
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
 
cjq_enjoy-15073 回答时间:2012-9-1 10:34:32

RE:跪求STM32F207 FSMC接口的nandflash例子【悬赏问答】

发个你
现在已经实现了通过FSMC对FLASH进行简单的读写

stm32f207 fsmc+nandflash.rar

下载

1.28 MB, 下载次数: 2887

wkuang 回答时间:2012-9-1 23:01:31

RE:跪求STM32F207 FSMC接口的nandflash例子【悬赏问答】

我手里没有207的, 407对应的代码倒是有的, 我看一个哥们已经提供了,就不重复了。 不过可以提示下,f1、F2、F4用的都是fsmc总线,控制nandflash的方式一样的,只是可以总线片选用的不样,需要修改nand flash的读写接口地址
dfishing 回答时间:2012-9-3 17:01:44

回复:跪求STM32F207 FSMC接口的nandflash例子【悬赏问答】

我试了一下。。。。。把
FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable;改成
FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Disable;就可以了,但是我不明白为什么。我在STM32F103板子上调试过这个配置FSMC_NANDInitStructure.FSMC_Waitfeature =  FSMC_Waitfeature_Enable ;是可以的啊,并且在STM32F103上片选是被配置成复用的,在程序运行完初始化配置时,芯片的片选还是高电平(低电平有效),在运行下一条读取ID号时自动拉低。而现在的STM32F207上FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Disable;,片选是被配置成输出,程序运行完初始化配置时,芯片的片选脚就被手动拉低了。这个我很不解,是不是我还没有配置好FSMC接口啊??????   ————哪位大神知道这其中的奥秘啊,真心求教。
叮当叮当 回答时间:2016-12-11 03:17:28
wkuang 发表于 2012-9-1 23:01
我手里没有207的, 407对应的代码倒是有的, 我看一个哥们已经提供了,就不重复了。 不过可以提示下,f1、F ...

最近调试STM32F407通过FSMC外设访问三星NAND FLASH,系统时钟是168MHz,初始化外设GPI0D的PD0、PD1、PD3、PD4、PD6、PD11、PD12、PD14、PD15,还有PE的PE7、PE8、PE9、PE10等时钟及GPIO复用,设置FSMC对应的bank2,访问NAND FLASH ID 时,函数如下:
void FSMC_NAND_ReadID(NAND_IDTypeDef* NAND_ID)
{
    /* Send Command to the command area */
    *(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READID;
        /* Send Address to the address area */
    *(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0x00;

    /* Sequence to read ID from NAND flash */
    NAND_ID->Maker_ID   = *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
    NAND_ID->Device_ID  = *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
    NAND_ID->Third_ID   = *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
    NAND_ID->Fourth_ID  = *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
    NAND_ID->Fifth_ID   = *(vu8 *)(NAND_FLASH_START_ADDR | DATA_AREA);
}

程序能够正常单步执行 *(vu8 *)(NAND_FLASH_START_ADDR | CMD_AREA) = NAND_CMD_READID;
单步执行*(vu8 *)(NAND_FLASH_START_ADDR | ADDR_AREA) = 0x00时,程序就有问题,不能正常执行,像是跑别的地方去了,停止仿真时,程序指向复位中断(NAND FLASH bank2 地址设置也是正确的)。
上述问题,不仅仅是访问NAND FLASH ID出现,执行擦除函数时也是这样,执行第一句函数正常,但是执行第二句就有问题,不知何故。
上述问题的NAND FLASH.c,NAND FLASH.h是在stm32f103例程基础上移植过来的,由于STM32F407例程没有提供FSMC总线的NAND FLASH例程。
请高手指教,如果你有相关例程,请帮助提供下,谢谢。
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版