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

查看: 11828|回复: 8

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

[复制链接]

3

主题

9

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2012-8-27 16:42:19 | 显示全部楼层 |阅读模式
官方好像没有nandflash的实例  跪求好心人发个可用的STM32F2的nandflash例子
<
回复

使用道具 举报

24

主题

591

回帖

0

蝴蝶豆

中级会员

最后登录
2020-12-2
发表于 2012-8-27 21:18:11 | 显示全部楼层

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

官网应该有下载的啊。暂时还没有搞过。
回复 支持 反对

使用道具 举报

3

主题

9

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 2012-8-28 09:42:26 | 显示全部楼层

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

官方的只有onenand,sram,SRAM_DataMemory这3个例子啊。。。。。。。。?
未命名.jpg
回复 支持 反对

使用道具 举报

1

主题

39

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
发表于 2012-8-30 14:53:35 | 显示全部楼层

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

http://blog.csdn.net/licaihuameng/article/details/7758053
这个看看有没有帮助。
回复 支持 反对

使用道具 举报

3

主题

9

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 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 &quot;fsmc_nand.h&quot;
/** @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-&gt;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, &amp;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, &amp;GPIO_InitStructure);
  /*FSMC NCE3初始化,推挽复用输出*/
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
  GPIO_Init(GPIOG, &amp;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, &amp;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, &amp;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 = &amp;p;
  FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &amp;p;
  FSMC_NANDInit(&amp;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;
  /*!&lt; 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; 

   /*!&lt; Sequence to read ID from NAND flash */
   data = *(__IO uint32_t *)(FSMC_Bank3_NAND | DATA_AREA);
   NAND_ID-&gt;Maker_ID   = ADDR_1st_CYCLE (data);
   NAND_ID-&gt;Device_ID  = ADDR_2nd_CYCLE (data);
   NAND_ID-&gt;Third_ID   = ADDR_3rd_CYCLE (data);
   NAND_ID-&gt;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) &amp;&amp; (addressstatus == NAND_VALID_ADDRESS) &amp;&amp; (status == NAND_READY))
  {
    /*!&lt; 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);
    /*!&lt; Calculate the size */
    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);
    /*!&lt; Write data */
    for(; index &lt; size; index++)
    {
      *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
    }
   
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
    /*!&lt; Check status for successful operation */
    status = NAND_GetStatus();
   
    if(status == NAND_READY)
    {
      numpagewritten++;
      NumPageToWrite--;
      /*!&lt; Calculate Next small page Address */
      addressstatus = NAND_AddressIncrement(&amp;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) &amp;&amp; (addressstatus == NAND_VALID_ADDRESS))
  {
    /*!&lt; 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;
    /*!&lt; Calculate the size */
    size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpageread);
   
    /*!&lt; Get Data into Buffer */   
    for(; index &lt; size; index++)
    {
      pBuffer[index]= *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
    }
    numpageread++;
   
    NumPageToRead--;
    /*!&lt; Calculate page address */
    addressstatus = NAND_AddressIncrement(&amp;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) &amp;&amp; (addressstatus == NAND_VALID_ADDRESS) &amp;&amp; (status == NAND_READY))
  {
    /*!&lt; 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);
    /*!&lt; Calculate the size */
    size = NAND_SPARE_AREA_SIZE + (NAND_SPARE_AREA_SIZE * numsparesreawritten);
    /*!&lt; Write the data */
    for(; index &lt; size; index++)
    {
      *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];
    }
   
    *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;
    /*!&lt; Check status for successful operation */
    status = NAND_GetStatus();
    if(status == NAND_READY)
    {
      numsparesreawritten++;
      NumSpareAreaTowrite--;
   
      /*!&lt; Calculate Next page Address */
      addressstatus = NAND_AddressIncrement(&amp;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) &amp;&amp; (addressstatus == NAND_VALID_ADDRESS))
  {    
    /*!&lt; 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;
    /*!&lt; Data Read */
    size = NAND_SPARE_AREA_SIZE +  (NAND_SPARE_AREA_SIZE * numsparearearead);
    /*!&lt; Get Data into Buffer */
    for ( ;index &lt; size; index++)
    {
      pBuffer[index] = *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA);
    }
   
    numsparearearead++;
   
    NumSpareAreaToRead--;
    /*!&lt; Calculate page address */
    addressstatus = NAND_AddressIncrement(&amp;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();
  /*!&lt; Wait for a NAND operation to complete or a TIMEOUT to occur */
  while ((status != NAND_READY) &amp;&amp;( timeout != 0x00))
  {
     status = NAND_ReadStatus();
     timeout --;
  }
  if(timeout == 0x00)
  {
    status =  NAND_TIMEOUT_ERROR;
  }
  /*!&lt; 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;
  /*!&lt; Read status operation ------------------------------------ */
  *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_STATUS;
  data = *(__IO uint8_t *)(Bank_NAND_ADDR);
  if((data &amp; NAND_ERROR) == NAND_ERROR)
  {
    status = NAND_ERROR;
  }
  else if((data &amp; 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-&gt;Block++;
   
    if(Address-&gt;Block == NAND_ZONE_SIZE)
    {
      Address-&gt;Block = 0;
      Address-&gt;Zone++;
      if(Address-&gt;Zone == NAND_MAX_ZONE)
      {
        status = NAND_INVALID_ADDRESS;
      }
    }
  }
 
  return (status);
}
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */
/**
  * @}
  */ 
/******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/
 
回复 支持 反对

使用道具 举报

24

主题

317

回帖

0

蝴蝶豆

高级会员

最后登录
2020-10-10
发表于 2012-9-1 10:34:32 | 显示全部楼层

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

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

stm32f207 fsmc+nandflash.rar

下载

1.28 MB, 下载次数: 2884

回复 支持 反对

使用道具 举报

4

主题

224

回帖

0

蝴蝶豆

初级会员

最后登录
2020-7-4
发表于 2012-9-1 23:01:31 | 显示全部楼层

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

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

使用道具 举报

3

主题

9

回帖

0

蝴蝶豆

新手上路

最后登录
1970-1-1
 楼主| 发表于 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接口啊??????   ————哪位大神知道这其中的奥秘啊,真心求教。
回复 支持 反对

使用道具 举报

3

主题

4

回帖

0

蝴蝶豆

新手上路

最后登录
2017-1-10
发表于 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管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版