ARM第六天(Nand Flash 上)

本文深入介绍了NandFlash存储设备的工作原理和技术细节,包括其在TPAD中的应用、操作方法及特性,还提供了读取NandFlash ID的实例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这里写图片描述
1,什么是Nand fash?
存储设备,用于存储整个系统(引导程序、内核、文件系统),相当于PC中的硬盘。

2,TPAD采用了什么Nand Flash
三星公司的K9K8G08U0B型号的Nand Flash。

3,如何才能操作Nand Flash,主要是对它进行写操作,读操作,校验操作
需要阅读Nand flash的datasheet ,该手册会详细描述如何操作nand falsh的正确方法。

4,Nand Flash能用特性
1),Nand Flash在没写数据之前,Nand Flash都是1
2),如果已经写了数据 ,再写数据,必须先擦除
在Nand Flash只有将1改成0的能力,没有将0改成1的能力。
3),Nand Flash在出厂时,可能存在坏块,但是不影响使用,并且保证第一块一定是好块。
4),Nand Flash的擦写次数有限。100K 次

5,K9K8G08U0B Nand Flash的主要指标参数
1),工作电压: 3.3V
2),容量:(1G + 32M) x 8bit
3),写操作:按页(2K+66)Byte
擦除操作:按块(128K+4k)Byte
4),页大小:(2K+64)Byte
块大小: (128+4K)Byte
1块 = 64页
5),IO管脚复用:命令、地址、数据复用IO口
6),Nand Flash可以100K次的写、擦除
数据保存时间:10年
7),通过命令来操作Nand flash
8),Nand flash存在唯一的ID号
9),Nand flash封装形式
这里写图片描述

Nand Flash共有48个管脚,并不是每个管脚都使用了。
N.C:没有使用,无连接的管脚,可以不用管
Vcc:电源
Vss:接地
nCE:低电平有效,片选信号,低电平有效
IO0-IO7:8个IO管脚,功能复用,传输命令、地址,数据
CLE:高电平有效,命令锁存信号,如果这个信号为高,表示IO0-IO7传输的是命令
ALE:高电平有效,地址锁存信号,IO0-IO7传输的是地址。CLE、ALE不同时为高
当CLE、ALE都为低电平时,IO0-IO7传输的是数据
CLE ALE
1 0 命令
0 1 地址
0 0 数据
nWE:低电平有效,写使能. 可以写命令、写地址、写数据
nRE:低电平有效,读使能
nWP:低电平有效,写保护
R/nB:当前Nand flash的状态
R:高电平,表示Ready,准备就绪
nB:低电平,表示Busy,忙

Nand Flash芯片上的各个管脚实际上与S5PV210处理器中的Nand Falsh控制器相连(所谓Nand flash控制器从表现形式上看,也就是一引起S5PV210上管脚,只是部分管理的主要功能是用来控制Nand Flash),因此,我们不用直接去操作Nand flash的管脚,而是通过操作Nand Flash控制器中的寄存器来实现对Nand Flash的操作。

Nand Flash控制器的寄存器的地址范围:
这里写图片描述
SFRS特殊功能寄存器

Nand Flash的内部结构图:
这里写图片描述
1,页:构成Nand Flashr的基本单位,页大小固定
1 page = (2K + 64)bytes = (2048(main) + 64(spare))bytes
每一页又分为main区和spare区
main区:用于正常数据的存储
spare区:用于存储一些附加信息,如坏块的标志,块的逻辑地址,ECC校验信息
2,块:由若干页构成,64页构成一块,块大小固定
1 block = (2K+64)bytes * 64 page = (128K(main)+4K(spare))bytes
3,device:由若干块构成,8192块
1 device = (128K + 4K)*8192 = (1G + 32M)bytes = (1024M+32M)bytes=(1056M)bytes = 8448Mbits

Nand Flash:(1G+32M)bytes
1G字节:存储主数据,main区
32M字节:存储附加信息,spare区

块号:8192块,0~8191块
页号:8192*64 = 524288页 ,0~524287页

表示Nand Flash地址,需要多少bit来表示一个字节的地址?
这里写图片描述

31bit地址如何发送?
IO0-IO7 8个IO管脚,一次只能发8bit
由于Nand Flash是I/O接口,复用,只用用8根IO线发送地址一次发8bit,共分5个周期(Nand Flash的datasheet定义)
5个周期:
1周期:A0-A7(页内地址,列地址)
2周期:A8-A11 0000 (页内地址,列地址)
3周期:A12-A19(页内地址,行地址)
4周期:A20-A27 (页内地址,行地址)
5周期:A28-A30 0000

案例:
列地址(页内地址):2048
行地址(行号):518400

如何发送?
2048 00001000,00000000
518400 00000111,11101001,00000000

由Nand Flash的Datasheet可知,Nand Flash是通过命令来操作的:
这里写图片描述

Nand Flash不一样,对应的命令集不一样。

Nand Flash:
通用特性:
具体特性:

Nand Flash管脚:
Nand Flash内部结构 :页、块
地址:31bit ,分5个周期来发送
命令集:

Nand Flash 控制器:
阅读S5PV210 datasheet P692
1,支持Nand Flash页大小:512Bytes,2KB,4KB,8KB
2,可以通过软件编程的方式实现对Nand Flash进行读操作、写操作、擦除操作
3,支持8bit的IO口的Nand Flash.
4,硬件可以产生,监测ECC校验码,软件纠正。
5,支持SLC和MCL两种工艺的Nand Flash
6,ECC:支持1\4\8\12\16 bit ECC
7,特殊功能寄存器的访问方式。
Data(数据寄存器NFDATA)和ECC data数据寄存器,可以采用字节,半字,字的方式访问,其余寄存器采用字方式访问。
这里写图片描述

寄存器
这里写图片描述

如何通过软件编程的方式操作Nand Flash(P695)
1,向命令寄存器(NFCMMD)写入操作Nand Flash的命令
2,向地址寄存器(NFADDR)写入要操作Nand Flash的具体地址
3,向数据寄存器(NFADATA)写入要向Nand Flash写主的数据
4,从数据寄存器(NFADATA)读出Nand Flash的数据
5,读出main区和spare区的ECC校验信息,进行数据校验

NFCONF 配置寄存器
这里写图片描述
这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

HCLK = 133MHZ = 7 ns;

TACLS:表征的是从CLE(命令锁存信号)/ALE (地址锁存信号)有效,到nWE写使能信号有效经过的时间Druation1.
Druation1 = HCLK * TACLS = 7ns * TACLS >=0
= tCLS - tWP = tALS - tWP
= 12 - 12 = 12 - 12
TACLS = 15
TWRPH0:表征的是nWE写使能信号的有效时间Druation2。
Druation2 = HCLK *(TWRH0+1)
= 7ns *(TWRH0+1)>=12
= tWP
= 12 ns
TWRH0 = 15
TWRPH1:表征的是nWE写使能信号无效之后,CLE\ALE信号还要维持的时间Druation3。
Druation3 = HCLK *(TWRPH1+1)
= 7ns *(TWRPH1+1)>=5
= tCLH = tALH
= 12 ns
TWRPH1 = 15

NFCONT 控制寄存器
这里写图片描述
NFCMMD命令寄存器
这里写图片描述
NFADDR地址寄存器
这里写图片描述
NFDATA数据寄存器
这里写图片描述
这里写图片描述

NFSTAT状态寄存器

读时序图:
这里写图片描述

read Nand Flash 的ID案例
nand.h

#define __NAND_H__
#define __NAND_H__

//定义寄存器
#define NFCONF (*((volatile unsigned int*)0xBOE00000));
#define NFCONT (*((volatile unsigned int*)0xBOE00004));
#define NFCMMD (*((volatile unsigned int*)0xBOE00008));
#define NFADDR (*((volatile unsigned int*)0xBOE0000C));
#define NFDATA (*((volatile unsigned int*)0xBOE00010));
#define NFSTAT (*((volatile unsigned int*)0xBOE00028));

//声明函数原型
extern void nand_init(void);
extern void nand_read_id(void);

#endif

nand.c文件:

#include "nand.h"
#include "uart.h"
#include "itoa.h"

void nand_init(void)
{
   //nand flash 控制器使用的管脚配置,
   //因为我们使用的nand flash启动方式,所以关于GPIO管脚功能配置可以不做
   //如果使用的不是nand flash启动,将需要配置
   NFCONF = (0xF<<12) | (0xF<<8) |(0xF<<4) | (1<<1); 
   NFCONT = (3<<12) | (3<<8) | 7; 
}

void nand_read_id(void)
{
   //1,nand falsh片选信号拉低,使能nand falsh芯片
   //操作 NFCONT bit[1] = 0;
   NFCONT &= ~(1<<1);//  1<<1 ==> 10
   //2,向NFCMMD寄存器写入0x90
   NFCMMD = 0x90;
   //3,向NFADDR寄存器写入0x0
   NFADDR = 0x0;
   //4,延时
   int i;
   for(i = 0;i < 256; i++)
   {
      ;
   }
   //5,读NFDATA 寄存器(字)ID
   //读5个字节的ID号
   unsigned int id1;
   unsigned int id2;
   id1 = NFDATA;
   id2 = (NFDATA & 0xFF);//只要低八位
   //6,Nand flash片选信号拉高
    //操作 NFCONT bit[1] = 1;
   NFCONT |= (1<<1) ;
   //7,显示读出来的nand flash的ID号
   char buf[16];
   uart0_puts("\n ID1 = ");
   itoa(buf,id1);//转换(整型无法直接打印,打印前转换成字符串)
   uart0_puts(buf);//输出

   uart0_puts("\n ID2 = ");
   itoa(buf2,id2);//转换
   uart0_puts(buf2);//输出
}

说明:
NFCONF = (0xF<<12) | (0xF<<8) |(0xF<<4) | (1<<1),
1<<1 ⇒ 10
0xF<<4 ==>1111,0000
0xF<<8 ==>1111,0000,0000
0xF<<12==>1111,0000,0000,0000
(0xF<<12) | (0xF<<8) |(0xF<<4) | (1<<1) = 1111,1111,1111,0010

cmd.c

#include "cmd.h"
#include "led.h"
#include "nand.h"

void cmd_ledon(void)
{
    //调用开灯函数
    led_on();
}

void cmd_nid(void)
{
    //调用读nand flash Id函数
    nand_read_id();
}

void cmd_ledoff(void)
{
    //调用关灯函数
    led_off();
}
const cmd_t cmd_tb1[] =
{
    {"ledon",cmd_ledon},
    {"ledoff",cmd_ledoff},
    {"nid",cmd_nid},
};

int cmd_tab1_num = sizeof(cmd_tb1)/sizeof(cmd_tb1[0]);

cmd_t *find_cmd(const char *name)
{
    for(int i=0;i<cmd_tab1_num;i++)
    {
      if(name == cmd_tb1[i].name)
      {
         return cmd_tb1[i];
      }  
    }
    return NULL;
}

main.c

#include "uart.h"
#include "strcmp.h"
#include "led.h"
#include "nand.h"

#define int BUF_LEN = 10;
#define char buf[BUF_LEN];
void main(void)
{
    char ch;
    //1,初始化串口
    uart0_init();
    led_init();
    nand_init();

    //2,发送一个字符串
    while(1){
        uart0_puts("\n Shell#");
    }
}

makefile 略

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值