zoukankan      html  css  js  c++  java
  • nandflash的读写(2440)

    说明:

    根据物理结构上的区别 , 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;
    }

  • 相关阅读:
    python基础 2
    python基础 1
    进程
    进程作业
    上海python14期第二次阶段性考试
    面向对向之元类
    面向对向
    笔试题
    模块(2)
    模块作业
  • 原文地址:https://www.cnblogs.com/wxb20/p/6256987.html
Copyright © 2011-2022 走看看