Chinaunix首页 | 论坛 | 博客
  • 博客访问: 23345
  • 博文数量: 3
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2015-11-03 20:09
文章分类
文章存档

2015年(3)

我的朋友

分类: 嵌入式

2015-11-03 20:12:02

    三星公司的Nand Flash型号为K9F1G08U0B是128MB大小的储存器,其读写与64MB的K9F1208有一定的区别,在此记录一下,有关Nand Flash原理的分析请看我的另一篇文章。K9F1G08U0B的 1 Block = 64 Page=(128K +4 K) 1 page = (2K + 64)byte。下面是它的组织结构图。
    其中在命令上也有区别,主要是读数据的命令上有变化,必须在第一个周期发送完命令0x00H,再发送完地址序列后,再发送一个0x30命令。由于页的大小是2KB的,所以在传送地址序列是,列地址的大小也不一样了,页内地址的话、row地址应该是A11~A26. 第五个周期(也就是第三个row地址周期)只有在NAND Flash大小超过128M的时候才有意义。K9F1G08U0B会自己忽略,也就是说可以去掉!下面的数据手册上的地址周期的描述。

int NF_Write_Page(U32 addr,U8 *buf,U32 size)
{    /* 函数传送的参数 addr 应该是一个不大于0x07FFFFFF,的值,因为Nand Flash 是128MB的地址范围就是 0-0x07FFFFFF 64MB 0---0x03FFFFFF*/
    U32 i,page_num;
    U32 bak;
    NF_nFCE_L();
    NF_CLEAR_RB();
    NF_CMD(0x80);
    page_num = addr >> 11;//相当于addr / 2408 页大小是2KB
    
    NF_ADDR(addr & 0xff);
    NF_ADDR((addr>>8) & 0x7);//表示从一页中的某个字节开始写的,
    NF_ADDR(page_num & 0xff);
    NF_ADDR((page_num >> 8) & 0xff);
    NF_ADDR((page_num >> 16)& 0xff);
    //NF_ADDR((addr >> 11) & 0xff); 这里和上面的三行是等价的,也是求page和block地址,只是表示的方法不一样
    //NF_ADDR((addr >> 19) & 0xff);

    //NF_ADDR((addr >> 27) & 0xff);
    for(i = 0;i < size;i++)
    {
        NF_WRDATA(buf[i]);
    }
    
    NF_CMD(0x10);
    NF_WAITRB();
    
    NF_CMD(0x70);
    bak = NF_RDDATA8();
    NF_nFCE_H();
    
    if(bak & 0x01)
    {
        return 0;
        Uart_Printf("Write Faile!\r\n");
    }
    else
    { Uart_Printf("Write successful!\r\n");
        return 1;
    }
}  


int Nand_Read_Page(U32 addr,U8 * buf,U32 size)
{
    U8 *ptr16 = (U8 *)buf;
    U32 i,page_num,bak;
    
    NF_nFCE_L();
    NF_CLEAR_RB();
    NF_CMD(0x00);
    
    page_num = addr >> 11 ;
    
    NF_ADDR (addr & 0xff);
    NF_ADDR ((addr >>8)& 0x7 );
    NF_ADDR(page_num & 0xff);
    NF_ADDR ((page_num >>8) & 0xff);
    NF_ADDR ((page_num >>16) & 0xff);
    //NF_ADDR((addr >> 11) & 0xff);
    //NF_ADDR((addr >> 19) & 0xff);
    //NF_ADDR((addr >> 27) & 0xff);

    NF_CMD(0x30);//发送完地址序列后还要发送 命令0x30
    
    NF_DETECT_RB();
    
    for(i=0;i< size;i++)
    {
        buf[i] = NF_RDDATA8();
    }
    NF_CMD(0x70);
    bak = NF_RDDATA8();
    NF_nFCE_H();
    if(bak & 0x01)
    {
        Uart_Printf("Read faile!\r\n");
        return 0;
    }
    else
    {
        Uart_Printf("Read successful\r\n");
        return 1;
    }
}


阅读(1948) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~