当前位置:首页 > 技术 > Cortex-M3 > 正文内容

STM32CubeMX系列教程20:Nand Flash

Watrt7年前 (2017-12-17)Cortex-M320260
一、Nand Flash 简介

        Flash 中文名字叫闪存,是一种长寿命的非易失性(断电数据不丢失)的存储器。可以对称为块的存储器单元块进行擦写和再编程,在进行写入操作之前必须先执行擦除。功能性分为两种:
NOR Flash:允许随机存取存储器上的任何区域,编码应用为主,其功能多与运算相关
Nand Flash:主要功能是存储资料,适合储存卡之类的大量数据的存储。
本章以K9F1G08U0E芯片为例讲解Nand Flash。如下为此芯片的数据手册:


二、Nand Flash存储结构



        一个Nand Flash由多个块(Block)组成,每个块里面又包含很多页(page)。每个页对应一个空闲区域/冗余区域(spare area),这个区域不是用来存储数据的,用于放置数据的校验值检测和纠错的。
块,是Nand Flash的擦除操作的基本/最小单位。
页,是Nand Flash的写入操作的基本/最小的单位。
从上图可知,K91FG080U0E包含1024 Blocks,每个Block包含 64 Pages,每个Page包含2K Bytes数据空间 + 64 Bytes冗余空间。故总大小=1024 Blocks  x 64 Pages x (2K+ 64) B = (1024 + 32) MBits = 1G Bits。

K91G08U0E功能框图如下:




三、Nand Flash引脚功能说明





上图是常见的Nand Flash所拥有的引脚(Pin)所对应的功能,简单翻译如下:


  1. I/O0 ~ I/O7:用于输入地址/数据/命令,输出数据

  2. CLECommand Latch Enable,命令锁存使能,在输入命令之前,要先在模式寄存器中,设置CLE使能

  3. ALEAddress Latch Enable,地址锁存使能,在输入地址之前,要先在模式寄存器中,设置ALE使能

  4. CE#Chip Enable,芯片使能,在操作Nand Flash之前,要先选中此芯片,才能操作

  5. RE#Read Enable,读使能,在读取数据之前,要先使CE#有效。

  6. WE#Write Enable,写使能,在写取数据之前,要先使WE#有效。

  7. WP#Write Protect,写保护

  8. R/B#:Ready/Busy Output,就绪/,主要用于在发送完编程/擦除命令后,检测这些操作是否完成,,表示编程/擦除操作仍在进行中,就绪表示操作完成.

  9.  VccPower,电源

  10. VssGround,接地

  11. N.CNon-Connection,未定义,未连接

(字母上面带横杠说明引脚是低电平有效,为书写方便,在字母后面加“#”表示)
四、可变存储控制器(FMC)

        FMC,即可变存储控制器,为STM32系列单片机的接口,本章就是通过这个接口控制NAND FLAHS。

FMC 功能块可连接:同步/异步静态存储器、 SDRAM 存储器和 NAND Flash。其主要用途有:

  • 将 AHB 数据通信事务转换为适当的外部器件协议

  • 满足外部存储器器件的访问时间要求


        
        说得复杂一点,FMC个功能就是将读写stm32内部地址操作转换为输出满足外部存储器的时序读写外部存储器。例如对STM32内部Ox8000 0000地址写入一个数据,FMC控制器会控制对应的管脚输出一个满足Nand Flash的时序,发送一个数据到Nand Flash设备。同理读取读取内部的寄存器,也会生成一个时序从Nand Flash读取一个数据。因此通过FMC控制外设非常简单,只需读写STM32内部寄存器即可实现对外部存储器的读写操作。我们只需配置好FMC时序寄存器,使产生的时序满足外部存储器的访问时间要求。



        FMC框图如上图,所有外部存储器共享地址、数据和控制信号, 但有各自的片选信号。 FMC 一次只能访问一个外部器件。其中FMC_A[25:0],FMC_D[31:00]为地址线和数据线,由于Nand Flash地址线和数据线复用,故配置时地址线和数据线是一样的。Nand Flash接口如下图(摘自Open746I-C原理图)。





FMC的存储区域外部储存分配图如图。其中Nand Flash为储存区域3,4x64MB。起始地址为0x8000 0000。



五、Nand Flash控制时序

        和前面介绍的串行Nor Flash芯片W25Q128FV类似,Nand Flash也是通过指令控制的,在这里简单讲解一下Nand Flash的控制时序,讲解这部分只要是为了加深对Nand Flash的了解,和学习看时序图,实际编程的时候是不需要用到的,这部分ST公司已经提供nand flash的库了,我们只需调用函数控制Nand flash即可,不需要再理会底层。
   下面为Nand Flash操作指令:




        如下编程操作和读操作的时序。首先先拉低NCE片选,只有选中芯片才能让他工作。
 Nand Flash是通过 ALE/CLE 来区分数据线上的数据是命令(CLE有效),地址(ALE有效)还是数据(CLE/ALE都无效)。通过NWE/NRE来区分数据线上的数据是写操作(NWE有效)还是读操作(NRE有效)。






下面为发送命令的时序图,已经对应的时间参数表:







用FMC控制Nand Flash 我们只需要知道访问波形图中的四个时间参数既可。



从上这三个图我们可以知道:
        MEMxSET = tCLS - tWP >= 0ns
        MEMxWAIT = tWP  >= 12ns
        MEMxHOLED = tCLH >= 5ns
        MEMxHIZ = tCLS - tDS >= 0ns
六、新建工程
       复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置,选择NCE3开启NAND Flash,数据地址线选择8 bits,Ready or Busy选择 NWAIT。
    

FMC配置NAND Flash如下:使能ECC校验,建立保存等待等时间参数设置可以见上一节的时序图时间参数。
FMC是挂载到AHB时钟线上,频率等于系统时钟频率,即216M,时钟周期为 1 /216 MHz = ~4.6ns。
NAND属性信息根据前面介绍的K91FG080U0E存储结构配置。



生成报告以及代码,编译程序。在fmc.c文件中可以看到初始化函数。在stm32f7xx_hal_nand.h头文件中可以看到NAND Flash的操作函数。

声明变量: RxBuffer,TxBnffer为读写缓存,大小可以Nand flash一页的长度;NAND_ID储存ID信息,WriteReadAddr为存储Nand Flash操作地址。

/* USER CODE BEGIN PV */
/* Private variables ---------------------------------------------------------*/
/* for K9F1G08 */
#define NAND_PAGE_SIZE             ((uint16_t)0x0800) /* 2 * 1024 bytes per page w/o Spare Area */
 
NAND_IDTypeDef NAND_ID;
NAND_AddressTypeDef WriteReadAddr;
 
static uint8_t TxBuffer [NAND_PAGE_SIZE];
static uint8_t RxBuffer [NAND_PAGE_SIZE];
uint16_t i;
/* USER CODE END PV */

添加应用程序,程序中先读取Nand Flash ID,然后配置操作地址,对页进行擦除,写,读等操作

/* USER CODE BEGIN 2 */
  printf("\r\nNandFlash Example \r\n\r\n");
     
  /* Read the NAND memory ID */                                                                  
  HAL_NAND_Read_ID(&hnand1, &NAND_ID);
 
  printf("Nand Flash ID = 0x%02X,0x%02X,0x%02X,0x%02X  ",NAND_ID.Maker_Id, NAND_ID.Device_Id,
                                                 NAND_ID.Third_Id, NAND_ID.Fourth_Id );
  if ((NAND_ID.Maker_Id == 0xEC) && (NAND_ID.Device_Id == 0xF1)
        && (NAND_ID.Third_Id == 0x80) && (NAND_ID.Fourth_Id == 0x15))
  {
        printf("Type = K9F1G08U0A\r\n");
  }
  else if ((NAND_ID.Maker_Id == 0xEC) && (NAND_ID.Device_Id == 0xF1)
        && (NAND_ID.Third_Id == 0x00) && (NAND_ID.Fourth_Id == 0x95))
  {
        printf("Type = K9F1G08U0B\r\n");     
  }
  else if ((NAND_ID.Maker_Id == 0xAD) && (NAND_ID.Device_Id == 0xF1)
        && (NAND_ID.Third_Id == 0x80) && (NAND_ID.Fourth_Id == 0x1D))
  {
        printf("Type = HY27UF081G2A\r\n");       
  }
  else
  {
        printf("Type = Unknow\r\n");
  }
     
  /* NAND memory address to write to */
  WriteReadAddr.Zone = 0x00;
  WriteReadAddr.Block = 0x00;
  WriteReadAddr.Page = 0x00;
 
  /* Erase the NAND first Block */
  HAL_NAND_Erase_Block(&hnand1,&WriteReadAddr);
 
  /* Fill the buffer to send */
  for (i = 0; i < NAND_PAGE_SIZE; i++ )
  {
     TxBuffer[i] = i;
  }
 
  /* Write data to FMC NAND memory */
  HAL_NAND_Write_Page(&hnand1, &WriteReadAddr, TxBuffer, 1);
  printf("\r\nWritten to the number of£º \r\n");
  for(i = 0; i < 2048; i++)
      printf("0x%02X \r",TxBuffer[i]);
 
  HAL_Delay(100);
  /* Read data from FMC NAND memory */
  HAL_NAND_Read_Page(&hnand1, &WriteReadAddr, RxBuffer, 1);
  printf("\r\nRead receive: \r\n");
  for(i = 0; i < 2048; i++)
      printf("0x%02X \r",RxBuffer[i]);


分享给朋友:

相关文章

STM32CubeMX系列教程2:外部中断(EXIT)

STM32CubeMX系列教程2:外部中断(EXIT)

      这一章我们在前一章GPIO的工程修改。复制GPIO的工程,修改文件夹名。点击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置。PA0管脚重新配置为GPIO_EXIT0模式。 WAKEUP按键已经外部下拉,按下是PA0为高电平。在GPIO配置中配置PA0为上升沿触发。内部既不上拉也不下拉,添加用户标签WAKEUP。在NVIC(嵌套向量中断控制器)中,勾选EXIT Line0 interrupt使能PA0中断。右边两个选项设置抢占优...

STM32CubeMX系列教程3:基本定时器

STM32CubeMX系列教程3:基本定时器

这一章我们在前一章GPIO的工程修改。复制GPIO的工程,修改文件夹名。点击打开STM32cubeMX的工程文件重新配置。开启定时器TIM3,选择内部时钟。定时器就相当于单片机的闹钟,下面我们以基本定时器为例简单介绍一下定时器。从上图我们可以看到,基本定时器主要由下面三个寄存器组成。计数器寄存器 (TIMx_CNT)预分频器寄存器 (TIMx_PSC)自动重载寄存器 (TIMx_ARR)计数器寄存器 (TIMx_CNT)存储的是当前的计数值。预分频器&nb...

STM32CubeMX系列教程6:直接存储器访问 (DMA)

STM32CubeMX系列教程6:直接存储器访问 (DMA)

直接存储器访问 (DMA) 用于在外设与存储器之间以及存储器与存储器之间提供高速数据传输。可以在无需任何 CPU 操作的情况下通过 DMA 快速移动数据。这样节省的 CPU 资源可供其它操作使用。说白了DMA就是一个搬运工,将数据从一个地方搬到另一个地方而不需要CPU处理。        作为一个搬运工,要他正常工作必须要确定几个重要的参数。1.传输模式:数据从哪里搬到哪里。...

STM32CubeMX系列教程14:电源控制器(PWR)

STM32CubeMX系列教程14:电源控制器(PWR)

一.低功耗模式介绍        系统提供了多个低功耗模式,可在 CPU 不需要运行时(例如等待外部事件时)节省功耗。由用户根据应用选择具体的低功耗模式,以在低功耗、短启动时间和可用唤醒源之间寻求最佳平衡。        当系统断电时,仍然可以通过电池供电保留备份域的数据。备份域中包含RTC实时时钟,4KB备份SRAM以及调压器,调压器为备份域和待机电路以外...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。