zoukankan      html  css  js  c++  java
  • SAM4E单片机之旅——16、NAND Flash读写

    这次大概介绍了一下NAND Flash,以及在ASF中使用它的方法。

    一、 接线

    这个开发板搭载了一个256 MB,8位的NAND Flash(MT29F2G08ABAEA)。引脚接线如下:

    wps_clip_image-17474

    偷个懒,直接上引脚复用的图。其中PC14表明该NAND FLASH需要作为SMC的外设0使用。通过使用NANDOE和NANDWE引脚说明需要使用芯片的NAND Flash控制逻辑。另外,PC18复用为输入引脚,用以查询芯片的状态。

    wps_clip_image-1894

    二、 NAND Flash

    • 组织结构与寻址

      NAND Flash的容量较大。整片Flash分为若干个(Block),每个Block分为若干个(Page)。在每个页中,除了数据区域,也包含若干“多余”的区域,用来进行ECC等操作。在进行擦除操作是,基本单位是“块”;而编程的基本单位是“页”。

      另外,NAND Flash的物理特性决定了其在编程时,每个bit只能从1变成0。所以在写入前,必须先对该块进行擦除(擦除时把所有位置为1)。

      该Flash的结构如下(忽略plane):

      wps_clip_image-30709

      在寻址时,是通过行地址和列地址指定储存单元的。其中行地址表示页的编号,列地址表示指定在目标地址在该页的位置。

    • 读写时序

      因为没有地址线,所以读写较为复杂。读写时,需要先发送相应操作命令,然后发送地址,才能进行数据传输。一个简单的“页读取”操作时序图如下:

      wps_clip_image-13318

      该命令首先拷贝整个页到NAND Flash的cache寄存器中,然后在需要输出的时候,再从指定的列地址开始输出。

      PS,该NAND Flash支持在上电的时候自动送出第一页的数据,所以经过适当的配置,也是可以通过它进行Boot的。

    • CE# Don’t Care

      在给NAND Flash发送完命令后,Flash需要一个准备的过程。在这个过程中,需要保持片选信号的有效。(据说否则Flash就会进入低功耗状态)

      一个简单的方法是使用GPIO直接控制这个引脚。在ASF中使用的即是这个方法。

      另外的方法即是使用Flash的“CE# Don’t Care”功能。开启这个功能后,即使片选无效,Flash也会进行工作。这样做的好处是不用再手动控制片选信号线外;同时可以在Flash进行内部操作时,可以进行其他的片选。比如在一块Flash忙时,可以给另外一块Flash发送命令。但是,开启这个功能可能会增加Flash的功耗。

    三、 ASF中NAND Flash使用

    1. 准备

      在ASF Wizard中添加“NAND Flash on EBI”模块。

      在conf_board.h中进行如下声明,记得调用board_init():

      #define CONF_BOARD_NAND
    2. Flash 初始化

      在board_init()之后,调用nand_flash_raw_initialize() 即可完成NAND Flash的初始化工作。

      struct nand_flash_raw nf_raw;
      memset((void*)&nf_raw, 0, sizeof(nf_raw));
      
      // Init NAND Flash, and get informations into nf_raw
      if (nand_flash_raw_initialize(&nf_raw, 0,
      	BOARD_NF_COMMAND_ADDR, BOARD_NF_ADDRESS_ADDR, 	BOARD_NF_DATA_ADDR)) {
      	MainExit();
      }

      该函数中,会对SMC和若干引脚进行配置;同时对Bus matrix进行设置,以使用芯片提供的NAND Flash逻辑功能。

      然后会对NAND Flash进行重置。接着就会读取该Flash的ID,并根据该ID检测Flash的参数,如page大小,block数目等。

    3. 基本操作

      nand_flash_raw.h中还提供了一些比较基础的操作。

      以下代码对所有的块进行擦除,若在擦除中碰到错误,则打印出来(这里printf会通过UART0口打印,以后有机会会说怎么实现):

      // Get NAND's information from nf_raw
      const struct nand_flash_model* nf_mod = &(nf_raw.model);
      int num_block = nand_flash_model_get_device_size_in_blocks(nf_mod);
      // Erase all block
      printf("Erasing NAND Flash...
      
      ");
      int error;
      for (int i = 0; i < num_block; i++) {
      	error = nand_flash_raw_erase_block(&nf_raw, i);
      
      	if (error == NAND_COMMON_ERROR_BADBLOCK) {
      		printf("-E- Block %u is BAD block. 
      
      ", i);
      	}
      }

      还有page的写入、读取和拷贝等操作就不一一列举了……

  • 相关阅读:
    对于程序员来说,如何才能快速转行赶上大数据这辆高铁呢?
    大数据学习计划
    大数据学习详细路线
    大数据到底要怎么学习?
    大数据处理技术怎么学习呢?
    从零开始大数据学习路线
    大数据从入门到精通
    大数据学习路线
    8.【Spring Cloud Alibaba】配置管理-Nacos
    7.【Spring Cloud Alibaba】微服务的用户认证与授权
  • 原文地址:https://www.cnblogs.com/h46incon/p/3483067.html
Copyright © 2011-2022 走看看