NOR FLASH_MX29LV160DBTI

  1. NOR flash带有SRAM接口,有足够的地址引脚来寻址,可以很容易地存取其内部的每一个字节。

  2. NOR flash是只读存储器,可以轻易的读,却不能够轻易的写。写NOR FLASH需要一些特定的命令。

  3. MX29LV160DBTI NOR flash有21位地址线接口,16 位数据线接口。

  4. NOR flash的容量一般都比较小,一般常见最大的也就只有32M.

  5. NOR flash一般用来存一下内核,关键性的程序。

    MX29LV160DBTI的原理图如下
    以上图为例来写一些基本的底层代码
    注意:由上图可知CPU的A1接的是NOR FALSH的A0,所以在一些地址数据传输上需要注意一些地址的移位!

写出一些基本的指令传送,地址传送,数据传送的函数

#define NOR_FLASH_BASE  0  //根据你的NOR FALSH与CPU连接,片选信号而定,由于我的NOR FLASH片选信号接的是nGCS0,所以基地址为0void nor_write_word(unsigned int FLASH_base, unsigned int offset, unsigned int val) //向一个基本地址为FLASH_base的NORFALSH的offset地址写入data数据
{volatile unsigned short *p = (volatile unsigned short *)(NOR_FLASH_BASE  + (offset << 1));    //定义一个双字节指针P*p = val;
}
void nor_write(unsigned int offset, unsigned int data) //向一个NORFALSH的地址写入data数据
{nor_write_word(NOR_FLASH_BASE, offset, data);
}
unsigned int nor_read_word(unsigned int base, unsigned int offset)  //向一个基地址为base的NORFALSH的offset地址读出数据
{volatile unsigned short *p = (volatile unsigned short *)(base + (offset << 1));return *p;
}unsigned int nor_dat(unsigned int offset)//向NORFALSH的offset地址读出数据
{return nor_read_word(NOR_FLASH_BASE, offset);
}

了解NOR FLASH 的命令操作

我们可以根据数据手册查看NOR FLASH 的一般命令操作。(擦除,写,读,进入CFI模式等)

由上图可知,如果想要访问芯片的厂家ID,我们需要4周期的命令才可以访问出数据。
同理设备ID也需要四个周期的命令才可以访问出数据。可知道我们芯片设备ID为22C4。

进入NOR FLASH的CFI模式进行查询

我们可以根据NOR FLASH的数据手册,得到如何去查看厂家ID以及其他有关芯片的资料。(例如有多少个region,每个region含有多少个block,每个block有多大)。



以下就是查看NOR_FLASH 一些基本数据的代码:

void check_nor_flash(void)
{char str[4];unsigned int size;int regions, i;int region_info_base;int block_addr, blocks, block_size, j;int cnt;int vendor, device;//打印厂家ID、设备IDnor_cmd(0x555, 0xaa);    //解锁nor_cmd(0x2aa, 0x55); nor_cmd(0x555, 0x90);    //read id vendor = nor_dat(0);device = nor_dat(1);nor_cmd(0, 0xf0);        //reset nor_cmd(0x55, 0x98);  //进入cfi模式 str[0] = nor_dat(0x10);str[1] = nor_dat(0x11);str[2] = nor_dat(0x12);str[3] = '\0';printf("str = %s\n\r", str); //打印进入CFI模式的QRY//打印容量size = 1<<(nor_dat(0x27));printf("vendor id = 0x%x, device id = 0x%x, nor size = 0x%x, %dM\n\r", vendor, device, size, size/(1024*1024));//打印各个扇区的起始地址/* 名词解释:*    erase block region : 里面含有1个或多个block, 它们的大小一样* 一个nor flash含有1个或多个region* 一个region含有1个或多个block(扇区)* Erase block region information:*    前2字节+1    : 表示该region有多少个block *    后2字节*256  : 表示block的大小*/regions = nor_dat(0x2c);region_info_base = 0x2d;block_addr = 0;printf("Block/Sector start Address:\n\r");cnt = 0;for (i = 0; i < regions; i++){blocks = 1 + nor_dat(region_info_base) + (nor_dat(region_info_base+1)<<8);block_size = 256 * (nor_dat(region_info_base+2) + (nor_dat(region_info_base+3)<<8));region_info_base += 4;for (j = 0; j < blocks; j++){/* 打印每个block的起始地址 *///printf("0x%08x ", block_addr);printHex(block_addr);putchar(' ');cnt++;block_addr += block_size;if (cnt % 5 == 0)printf("\n\r");}}printf("\n\r");/* 退出CFI模式 */nor_cmd(0, 0xf0);
}

进行NOR FLASH的读数据操作

void read_nor_flash(void)
{unsigned int addr;volatile unsigned char *p;int i, j;unsigned char c;unsigned char str[16];/* 获得地址 */printf("Enter the address to read: ");addr = get_uint();p = (volatile unsigned char *)addr;printf("Data : \n\r");/* 长度固定为64 */for (i = 0; i < 4; i++){/* 每行打印16个数据 */for (j = 0; j < 16; j++){/* 先打印数值 */c = *p++;str[j] = c;printf("%02x ", c);}printf("   ; ");for (j = 0; j < 16; j++){/* 后打印字符 */if (str[j] < 0x20 || str[j] > 0x7e)  //不可视字符一律打印... putchar('.');elseputchar(str[j]);}printf("\n\r");}
}

结果如下:(下面应该是我打印的地址为0的第一块的数据,也就是程序由GCC编译器编译的最开始的汇编代码)

NOR FLASH的繁忙状态位

当我们在进行一些擦除或写操作时,NOR FALSH的擦写是需要时间的,我们可以根据等待状态位来判断是否擦除完成!芯片手册如下:



我们可以从芯片手册得知,当我在进行擦除和写操作时,数据位bit6一直在0和1之间切换(Toggling)
故可以根据这一特性写出一个等待擦除或写入完成的函数。

void wait_ready(unsigned int addr)
{unsigned int val;unsigned int pre;pre = nor_dat(addr>>1);val = nor_dat(addr>>1);while ((val & (1<<6)) != (pre & (1<<6))){pre = val;val = nor_dat(addr>>1);      }
}

进行NOR FLASH的擦除数据的操作

这里一定要注意硬件与NOR FLASH 的连接方式,因为之前的offset地址是基于NOR FLASH 的角度出发的
现在的地址是基于CPU的角度看到的,所以地址要右移1位!!!(CPU的A1 接的是NOR FLASH的A0 )

void erase_nor_flash(void)
{unsigned int addr;/* 获得地址 */printf("Enter the address of sector to erase: ");addr = get_uint();printf("erasing ...\n\r");nor_cmd(0x555, 0xaa);    /* 解锁 */nor_cmd(0x2aa, 0x55); nor_cmd(0x555, 0x80);  /* erase sector */nor_cmd(0x555, 0xaa);    /* 解锁 */nor_cmd(0x2aa, 0x55); nor_cmd(addr>>1, 0x30);  /* 发出扇区地址 地址要右移一位 */wait_ready(addr);
}

进行NOR FLASH的写入数据的操作

void write_nor_flash(void)
{unsigned int addr;unsigned char str[100];int i, j;unsigned int val;/* 获得地址 */printf("Enter the address of sector to write: ");addr = get_uint();printf("Enter the string to write: ");gets(str);printf("writing ...\n\r");/* str[0],str[1]==>16bit * str[2],str[3]==>16bit */i = 0;j = 1;while (str[i] && str[j]){val = str[i] + (str[j]<<8);/* 烧写 */nor_cmd(0x555, 0xaa);   /* 解锁 */nor_cmd(0x2aa, 0x55); nor_cmd(0x555, 0xa0);     /* program */nor_cmd(addr>>1, val);/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */wait_ready(addr);i += 2;j += 2;addr += 2;}val = str[i];/* 烧写 */nor_cmd(0x555, 0xaa);  /* 解锁 */nor_cmd(0x2aa, 0x55); nor_cmd(0x555, 0xa0);     /* program */nor_cmd(addr>>1, val);/* 等待烧写完成 : 读数据, Q6无变化时表示结束 */wait_ready(addr);
}

以上就是我对NOR FLASH 的所有总结了!!!
我采用的NOR FLASH 型号就是MX29LV160DBTI,容量为2M,有4个区域,每个区域有块,由于每个区域的块的数量是不一样的,我也没有认真去看(浪一下~~)。

第一篇博客就写完了!!可能有一些不足的地方,希望大神的批评和指导!!!

底层嵌入式之NOR FLASH编程相关推荐

  1. 使用 Trace32 对 FLASH 编程

    from:   http://www.ibm.com/developerworks/cn/linux/l-trace32/ 随着软硬件复杂性的增加,在嵌入式系统开发中,调试器对项目的开发进度.质量起着 ...

  2. 关于linux下的嵌入式文件系统以及flash文件系统选择(转)

    嵌入式linux下常见的文件系统 • RomFS:只读文件系统,可以放在ROM空间,也 可以在系统的RAM中,嵌入式linux中常用来作 根文件系统 • RamFS:利用VFS自身结构而形成的内存文件 ...

  3. 掌财社:新手学习嵌入式用什么语言编程?

    随着AI智能产品的出现,市场上对于嵌入式开发人员需求也越来越多,嵌入式系统成为了一个很时尚的名词,应用范围也相当的广泛,很多人都想入行嵌入式,那么,学习嵌入式用什么语言编程?这个对于新手来说是一个比较 ...

  4. 嵌入式C开发中编程模型——重点事件驱动和表驱动

    嵌入式C开发中编程模型 事件驱动 消息驱动 事件驱动vs消息驱动 数据驱动 1. 表驱动法(Table-Driven) 用表驱动法来实现 Unix设计原则中的"分离原则"和&quo ...

  5. 使用 Trace32 对 FLASH 编程摘要及Trace32-ICD和Trace32-ICE的区别

    使用 Trace32 对 FLASH 编程 https://safrans.blog.csdn.net/article/details/8544901 转来比较麻烦,原文阅读效果更好 摘要内容: 介绍 ...

  6. java虚拟机线程调优与底层原理分析_Java并发编程——多线程的底层原理

    " Java代码在编译后会变成Java字节码,字节码被类加载器加载到JVM里,JVM执行字节码,最终需要转化为汇编指令在CPU上执行,Java中所使用的并发机制依赖于JVM的实现和 CPU的 ...

  7. 嵌入式C语言编程课件,嵌入式系统C语言编程基础PPT课件

    <嵌入式系统C语言编程基础PPT课件>由会员分享,可在线阅读,更多相关<嵌入式系统C语言编程基础PPT课件(81页珍藏版)>请在人人文库网上搜索. 1.嵌入式系统C语言编程基础 ...

  8. C语言获取norflash大小,NOR Flash 编程

    NOR Flash 编程1//************************************************************************************* ...

  9. NAND FLASH编程器烧录详解

    NAND FLASH编程器_NAND FLASH烧录器 SUPERPRO5000是西尔特出品的新一代USB接口独立式智能极速NAND FLASH编程器.具有编程速度快,烧录稳定,软件集成度高,更智能化 ...

最新文章

  1. 区分HPUX是Itanium还是PA-RISC
  2. 身体有恙,此段时间BLOG暂停更新
  3. c++ map初始化同时赋值_Golang入门教程——map篇
  4. 从踩坑到填坑|淘宝Web 3D应用与游戏开发实战
  5. Javascript中的事件对象和事件源
  6. 马云透露:未来10大行业即将消失!
  7. 电脑键盘部分按键失灵_键盘按键失灵别担心 电脑达人教你几步解决方法
  8. 什么是容器服务_即学即用Docker(一):说说容器和Docker
  9. 数学建模,一位负责编程的小白拿国奖的学习路程。
  10. snmp No Such Instance currently exists at this OID
  11. Idea 文件定位图标显示与关闭 -- idea ver:2020.1
  12. Win系统 - Windows10 系统恢复语言栏位置的方法(一)
  13. electron-vue 添加右下角通知图标
  14. Java开发谈:java如何开发安卓软件
  15. 小学计算机走进魔力画室教案,山西经济出版社小学第一册三年级信息技术第三单元活动1-12教案教案2017年(37页)-原创力文档...
  16. java 制作炸弹人
  17. 利用for循环打印 9*9 表?
  18. 解决:阿里云 OSS 存储访问报错 AccessDenied
  19. 计算机视觉用于图像识别的难点在哪?
  20. 团战可以输 提莫必须死

热门文章

  1. 解决webpack : 无法加载文件 C:\Users\XXX\AppData\Roaming\npm\webpack.ps1因为在此系统上禁止运行脚本
  2. Outlook里怎么设置网易企业邮箱【163企业邮箱注册】
  3. nginx设置代理后端服务器增加前缀
  4. Rockland 艾美捷丨TrueBlot链霉亲和素磁珠
  5. 总结-空洞卷积(Dilated/Atrous Convolution)、gridding问题以及解决方案、训练技巧BN和PReLU、CReLU
  6. 非极大值抑制(non-maximum suppression)的理解
  7. 负值最大与 Alpha-Beta 剪枝的结合
  8. 用c语言实现字母排列组合,C语言字母排列组合的实现.doc
  9. 面试中问的话题Spring工作原理
  10. 淘宝/天猫关键词搜索最新接口