历史上的今天
返回首页

历史上的今天

今天是:2024年12月03日(星期二)

正在发生

2019年12月03日 | nandflash的读写(2440)

2019-12-03 来源:eefocus

说明:

根据物理结构上的区别 , NandFlash主要分为如下两类:
1)•SLC (Single Level Cell): 单层式存储
2)•MLC (Multi Level Cell): 多层式存储
@:SLC在存储格上只存一位数据, 而MLC则存放两位数据。


1.nand.c

#define NFCONF (*(volatile unsigned long*)0x4E000000)
#define NFCONT (*(volatile unsigned long*)0x4E000004)
#define NFCMD  (*(volatile unsigned char*)0x4E000008)
#define NFADDR (*(volatile unsigned char*)0x4E00000C)
#define NFDATA (*(volatile unsigned char*)0x4E000010)
#define NFSTAT (*(volatile unsigned char*)0x4E000020)

#define TACLS 1
#define TWRPH0 2
#define TWRPH1 1


void select_chip()
{
    NFCONT &= ~(1<<1);    
}

void deselect_chip()
{
    NFCONT |= (1<<1);    
}

void clear_RnB()
{
   NFSTAT |= (1<<2); 
}

void send_cmd(unsigned cmd)
{
     NFCMD = cmd;
}

void send_addr(unsigned addr)
{
     NFADDR = addr;
}

void wait_RnB()
{
   while (!(NFSTAT&(1<<2)))    
   {
       ;    
   }
}

void nand_reset()
{
    //选中flash
    select_chip();
    
    //清除RnB
    clear_RnB();
    
    
    //发送0xff命令
    send_cmd(0xff);
    
    
    //等待RnB
    wait_RnB();
    
    
    //取消选中flash
    deselect_chip();
}

void nandflash_init()
{
    //初始化NFCONF
    NFCONF = (TACLS<<12) | (TWRPH0<<8) | (TWRPH1<<4);
    
    //初始化NFCONT
    NFCONT = (1<<0) | (1<<1);
    
    //复位
    nand_reset();    
}

void NF_PageRead(unsigned long addr,unsigned char* buff)
{
    int i;
    
    //选中nandflash芯片
    select_chip();
    
    //清除RnB
    clear_RnB();
    
    //发送命令0x00
    send_cmd(0x00);
    
    //发送列地址
    send_addr(0x00);
    send_addr(0x00);
    
    //发送行地址
    send_addr(addr&0xff);
    send_addr((addr>>8)&0xff);
    send_addr((addr>>16)&0xff);
    
    //发送命令0x30
    send_cmd(0x30);
    
    //等待RnB
    wait_RnB();
    
    //读取数据
    for(i=0;i<2048;i++)
    {
       buff[i] = NFDATA;      
    }
    
    //取消选中nandflash芯片
    deselect_chip();
}


void nand_to_ram(unsigned long start_addr, unsigned char* sdram_addr, int size)
{
     int i;
     
    for( i=(start_addr >>11); size>0;)
    {
        NF_PageRead(i,sdram_addr);    
        size -= 2048;
        sdram_addr += 2048;
        i++;
    }
}

int NF_Erase(unsigned long addr)
{
    int ret;
    
  //选中flash芯片
    select_chip();
    
    //清除RnB
    clear_RnB();
    
    //发送命令0x60
    send_cmd(0x60);
    
    //发送行地址
    send_addr(addr&0xff);
    send_addr((addr>>8)&0xff);
    send_addr((addr>>16)&0xff);
    
    //发送命令D0
    send_cmd(0xD0);
    
    //等待RnB
    wait_RnB();
    
    //发送命令0x70
    send_cmd(0x70);
    
    //读取擦除结果
    ret = NFDATA;
    
    //取消选中flash芯片
    deselect_chip();
    
    return ret;
    
}

int NF_WritePage(unsigned long addr,unsigned char *buff)
{
    unsigned int i,ret = 0;
    //选中nandflash
    select_chip();
    
    //清除RnB
    clear_RnB();
    
    //发送0x80命令
    send_cmd(0x80);
    
    //发送2个列地址
    send_addr(0x00);
    send_addr(0x00);
    
    //发送3个行地址
    send_addr(addr&0xff);
    send_addr((addr>>8)&0xff);
    send_addr((addr>>16)&0xff);
    
    //发送数据
        for(i=0;i<2048;i++)
    {
       NFDATA = buff[i];      
    }
    
    //发送0x10命令
    send_cmd(0x10);
    
    //等待RnB
    wait_RnB();
    
    //发送0x70命令
    send_cmd(0x70);
    
    //读取写入结果
    ret = NFDATA;
    
    //关闭nandflash
    deselect_chip();
     return ret;
    
}

2.uart.c

#define GPHCON (*(volatile unsigned long*)0x56000070)
#define ULCON0 (*(volatile unsigned long*)0x50000000)
#define UCON0  (*(volatile unsigned long*)0x50000004)
#define UBRDIV0  (*(volatile unsigned long*)0x50000028)
#define UTRSTAT0 (*(volatile unsigned long*)0x50000010)
#define UTXH0 (*(volatile unsigned long*)0x50000020)
#define URXH0 (*(volatile unsigned long*)0x50000024)

#define PCLK 50000000
#define BAUD 115200

void uart_init()
{
    //1.配置引脚功能
    GPHCON &= ~(0xf<<4);
    GPHCON |= (0xa<<4);
    
    //2.1 设置数据格式
    ULCON0 = 0b11;
    
    //2.2 设置工作模式
    UCON0 = 0b0101; 
    
    //3. 设置波特率    
    UBRDIV0 =(int)(PCLK/(BAUD*16)-1);
}


void putc(unsigned char ch)
{
    while (!(UTRSTAT0 & (1<<1)));
    UTXH0 = ch;  
}


unsigned char getc(void)
{
    unsigned char ret;

    while (!(UTRSTAT0 & (1<<0)));
    // 取数据
    ret = URXH0;  
    
    if ( (ret == 0x0d) || (ret == 0x0a) )
    {
        putc(0x0d);
        putc(0x0a);    
    }          
    else
        putc(ret);
        
        return ret;
}

推荐阅读

史海拾趣

Defense Logistics Agency公司的发展小趣事

Defense Logistics Agency(DLA)于1961年成立,是美国国防部(DOD)的一个独立作战支援机构。在成立初期,DLA就明确了其战略定位:为全球范围内的美军及国防部其他部门提供统一、高效的后勤保障服务。这一战略定位的确立,为DLA的后续发展指明了方向。

ET Enterprises Ltd公司的发展小趣事

在竞争激烈的电子行业中,ET Enterprises Ltd公司始终保持对技术创新的重视。公司不断投入研发资源,推动光电倍增管技术的不断进步。同时,公司也注重人才培养和团队建设,为公司的持续发展提供了有力保障。

Deltron公司的发展小趣事

随着国内市场的不断饱和,Deltron公司开始积极拓展国际市场。通过参加国际展览、与国外企业建立合作关系、设立海外分支机构等方式,Deltron逐渐打开了国际市场的大门。其优质的产品和服务得到了国际客户的认可,为公司的发展注入了新的活力。

Conflux公司的发展小趣事

作为一家具有社会责任感的企业,Conflux始终关注社会公益事业。公司积极参与扶贫、教育等公益活动,为社会做出积极贡献。同时,Conflux还注重环保和可持续发展,通过采用环保材料和节能技术,降低生产过程中的环境污染。这些举措不仅提升了公司的社会形象,也赢得了社会各界的广泛赞誉。

以上五个故事是虚构的,但反映了一个科技公司可能经历的发展阶段和策略选择。在现实中,一个公司的成长和发展往往涉及更多复杂的因素和决策过程。希望这些故事能够为您提供一些启发和参考。

Accuride公司的发展小趣事

在2009年,Accuride公司面临了严重的财务困境,其美国公司申请了破产保护。然而,这一困境并未击垮Accuride,反而成为其重生的契机。通过与债权人达成协议,Accuride成功地将公司的大部分所有权转让给债券持有人,并进行了重组。这一举措不仅缓解了公司的财务压力,还为其未来的发展奠定了坚实的基础。

创世(CS)公司的发展小趣事

创世公司(CS)的创立源于对未来技术趋势的敏锐洞察。在5G、人工智能、物联网等行业还未广泛崛起的初期,创世公司就预见到这些技术将引领未来电子行业的发展。基于这种战略眼光,创世公司决定专注于SD NAND存储产品的研发和生产。这一决策不仅为公司的后续发展奠定了坚实的基础,也展示了创始团队对未来技术趋势的坚定信心。

问答坊 | AI 解惑

天祥 十天学会CPLD FPGA VHDL视频教程(3.12G完整版)

第一讲:主要讲解CPLD系统开发的基本概念,介绍了CPLD和FPGA的各自特点、生产厂家和相应的软件以及开发相关的硬件描述语言。以分频器为例,让大家了解Altera公司的Quartus II软件的基本使用方法和VHDL描述的基本结构。 第二讲:主要以moore状态 ...…

查看全部问答>

关于viper50

关于viper50      我最近用viper50做了一款16.8V2A的恒流恒压电源,恒流恒压功能都不错,可以稳压到2.6A电压都不掉。可是就是viper50的温度过高,不能放入密闭的盒子里面,如果放入密闭的盒子里面,只能够工作20分钟左右viper ...…

查看全部问答>

大家来讨论~也说6410的VGA显示抖动

前两天看见论坛上有一个老帖子讲6410用VGA输出屏幕会抖动的。正好前些日子我正试摄像头采集然后给硬件编解码器编码,也遇到了这个问题,不过已经稀里糊涂的解决了,希望大家针对如下问题来讨论。 看那个帖子上说,这是“ram总线竞争”导致。那么大 ...…

查看全部问答>

如何设置驱动线程的优先级?

平台:S3C2440 + WINCE5.0 驱动使用中断EINT0和EINT5,大概20ms就一个中断,来了中断后就在IST中从3根GPIO口线读取300Bytes的数据 测试发现,在Wince有其他操作时,驱动IST中接收的数据会随机出现误码或者0,在IST中增加了计数器,测得中断是每次 ...…

查看全部问答>

控制AD0809的时候为什么要加反相器?

控制AD0809的时候为什么要加反相器? 或者要加与非门控制? 为什么不能直接设置为相应的逻辑值…

查看全部问答>

【连载】【ALIENTEK MiniSTM32 开发板】STM32不完全手册--跑马灯实验(实验一)

ALIENTEK开发板购买地址:http://shop62103354.taobao.com/     [ 本帖最后由 正点原子 于 2010-8-30 09:31 编辑 ]…

查看全部问答>

stm8指令执行周期需要几个系统时钟?

stm8 指令执行周期需要几个系统时钟? 有没有 DEMO 汇编代码?…

查看全部问答>

有关于编程的一个问题

各位大虾:我如果要编一个AD采样程序,除了和AD相关的操作外,对系统要做那些工作?要初始化那些寄存器??比如选CPU时钟?…………………

查看全部问答>

为什么ti送给了我两块一样的开发板lm3s8962.有一块还没拆。想换fpga开发板

想换fpga开发板。做视频开发用,fpga最好有sdram电话:18994047269…

查看全部问答>

梦之旅同学松鼠1.0学习笔记(四)之UART

1.     1.     串口的基本概念 在STM32的参考手册中,串口被描述成通用同步异步收发器(USART),它提供了一种灵活的方法与使用工业标准NRZ异步串行数据格式的外部设备之间进行全双工数据交换。USART利用 ...…

查看全部问答>