[国嵌攻略][052][NandFlash驱动设计_读]
NandFlash读数据方式
1.页读,读出页中主数据区的所有数据,提供页地址(行地址)
2.随机读,读出页中指定的存储单元的数据,提供页地址(行地址)和页内偏移(行地址)
代码编写
1.根据NandFlash中的读时序图写出工作流程,可以通过在芯片手册中搜索operation找到相关描述
2.主要关心的是IO脚上时序的变化
3.初始化闪存分为初始化闪存控制器和闪存芯片
4.对位操作
4.1.清零
x &= ~(y<<z) 对x的z位开始的y清零
4.2.置1
x |= y<<z 对x的z位开始的y置1
4.3.取数
x & y<<z 取出x的第z位开始的y
4.4.置数
x = y
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | /******************************************************************** *名称:flash *作者:D *时间:2015.11.08 *功能:闪存驱动 ********************************************************************/ /******************************************************************** * 宏定义 ********************************************************************/ #define NFCONF ( *((volatile unsigned long *)0x4E000000) ) //闪存配置寄存器 #define NFCONT ( *((volatile unsigned long *)0x4E000004) ) //闪存控制寄存器 #define NFCMMD ( *((volatile unsigned long *)0x4E000008) ) //闪存命令寄存器 #define NFADDR ( *((volatile unsigned long *)0x4E00000C) ) //闪存地址寄存器 #define NFDATA ( *((volatile unsigned char *)0x4E000010) ) //闪存数据寄存器 #define NFSTAT ( *((volatile unsigned long *)0x4E000020) ) //闪存状态寄存器 #define PAGE_SIZE 2048 //页大小 /******************************************************************** * 函数原型声明 ********************************************************************/ void init_flash(); void init_flash_controller(); void reset_flash_chip(); void read_flash(unsigned long src, unsigned long dst, int len); void read_page_flash(unsigned long page, unsigned char *buf); /******************************************************************** *名称:init_flash *功能:初始化闪存 *********************************************************************/ void init_flash(){ //初始化闪存控制器 init_flash_controller(); //重置闪存芯片 reset_flash_chip(); } /******************************************************************** *名称:init_flash_controller *功能:初始化闪存控制器 *********************************************************************/ void init_flash_controller(){ //初始化闪存配置寄存器 NFCONF = (1<<12)|(1<<8)|(1<<4); //设置TACLS:1 TWRPH0:1 TWRPH1:1 //初始化闪存控制寄存器 NFCONT = (1<<1)|(1<<0); //设置Reg_nCE:1 MODE:1 } /******************************************************************** *名称:reset_flash_chip *功能:重置闪存芯片 *********************************************************************/ void reset_flash_chip(){ //选中闪存芯片 NFCONT &= ~(1<<1); //设置Reg_nCE:0 //清除忙信号 NFSTAT |= (1<<2); //设置RnB_TransDetect:0 //发送重启命令 NFCMMD = 0xFF; //等待忙信号 while ( !(NFSTAT&(1<<2)) ); //当RnB_TransDetect等于1时,结束循环 //释放闪存芯片 NFCONT |= 1<<1; //设置Reg_nCE:1 } /******************************************************************** *名称:read_flash *参数: * src 源地址 * dst 目的地址 * len 读取长度 *返回: * null *功能:读闪存 *********************************************************************/ void read_flash(unsigned long src, unsigned long dst, int len){ unsigned long page; //页号 unsigned char *buf; //页缓存 while (len > 0){ page = src>>11; //设置页号 buf = (unsigned char *)dst; //设置页缓存 read_page_flash(page, buf); src +=PAGE_SIZE; dst +=PAGE_SIZE; len -=PAGE_SIZE; } } /******************************************************************** *名称:read_page_flash *参数: * page 页号 * buf 页缓存,2048字节 *返回: * none *功能:页读闪存 *********************************************************************/ void read_page_flash(unsigned long page, unsigned char *buf){ int i; //循环计数器 //选中闪存芯片 NFCONT &= ~(1<<1); //设置Reg_nCE:0 //清除忙信号 NFSTAT |= (1<<2); //设置RnB_TransDetect:0 //发送读命令(0x00) NFCMMD = 0x00; //发送列地址 NFADDR = 0x00; //Col.Add1 NFADDR = 0x00; //Col.Add2 //发送行地址 NFADDR = (page>>0)&0xFF; //Row.Add1 NFADDR = (page>>8)&0xFF; //Row.Add2 NFADDR = (page>>16)&0xFF; //Row.Add3 //发送读命令(0x30) NFCMMD = 0x30; //等待忙信号 while ( !(NFSTAT&(1<<2)) ); //当RnB_TransDetect等于1时,结束循环 //读取数据 for (i = 0; i < PAGE_SIZE; i++){ buf[i] = NFDATA; //注意,NFDATA寄存器数据类型要和buf匹配,一个读周期读出一个字节 } //释放闪存芯片 NFCONT |= 1<<1; //设置Reg_nCE:1 } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术