什么是Flash闪存以及STM32使用NAND Flash

电子说

1.4w人已加入

描述

NAND

文章目录

NAND

一、FLASH闪存是什么?

二、SD NAND Flash

三、STM32例程

一、FLASH闪存是什么?

简介

FLASH闪存是属于内存器件的一种,“Flash”。闪存则是一种非易失性( Non-Volatile )内存,在没有电流供应的条件下也能够长久地保持数据,其存储特性相当于硬盘,这项特性正是闪存得以成为各类便携型数字设备的存储介质的基础。


 

各类 DDR 、 SDRAM 或者 RDRAM 都属于挥发性内存,只要停止电流供应内存中的数据便无法保持,因此每次电脑开机都需要把数据重新载入内存。


 

闪存则是一种非易失性( Non-Volatile )内存,在没有电流供应的条件下也能够长久地保持数据,其存储特性相当于硬盘,这项特性正是闪存得以成为各类便携型数字设备的存储介质的基础。


 

分类

NOR和NAND是市场上两种主要的非易失闪存技术。


 

在1984年,东芝公司的发明人舛冈富士雄首先提出了快速闪存存储器(此处简称闪存)的概念。与传统电脑内存不同,闪存的特点是NVM,其记录速度也非常快。


 

Intel是世界上第一个生产闪存并将其投放市场的公司。1988年,公司推出了一款256K bit闪存芯片。它如同鞋盒一样大小,并被内嵌于一个录音机里。後来,Intel发明的这类闪存被统称为NOR闪存。它结合EPROM和EEPROM两项技术,并拥有一个SRAM接口。


 

第二种闪存称为NAND闪存。它由日立公司于1989年研制,并被认为是NOR闪存的理想替代者。NAND闪存的写周期比NOR闪存短90%,它的保存与删除处理的速度也相对较快。NAND的存储单元只有NOR的一半,在更小的存储空间中NAND获得了更好的性能。鉴于NAND出色的表现,它常常被应用于诸如CompactFlash、SmartMedia、 SD、 MMC、 xD、 and PC cards、USB sticks等存储卡上。


 

NAND 闪存的存储单元采用串行结构,存储单元的读写是以页和块为单位来进行(一页包含若干字节,若干页则组成储存块, NAND 的存储块大小为 8 到 32KB ),这种结构最大的优点在于容量可以做得很大,超过 512MB 容量的 NAND 产品相当普遍, NAND 闪存的成本较低,有利于大规模普及。


 

特点

性能


 

flash闪存是非易失存储器,可以对称为块的存储器单元块进行擦写和再编程。任何flash器件的写入操作只能在空或已擦除的单元内进行,所以大多数情况下,在进行写入操作之前必须先执行擦除。NAND器件执行擦除操作是十分简单的,而NOR则要求在进行擦除前先要将目标块内所有的位都写为1。


 

由于擦除NOR器件时是以64~128KB的块进行的,执行一个写入/擦除操作的时间为5s,与此相反,擦除NAND器件是以8~32KB的块进行的,执行相同的操作最多只需要4ms。


 

执行擦除时块尺寸的不同进一步拉大了NOR和NADN之间的性能差距,统计表明,对于给定的一套写入操作(尤其是更新小文件时),更多的擦除操作必须在基于NOR的单元中进行。这样,当选择存储解决方案时,设计师必须权衡以下的各项因素。


 

● NOR的读速度比NAND稍快一些。


 

● NAND的写入速度比NOR快很多。


 

● NAND的4ms擦除速度远比NOR的5s快。


 

● 大多数写入操作需要先进行擦除操作。


 

● NAND的擦除单元更小,相应的擦除电路更少。


 

可靠性


 

采用flash介质时一个需要重点考虑的问题是可靠性。对于需要扩展MTBF的系统来说,Flash是非常合适的存储方案。可以从寿命(耐用性)、位交换和坏块处理三个方面来比较NOR和NAND的可靠性。


 

耐用性


 

在NAND闪存中每个块的最大擦写次数是一百万次,而NOR的擦写次数是十万次。NAND存储器除了具有10比1的块擦除周期优势,典型的NAND块尺寸要比NOR器件小8倍,每个NAND存储器块在给定的时间内的删除次数要少一些。


 

易于使用


 

可以非常直接地使用基于NOR的闪存,可以像其他存储器那样连接,并可以在上面直接运行代码。


 

由于需要I/O接口,NAND要复杂得多。各种NAND器件的存取方法因厂家而异。


 

在使用NAND器件时,必须先写入驱动程序,才能继续执行其他操作。向NAND器件写入信息需要相当的技巧,因为设计师绝不能向坏块写入,这就意味着在NAND器件上自始至终都必须进行虚拟映射。


 

其他作用


 

驱动还用于对DiskOnChip产品进行仿真和NAND闪存的管理,包括纠错、坏块处理和损耗平衡。


 

虚拟化

FLASH闪存是一种内存技术,与RAM不同,在断电时它仍旧可以保留所存储的信息。尽管FLASH闪存在执行读写操作时并不像RAM那样快,但性能远远高于典型的硬盘。更为重要的是,FLASH闪存访问数据时几乎不存在任何时间延迟。FLASH闪存技术非常适合随机I/O,而虚拟服务器环境中恰恰存在大量的随机I/O。


 

对FLASH闪存主要的关注点之一是其执行写操作的方式。FLASH闪存可以执行的写操作次数有限,这意味着FLASH闪存厂商需要开发复杂的控制器技术,对写入FLASH闪存模块的方式进行管理,确保每个FLASH闪存单元接收相同的写请求。


 

目前有三种类型的FLASH闪存,耐久性各不相同。单阶存储单元(SLC)FLASH闪存在每个单元写一位数据,耐久性最好。多阶存储单元(MLC)FLASH闪存在每个单元写多位数据,耐久性排名第二。三阶存储单元(TLC)在每个单元写三位数据,耐久性最差。每个单元写入的数据位越多意味着每个单元的容量越高,每GB的成本越低,同样意味着平均寿命更短。


 

SLC是数据中心标准,但控制器技术的不断优化使得MLC被大多数用例所接受。尤其是在采用了某种方式的数据保护,比如镜像或者RAID或者使用了FLASH闪存层时。


 

二、SD NAND Flash

我以贴片式TF卡“CSNP32GCR01-AOW”型号为例介绍

NAND


 

芯片样子都一样,这里随便放一张


 

概述

CSNP32GCR01-AOW是基于NAND闪存和SD控制器的32Gb密度嵌入式存储。该产品与原始NAND相比,它有许多优点,包括嵌入式坏块管理和更强的嵌入式ECC。即使在异常断电的情况下,它仍然可以安全地保存数据。


 

特点

接口:标准SD规范2.0版,带有1-I/O和4-I/O。


 

电源:Vcc=2.7V-3.6V


 

默认模式:可变时钟频率0-25 MHz,最高12.5 MB/秒接口速度(使用4条并行数据线)


 

高速模式:可变时钟频率0-50 MHz,最高25 MB/秒接口速度(使用4条并行数据线)


 

工作温度:-25°C至+85°C


 

储存温度:-40°C至+85°C


 

备用电流:<250uA


 

开关功能命令支持高速、电子商务和未来功能


 

内存字段错误的纠正


 

内容保护机制-符合SDMI标准的最高安全性。


 

SD NAND的密码保护(CMD42-锁定和解锁)


 

使用机械开关的写保护功能


 

内置写保护功能(永久和临时)


 

特定于应用程序的命令

3. 引脚分配

NANDNAND


 

4.数据传输模式

NAND

5. SD NAND寄存器


 

SDNAND接口中定义了六个寄存器:OCR、CID、CSD、RCA、DSR和SCR。这些信息只能通过


 

相应的命令。OCR、CID、CSD和SCR寄存器携带SDNAND/内容特定信息,而RCA、DSR寄存器是存储实际配置参数的配置寄存器(这里选取俩个寄存器进行展示)。


 

CID register

NAND

SCR register

NAND


 

通电图

NAND

通电时间

NANDNAND


 

Tips: RDAT和RCMD(10K~100 kΩ)是上拉电阻器,当SDNAND处于a状态时,保护CMD和DAT线路不受总线浮动的影响;在高阻抗模式,即使主机仅在SD模式下使用SDNAND作为1位模式,主机也应通过RDAT上拉所有DAT0-3线。它是建议VCC上有2.2uF电容。RCLK参考0~120Ω。


 

NAND

三、STM32例程

1. 初始化


 


 


 

SD_Error SD_Init(void)


 

{


 

  uint32_t i = 0;


 


 


 

  /*!< Initialize SD_SPI */


 

  GPIO_Configuration(); 


 


 


 

  /*!< SD chip select high */


 

  SD_CS_HIGH();


 


 


 

  /*!< Send dummy byte 0xFF, 10 times with CS high */


 

  /*!< Rise CS and MOSI for 80 clocks cycles */


 

  for (i = 0; i <= 9; i++)


 

  {


 

    /*!< Send dummy byte 0xFF */


 

    SD_WriteByte(SD_DUMMY_BYTE);


 

  } 


 


 

//获取卡的类型,最多尝试10次


 

i=0;


 

do


 

{


 

/*------------Put SD in SPI mode--------------*/


 

/*!< SD initialized and set to SPI mode properly */


 

SD_GoIdleState();


 


 


 

/*Get card type*/


 

SD_GetCardType();


 


 

}while(SD_Type == SD_TYPE_NOT_SD && i++ >10);


 


 

//不支持的卡


 

if(SD_Type == SD_TYPE_NOT_SD)


 

return SD_RESPONSE_FAILURE;


 


 

return SD_GetCardInfo(&SDCardInfo);


 


 

}


 

2. 单数据块测试


 


 


 

void SD_SingleBlockTest(void)


 

{  


 

  /*------------------- Block Read/Write --------------------------*/


 

  /* Fill the buffer to send */


 

  Fill_Buffer(Buffer_Block_Tx, BLOCK_SIZE, 0x320F);


 


 


 

  if (Status == SD_RESPONSE_NO_ERROR)


 

  {


 

    /* Write block of 512 bytes on address 0 */


 

    Status = SD_WriteBlock(Buffer_Block_Tx, 0x00, BLOCK_SIZE);


 

    /* Check if the Transfer is finished */


 

  }


 


 


 

  if (Status == SD_RESPONSE_NO_ERROR)


 

  {


 

    /* Read block of 512 bytes from address 0 */


 

    Status = SD_ReadBlock(Buffer_Block_Rx, 0x00, BLOCK_SIZE);


 


 


 

  }


 


 


 

  /* Check the correctness of written data */


 

  if (Status == SD_RESPONSE_NO_ERROR)


 

  {


 

    TransferStatus1 = Buffercmp(Buffer_Block_Tx, Buffer_Block_Rx, BLOCK_SIZE);


 

  }


 


 

  if(TransferStatus1 == PASSED)


 

  {


 

    LED2_ON;


 

    printf("Single block 测试成功!n");


 


 


 

  }


 

  else


 

  {


 

LED1_ON;


 

    printf("Single block 测试失败,请确保SD卡正确接入开发板,或换一张SD卡测试!n");


 


 

  }


 

}


 

3. 多数据块测试


 


 

void SD_MultiBlockTest(void)


 

{  


 

  /*--------------- Multiple Block Read/Write ---------------------*/


 

  /* Fill the buffer to send */


 

  Fill_Buffer(Buffer_MultiBlock_Tx, MULTI_BUFFER_SIZE, 0x0);


 


 


 

  if (Status == SD_RESPONSE_NO_ERROR)


 

  {


 

    /* Write multiple block of many bytes on address 0 */


 

    Status = SD_WriteMultiBlocks(Buffer_MultiBlock_Tx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);


 

    /* Check if the Transfer is finished */


 

  }


 


 


 

  if (Status == SD_RESPONSE_NO_ERROR)


 

  {


 

    /* Read block of many bytes from address 0 */


 

    Status = SD_ReadMultiBlocks(Buffer_MultiBlock_Rx, 0x00, BLOCK_SIZE, NUMBER_OF_BLOCKS);


 

    /* Check if the Transfer is finished */


 

  }


 


 


 

  /* Check the correctness of written data */


 

  if (Status == SD_RESPONSE_NO_ERROR)


 

  {


 

    TransferStatus2 = Buffercmp(Buffer_MultiBlock_Tx, Buffer_MultiBlock_Rx, MULTI_BUFFER_SIZE);


 

  }


 


 

  if(TransferStatus2 == PASSED)


 

  {


 

LED2_ON;


 

    printf("Multi block 测试成功!");


 


 


 

  }


 

  else


 

  {


 

LED1_ON;


 

    printf("Multi block 测试失败,请确保SD卡正确接入开发板,或换一张SD卡测试!");


 

  }


 

}


 

4. 状态缓冲


 


 

TestStatus Buffercmp(uint8_t* pBuffer1, uint8_t* pBuffer2, uint32_t BufferLength)


 

{


 

  while (BufferLength--)


 

  {


 

    if (*pBuffer1 != *pBuffer2)


 

    {


 

      return FAILED;


 

    }


 


 


 

    pBuffer1++;


 

    pBuffer2++;


 

  }


 


 


 

  return PASSED;


 

}


 


 


 

void Fill_Buffer(uint8_t *pBuffer, uint32_t BufferLength, uint32_t Offset)


 

{


 

  uint16_t index = 0;


 


 


 

  /* Put in global buffer same values */


 

  for (index = 0; index < BufferLength; index++)


 

  {


 

    pBuffer[index] = index + Offset;


 

  }


 

}

了解产品更多详情:官网 http://www.longsto.com/

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 相关推荐
  • 热点推荐
  • NAND
  • SD

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分