Nand flash

2023-11-17

一、需要什么

我们的目的是编写Nand Flash 的裸机代码,可以读写Nand Flash, 那么我们应该从哪开始呢。
以我为例,我板子上的cpu 是时s5pv210, 板子上的nand flash的芯片是1Gbyte 的 NAND FLASH(K9K8G08U0B)。
我们要做的事:

  1. 仔细阅读K9K8G08U0B的芯片手册,了解基本知识。
  2. s5pv210 内部已经集成了nand flash的控制器,所以我们只需要阅读s5pv210芯片手册的Nand Flash控制器那部分就可以了。

二、K9K8G08U0B 基本信息

NAND Flash的数据是以bit的方式保存在memory cell,一般来说,一个cell 中只能存储一个bit(即SLC类型的NAND)。这些cell 以8个或者16个为单位,连成bit line,形成所谓的byte(x8)或word(x16),这就是NAND Device的位宽。这些Line会再组成Page,(NAND Flash有多种结构,以NAND Flash是K9F1208为例,下面内容针对三星的K9F1208U0M),每页528Bytes(512byte(Main Area)+16byte(Spare Area)),每32个page形成一个Block(32528B)。具体一片flash上有多少个Block视需要所定。使用的三星k9f1208U0M具有4096个block,故总容量为4096(32*528B)=66MB,但是其中的2MB是用来保存ECC校验码等额外数据的,故实际中可使用的为64MB。
NAND flash以页为单位读写数据,而以块为单位擦除数据。按照这样的组织方式可以形成所谓的三类地址:Column Address(Starting Address of the Register)列地址,地址的低8位;Page Address:页地址;  Block Address:块地址;对于NAND Flash来讲,地址和命令只能在I/O[7:0]上传递,数据宽度是8位。

NAND Flash地址的表示:
512byte需要9bit来表示,对于512byte系列的NAND,这512byte被分成1st half Page Register和2nd half Page Register,各自的访问由地址指针命令来选择,A[7:0]就是所谓的column address(列地址),在进行擦除操作时不需要用到它,为什么?因为是以块为单位擦除;32个page需要5bit来表示,占用A[13:9],即该 page在块内的相对地址。A8这一位地址被用来设置512byte的1st half page还是2nd half page,0表示1st,1表示2nd;Block的地址是由A14以上的bit来表示。
例如64MB(512Mb)的NAND flash(实际中,由于存在spare area,故都大于这个值),共4096block,因此,需要12个bit来表示,即A[25:14];如果是128MB(1Gbit)的528byte/page的NAND Flash,则block address用A[26:14]表示。而page address就是blcok address | page address in block。NAND Flash的地址表示为:Block Address|Page Address in block|halfpage pointer|Column Address。地址传送顺序是Column Address,Page Address,Block Address。
由于地址只能在I/O[7:0]上传递,因此,必须采用移位的方式进行。例如,对于512Mbit x8的NAND flash,地址范围是0~0x3FF_FFFF,只要是这个范围内的数值表示的地址都是有效的。以发NAND_ADDR 为例:
第1步是传递column address,就是NAND_ADDR[7:0],不需移位即可传递到I/O[7:0]上,而halfpage pointer即A8,是由操作指令决定的,即指令决定在哪个halfpage 上进行读写,因此真正的A8的值是不需程序员关心的;
第2步就是将NAND_ADDR右移9位,将NAND_ADDR[16:9]传到I/O[7:0]上;
第3步将NAND_ADDR[24:17]放到I/O上;
第4步将NAND_ADDR[25]放到I/O上;
因此,整个地址传递过程需要4步才能完成,即4-step addressing。如果NAND Flash的容量是32MB(256Mbit)以下,那么,block adress最高位只到bit24,因此寻址只需要3步。(具体参考芯片手册)
下面,就x16的NAND flash器件稍微进行一下说明。由于一个page的main area的容量为256word,仍相当于512byte。但是,这个时候没有所谓的1st halfpage和2nd halfpage之分了,所以,bit8就变得没有意义了,也就是这个时候,A8完全不用管,地址传递仍然和x8器件相同。除了这一点之外,x16的NAND使用方法和x8的使用方法完全相同。

从芯片手册得知:
1).每页 = 2112Bytes(2048byte(Main Area)+64byte(Spare Area));
2).每块 = 64页;
3).一共8192块;

问:既然得知了该芯片的大小,那么列地址,页内地址,块地址应该分别是多少位呢?为什么?
答:
1).A0~A11表示列地址,因为2的12次方等于4K,但是硬件只有2K,所以发地址的时候,要不A11给舍弃了;
2).A12-A17是页地址,因为2的6次方刚好等于64;
3).A18到A28是块地址;

问:那么地址是怎么发送出去的呢?
答:步骤如下:
第1步是传递column address,就是NAND_ADDR[7:0],不需移位即可传递到I/O[7:0]上;
第2步任然传的是列地址,但是由于每页只有2K,故要对地址做以下操作:
(addr>>8) & 0x7 /* 右移8位,就是为了去掉第八位的地址,因为已经在第一步发出了,与上0x7,是为了只保留A8~A10,即上文所说的舍弃A11 */
第3步就是将NAND_ADDR右移11位,将NAND_ADDR[19:12]传到I/O[7:0]上;
第4步将是将NAND_ADDR右移19位,将NAND_ADDR[27:20]放到I/O上;
第5步将是将NAND_ADDR右移27位,将NAND_ADDR[28]放到I/O上;

三、s5pv210 nand flash 控制器

在这里我们不使用ECC, 所以比较简单,只需要配置几个寄存器就可以了。
NandFlash 配置寄存器:NFCONF
NandFlash 控制寄存器:NFCONT
NandFlash 命令寄存器:NFCMMD
NandFlash 地址寄存器:NFADDR
NandFlash 数据寄存器:NFDATA
NandFlash 状态寄存器:NFSTAT

四、编写代码

  1. 初始化s5pv210 nand flash 控制器
    在这里插入图片描述
    NFCONF寄存器:
    AddrCycle = 1,When page size is 2K or 4K, 1 = 5 address cycle,Mini210S的NAND Flash的页大小为2k,所有是5个地址周期;
    PageSize = 0,When MLCFlash is 0, the value of PageSize is as follows: 0 = 2048 Bytes/page,Mini210S使用的是SLC NAND Flash且每页大小为2k;
    MLCFlash = 0,在此使用的是SLC NAND Flash;
    TWRPH1/TWRPH0/TACLS是关于访问时序的设置,需对照NAND Flash芯片手册设置,这里不再详细解释,分别取TWRPH1=1,TWRPH0=4,TACLS=1;
    ECCType0/MsgLength,我们的裸机代码没有使用到ECC,所有不用设置这两个标志。
    在这里插入图片描述
    在这里插入图片描述
    MODE = 1,使能NAND Flash控制器;
    Reg_nCE0 = 1,取消片选,需要操作NAND Flash时再发片选;
    Reg_nCE1 = 1, 取消片选,需要操作NAND Flash时再发片选;
    InitMECC/InitSECC/SECCLock/MECCLock,我们的裸机代码不涉及ECC,这4个标志位随便设置即可;
    RnB_TransMode = 0,Detect rising edge,RnB是NAND Flash的状态探测引脚,我们使用上升沿触发;
    EnbRnBINT = 0 ,禁止RnB中断;
    EnbIllegalAccINT = 0,禁止Illegal access 中断 ;
    EnbMLCDecInt/EnbMLCEncInt为MCL相关,不用设置;
    LOCK = 0,我们没有用到Soft Lock,所以禁止Soft Lock;
    LockTight = 0,我们没有用到Lock-tight,所有禁止Lock-tight;
    MLCEccDirection,MLC相关,可不用设置。

我们还需要配置GPIO来支持Nand Flash, 这里不多讲。只需要查看原理图,配置对应的GPIO口复用就行了。

void nand_init()
{
    // SLC / 2048B / 5 address cycle
    NFCONF = (0 << 0) | (1 << 1) | (0 << 3) | (0 << 4)
            | (TWRPH1 << 4) | (TWRPH0 << 8) | (TACLS << 12);
    NFCONT = (1 << 0) | (0x3 << 1) | (0 << 8) | (0 << 9)
            | (0 << 10) | (0 << 16) | (0 << 17) | (0x3 << 22);

    // 设置
    MP0_1CON &= ~(0xF << 8 | 0xF << 12);
    MP0_1CON |=  (0x3 << 8 | 0x3 << 12);

    // 设置引脚0、1、2、3、4分别为 NF_CLE,NF_ALE, NF_FWEn,NF_FREn,NF_RnB[0]
    MP0_3CON &= ~(0xFFFFF);
    MP0_3CON |= 0x22222;

    nand_reset();
}
  1. nand flash芯片复位
    在这里插入图片描述
    很简单,只要发生命令0xFF就可以了
void nand_reset()
{
    nand_select_chip(); // 发片选
    nand_send_cmd(NAND_CMD_RESET);
    nand_wait_idle();   // 
    nand_deselect_chip(); // 取消片选
}

  1. 发命令、读数据、写数据
void nand_send_cmd(unsigned char cmd)
{
    NFCMMD = cmd;
}

unsigned char nand_read()
{
    return NFDATA;
}

void nand_write(unsigned char c)
{
    NFDATA = c;
}

  1. 读芯片ID
    在这里插入图片描述
void nand_read_id(nand_info_t *id_info)
{                                
    nand_select_chip(); // 发片选
    nand_send_cmd(NAND_CMD_READ_ID); // 发命令
    nand_send_addr(0x00); // 发地址
    nand_wait_idle();     // 等待就绪
    id_info->IDm = nand_read();  // 读数据
    id_info->IDd = nand_read();  // 读数据
    id_info->ID3rd = nand_read();
    id_info->ID4th = nand_read();
    id_info->ID5th = nand_read();
                                 
    nand_deselect_chip();        // 取消片选
}     
  1. 发送地址

首先根据页大小来获取页地址和页内偏移地址,然后通过 5 个周期将地址发送出去,实质就是写NFADDR 寄存器,具体每个周期如何发送,查阅 NAND Flash 芯片手册可知,见下图:
在这里插入图片描述

void nand_send_addr(unsigned long addr)
{
    int i;
    unsigned long row, col;

    // 计算出行地址,也就是哪一页
    row = addr / NAND_PAGE_SIZE;
    // 计算出列地址,也就是页地址
    col = addr % NAND_PAGE_SIZE;

    // 1st 发送列地址低8位
    NFADDR = (col & 0xFF);
    for(i = 0; i < 10; i++);

    // 2st 发送列地址低9-12位
    NFADDR = ((col >> 8) & 0xF);
    for(i = 0; i < 10; i++);

    // 3st 发送行地址低8位
    NFADDR = (row & 0xFF);
    for(i = 0; i < 10; i++);

    // 4st 发送行地址低9-16位
    NFADDR = ((row >> 8) & 0xFF);
    for(i = 0; i < 10; i++);

    // 5st 发送行地址低17-19位
    NFADDR = ((row >> 16) & 0x7);
    for(i = 0; i < 10; i++);
}
  1. 读Nand Flash 状态寄存器
    在这里插入图片描述
unsigned char nand_read_status()
{
    int i;
    unsigned char ch; 
    nand_select_chip();          // 发片选
    nand_send_cmd(NAND_CMD_READ_STATUS); // 发命令
    for (i = 0; i < 10; i++);            
    ch = nand_read();                    // 读数据
    nand_deselect_chip();                // 取消片选
    return ch;                           
} 
  1. 擦除Nand Flash 某个块
    在这里插入图片描述
int nand_erase_block(unsigned int block)
{                                       
    int i;                              
    unsigned long row;                  
    unsigned char st;                   
                                        
    // 得到行地址,就是哪个页           
    row = block * NAND_PAGE_SIZE;       
                                        
    nand_select_chip();         // 发片选
    nand_send_cmd(NAND_CMD_ERASE_1st); // 发命令60H
                                        
    // 分3clcye写地址                   
    NFADDR = (row & 0xFF);              
    for (i = 0; i < 10; i++);           
    NFADDR = ((row >> 8) & 0xFF);       
    for (i = 0; i < 10; i++);           
    NFADDR = ((row >> 16) & 0x7);       
    for (i = 0; i < 10; i++);           
                                        
    nand_send_cmd(NAND_CMD_ERASE_2st); // 发命令D0H
    nand_wait_idle();                   
                                        
    st = nand_read_status();            // 读状态
    if (st & 1) {
        nand_deselect_chip();
        return -1;
    }
    nand_deselect_chip();
    return 0;
}
  1. 顺序读Nand Flash 数据
// TODO
  1. 顺序写数据到Nand Falsh
// TODO
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Nand flash 的相关文章

  • 开发 ARM 处理器需要什么? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我熟悉 X86 64 架构和汇编 我想开始开发 ARM 处理器 但与桌面处理器不同的是 我没有真正的
  • 除了提供必要的保证之外,硬件内存屏障是否还能使原子操作的可见性更快?

    TL DR 在生产者 消费者队列中 放置不必要的 从 C 内存模型的角度来看 内存栅栏或不必要的强内存顺序是否有意义 以牺牲可能更差的吞吐量为代价获得更好的延迟 C 内存模型在硬件上执行 通过为更强的内存顺序设置某种内存栅栏 而不是在较弱的
  • 中断的尾链

    什么是 ARM Cortex M3 中 NVIC 支持的中断尾链 尾链是异常的背对背处理 无需 中断之间的状态保存和恢复的开销 这 处理器跳过八个寄存器的弹出操作和八个寄存器的压入操作 当退出一个 ISR 并进入另一个 ISR 时 因为这没
  • STM32内部时钟

    我对 STM32F7 设备 意法半导体的 Cortex M7 微控制器 上的时钟系统感到困惑 参考手册没有充分阐明这些时钟之间的差异 SYSCLK HCLK FCLK 参考手册中阅读章节 gt RCC 为 Cortex 系统定时器 SysT
  • 对 -finstrument-functions 的未定义引用

    我正在尝试跟踪内核函数并且我正在使用 finstrument functions这样做 但我收到未定义的参考错误 如下所示 arch arm kernel elf c 9 undefined reference to cyg profile
  • arm gcc工具链为arm-elf或arm-none-eabi,有什么区别?

    当您构建 gcc 工具链时 可以将其构建为arm elf 或arm none eabi 但是有什么区别呢 我今天使用 eabi 但这只是因为其他人似乎都这样做 但由于这是一个非常糟糕的论点 因此理解其中的差异真的很高兴 注意 此工具链将为基
  • GNU Arm Cortex m4 上的 C++ 异常处理程序与 freertos

    2016 年 12 月更新现在还有一个关于此行为的最小示例 https community nxp com message 862676 https community nxp com message 862676 我正在使用带有 free
  • 适用于arm(cortex-m3)的位置独立可执行文件(-pie)

    我正在使用codesourcery g lite 基于gcc4 7 2版本 为stm32 Cortex m3 编程 我希望动态加载可执行文件 我知道我有两个选择 1 可重定位的elf 需要一个elf解析器 2 具有全局偏移寄存器的位置无关代
  • 使用 gnueabihf 为 ARMv6 构建

    我尝试为 ARMv6 构建应用程序 但失败了 我猜问题是工具链支持硬浮点 但 ARMv6 不支持 好吧 首先我设置 march armv6 编译失败 opt gcc linaro arm linux gnueabihf 4 8 2014 0
  • ARM Neon:如何从 uint8x16_t 转换为 uint8x8x2_t?

    我最近发现了关于vreinterpret q dsttype src类型转换运算符 https stackoverflow com a 43519190 2436175 但是 这似乎不支持所描述的数据类型的转换这个链接 http infoc
  • ARM Linux 如何模拟 PTE 的脏位、访问位和文件位?

    As per pgtable 2 level h https git kernel org cgit linux kernel git torvalds linux git tree arch arm include asm pgtable
  • RAM 存储二进制数和汇编语言的冒泡排序

    我必须使用 ARM v7 执行一个例程 在 RAM 内存中存储 10 个二进制数 然后使用冒泡排序对这些数字从高到低进行排序 我应该如何开始 func bubbleSortAscendingU32 ldr r3 r0 4 mov r1 9
  • GCC ARM 汇编预处理器宏

    我正在尝试使用汇编 ARM 宏进行定点乘法 define MULT a b asm volatile SMULL r2 r3 0 1 n t ADD r2 r2 0x8000 n t ADC r3 r3 0 n t MOV 0 r2 ASR
  • 为 ARM 交叉编译 zlib

    我尝试为arm poky linux gnueabi交叉编译zlib 但启动 make 时出现错误 zlib 1 2 11 AR HOST ar CC HOST gcc RANLIB HOST ranlib configure prefix
  • M1 MacBook Pro 上的 Android Studio 无法使用 ABI armeabi-v7a 模拟系统映像

    我的 M1 Macbook Pro 上的 Android Studio 可以很好地模拟 ABI arm64 v8a 的所有系统映像 API 24 29 30 31 但是 它无法使用 ABI armeabi v7a 运行所有映像 例如 API
  • 有没有办法在 Xcode 4 中为 ARM 而不是 Thumb 进行编译?

    如果有很多浮点运算正在进行 Apple 建议针对 ARM 进行编译 而不是针对拇指进行编译 我的整个应用程序几乎是一个大型浮点运算 iOS 应用程序开发工作流程指南中是这样说的 iOS 设备支持两种指令集 ARM 和 Thumb Xcode
  • 在linux x86平台上学习ARM所需的工具[关闭]

    Closed 此问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我有一个 x86 linux 机器 在阅读一些关于 ARM 的各种信息时 我很好奇 现在我想花一些时间学
  • 为什么当大小大于 50 时,该程序花费的时间会呈指数级增长?

    所以我正在为类编写一个 ARM 汇编快速排序方法 我对大部分内容都有了解 除了复杂性没有意义 我们将其与我们制作的另一种冒泡排序方法进行比较 它对于具有 1 个参数和 10 个参数的示例表现更好 然而 我什至无法比较 100 个参数测试 因
  • 基于 Windows 8 ARM 的平板电脑上的 VB6

    随着 Windows 8 将支持 VB6 我的问题是 Microsoft 是否在任何地方表示 是或否 VB6 应用程序将在基于 ARM 的平板电脑上运行 如果没有 是否有任何 ARM 模拟器 以便我们可以在 Windows 8 ARM 平板
  • DS-5:什么是 FVP、RTSM、基础模型、AEM 模型、快速模型、CADI?

    DS 5 模拟器使用了很多术语 如 FVP RTSM 快速模型 基础模型 AEM 模型 CADI Arm的文档中提供的解释不是很清楚 这些术语的含义是什么 作为 DS 5 的最终用户我应该关心哪些术语 Model 软件模拟的行业术语 就 A

随机推荐

  • rabbitmq 安装

    文章目录 RabbitMQ 安装 erlang安装 RabbitMQ安装 环境变量 管理界面 添加用户 配置允许远程访问的用户 未验证 RabbitMQ 安装 erlang安装 http www erlang org downloads R
  • 鼠标、键盘、窗口监听事件

    一 画笔paint 画笔 public class TestPaint public static void main String args new MyPaint loadFrame class MyPaint extends Fram
  • openwrt路由器(RP-LINK)安装python并设置开机启动程序

    由于项目需求 实际条件限制 需要在某台设备上运行一个python小程序 在工业机器人和云服务器之间实现信息转发的功能 因为机器人也需要通过路由器认证连接校园网 出于简化设备的考虑 不想每次跑程序还得开电脑 我决定尝试在路由器上运行这个程序
  • js时间戳与日期格式的转换

    1 将时间戳转换成日期格式 function timestampToTime timestamp 时间戳为10位需 1000 时间戳为13位不需乘1000 var date new Date timestamp 1000 var Y dat
  • 软件测试用例设计之因果图

    软件测试用例设计之因果图 自动贩卖机功能测试 若投入5角钱或1元钱的硬币 押下 橙汁 或 啤酒 的按钮 则相应的饮料就送出来 若售货机没有零钱找 则一个显示 零钱找完 的红灯亮 这时在投入1元硬币并押下按钮后 饮料不送出来而且1元硬币也退出
  • char* buf和char buf[64],定义两种字符串作为参数传递给函数的区别

    问题描述 最近在项目中遇到了一个让人疑惑的问题 有一个发送函数需要传递void 类型的参数 我定义了char buf abcdefg 然后将buf作为参数传递给了这个发送函数 但是函数返回值显示发送成功 但是另一端没有接收到数据 查找了好久
  • WEB服务器和应用服务器有什么区别

    author skate time 2009 12 04 俗的讲 Web服务器传送 serves 页面使浏览器可以浏览 然而应用程序服务器提供的是客户端应用程序可以调用 call 的方法 methods 确切一点 你可以说 Web服务器专门
  • 部署MES管理系统首先要解决什么问题

    随着制造业市场竞争的加剧 企业需要更加高效 灵活的生产运营 以提高产品质量和降低成本 在这种情况下 MES管理系统解决方案成为许多企业的选择 然而 在部署MES管理系统之前 必须首先解决一些关键问题 以确保系统的成功实施 本文将探讨部署ME
  • C和C++中的结构体

    解释一 C C 结构体的区别 C中的结构体和C 中结构体的不同之处 在C中的结构体只能自定义数据类型 结构体中不允许有函数 而C 中的结构体可以加入成员函数 C 中的结构体和类的异同 一 相同之处 结构体中可以包含函数 也可以定义publi
  • 基于Rancher实现kubernetes集群管理

    基于Rancher实现kubernetes集群管理 1 Rancher介绍 2 Rancher部署 添加kubernetes集群 3 Rancher简单操作 1 Rancher介绍 Rancher可以通过图形化操作的方式管理kubernet
  • JAVA利用HttpClient进行POST请求(HTTPS)

    目前 要为另一个项目提供接口 接口是用HTTP URL实现的 最初的想法是另一个项目用JQuery post进行请求 但是 很可能另一个项目是部署在别的机器上 那么就存在跨域问题 而JQuery的post请求是不允许跨域的 这时 就只能够用
  • 逆水寒跑商时服务器维护,逆水寒跑商路线推荐 合适的路线让你事半功倍

    逆水寒跑商路线推荐 帮会跑商可以赚到大量的财富 因为跑商比较浪费时间也比较危险 所以我们需要研究一条比较合理的路线 这样对于各位镖师来说才是最省时省力的方法 汴京 菊花酒 杭州 贸易信息 木板年画 宋辽边境 磁州 3000以下 贸易信息赚更
  • Linux学习笔记(九) -- 利用Code::Blocks建立C++静态链接库

    1 测试平台 测试平台 Linux版本 Ubuntu 18 04 LTS Code Blocks版本 16 01 2 操作步骤 2 1 启动Code Blocks 2 2 新建静态链接库工程 1 选择 File 菜单中的 New Proje
  • 总结:nn.Module的children()与modules()方法、如何获取网络的某些层

    一 nn Module的children 方法与modules 方法的区别 children 与modules 都是返回网络模型里的组成元素 但是children 返回的是最外层的元素 modules 返回的是所有的元素 包括不同级别的子元
  • osg学习(三十九)DisplaySettings

    DisplaySettings是osg的全局单实例变量 类似osg的Registry 主要记录窗口的一些显示设置 比如窗口尺寸 多重纹理采样数 着色器设置等 osg在创建窗口时会从该变量中读取信息 这个变量中的信息可以通过命令行输入也可以通
  • 2023Matlab初级教程- 第二章 Matlab 基础运算及函数、数据类型

    第二章 Matlab 基础运算及函数 数据类型 文章目录 第二章 Matlab 基础运算及函数 数据类型 前言 一 基础运算 二 基础函数 1 基础函数 2 练习 三 数据类型 3 1特殊变量 3 2调用优先级 3 3 1数组 3 3 2结
  • 转码日记——Javascript笔记(4)

    对象 引用数据类型 基本数据类型的不足 基本数据类型都是单一的值 值和值之间没有任何联系 如果只使用基本数据类型 那么创建的变量都是独立的个体 不能成为一个整体 对象属于复合的数据类型 在对象中可以保存多个不同数据类型的属性 分类 1 内建
  • 21份软件测试全流程文档模板(标准版)

    1 需求说明书 2 功能测试计划 3 功能测试用例 4 业务流程测试用例 5 系统安装配置说明书 6 阶段功能测试报告 7 性能测试计划 8 性能测试用例 9 性能测试报告 10 系统功能测试报告 11 需求变更说明书 12 用户建议说明书
  • VS中C语言调Fortran,急急急!哪位大哥能帮我一下,把以下FORTRAN语言的程序转换成C语言...

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 PROGRAM MAIN IMPLICIT NONE INTEGER I NUM NMAX M MB ME MS PN PARAMETER NMAX 2000 parameter PN 1500
  • Nand flash

    一 需要什么 我们的目的是编写Nand Flash 的裸机代码 可以读写Nand Flash 那么我们应该从哪开始呢 以我为例 我板子上的cpu 是时s5pv210 板子上的nand flash的芯片是1Gbyte 的 NAND FLASH