匿名
未登录
登录
丢石头百科
搜索
查看“STM32CubeMX系列教程20:Nand Flash”的源代码
来自丢石头百科
名字空间
页面
讨论
更多
更多
页面选项
查看
查看源代码
历史
←
STM32CubeMX系列教程20:Nand Flash
因为以下原因,您没有权限编辑本页:
您所请求的操作仅限于该用户组的用户使用:
用户
您可以查看与复制此页面的源代码。
<b>一、Nand Flash 简介</b> <b> </b> Flash 中文名字叫闪存,是一种长寿命的非易失性(断电数据不丢失)的存储器。可以对称为块的存储器单元块进行擦写和再编程,在进行写入操作之前必须先执行擦除。功能性分为两种: NOR Flash:允许随机存取存储器上的任何区域,以编码应用为主,其功能多与运算相关 Nand Flash:主要功能是存储资料,适合储存卡之类的大量数据的存储。 本章以K9F1G08U0E芯片为例讲解Nand Flash。如下为此芯片的数据手册: <a class="attach" href="portal.php?mod=attachment&id=507" target="_blank">K9F1G08U0E.pdf <b>二、Nand Flash存储结构</b> <b> </b> [[File:112308jakhbuzhshbujasx.png]] 一个Nand Flash由多个块(Block)组成,每个块里面又包含很多页(page)。每个页对应一个空闲区域/冗余区域(spare area),这个区域不是用来存储数据的,用于放置数据的校验值检测和纠错的。 块,是Nand Flash的擦除操作的基本/最小单位。 页,是Nand Flash的写入操作的基本/最小的单位。 从上图可知,K91FG080U0E包含1024 Blocks,每个Block包含 64 Pages,每个Page包含2K Bytes数据空间 + 64 Bytes冗余空间。故总大小=1024 Blocks x 64 Pages x (2K+ 64) B = (1024 + 32) MBits = 1G Bits。 K91G08U0E功能框图如下: [[File:112308ks6spadqa3kq9zbw.png]] <b>三、Nand Flash引脚功能说明</b> <b> </b> [[File:112309dzvhjxzjda42zj34.png]] [[File:112309g3ezgkg84gggqgss.png]] 上图是常见的Nand Flash所拥有的引脚(Pin)所对应的功能,简单翻译如下: <ol style="font-family: 'Microsoft YaHei', 微软雅黑; line-height: 1.5; background-color: rgb(255, 255, 255);">* I/O0 ~ I/O7:用于输入地址/数据/命令,输出数据* CLE:Command Latch Enable,命令锁存使能,在输入命令之前,要先在模式寄存器中,设置CLE使能* ALE:Address Latch Enable,地址锁存使能,在输入地址之前,要先在模式寄存器中,设置ALE使能* CE#:Chip Enable,芯片使能,在操作Nand Flash之前,要先选中此芯片,才能操作* RE#:Read Enable,读使能,在读取数据之前,要先使CE#有效。* WE#:Write Enable,写使能,在写取数据之前,要先使WE#有效。* WP#:Write Protect,写保护* R/B#:Ready/Busy Output,就绪/忙,主要用于在发送完编程/擦除命令后,检测这些操作是否完成,忙,表示编程/擦除操作仍在进行中,就绪表示操作完成.* Vcc:Power,电源* Vss:Ground,接地* N.C:Non-Connection,未定义,未连接</ol> (字母上面带横杠说明引脚是低电平有效,为书写方便,在字母后面加“#”表示) <b>四、可变存储控制器(FMC)</b> <b> </b> FMC,即可变存储控制器,为STM32系列单片机的接口,本章就是通过这个接口控制NAND FLAHS。FMC 功能块可连接:同步/异步静态存储器、 SDRAM 存储器和 NAND Flash。其主要用途有: * 将 AHB 数据通信事务转换为适当的外部器件协议* 满足外部存储器器件的访问时间要求 说得复杂一点,FMC个功能就是将读写stm32内部地址操作转换为输出满足外部存储器的时序读写外部存储器。例如对STM32内部Ox8000 0000地址写入一个数据,FMC控制器会控制对应的管脚输出一个满足Nand Flash的时序,发送一个数据到Nand Flash设备。同理读取读取内部的寄存器,也会生成一个时序从Nand Flash读取一个数据。因此通过FMC控制外设非常简单,只需读写STM32内部寄存器即可实现对外部存储器的读写操作。我们只需配置好FMC时序寄存器,使产生的时序满足外部存储器的访问时间要求。 [[File:112310bgvl73mmql3v9oza.png]] FMC框图如上图,所有外部存储器共享地址、数据和控制信号, 但有各自的片选信号。 FMC 一次只能访问一个外部器件。其中FMC_A[25:0],FMC_D[31:00]为地址线和数据线,由于Nand Flash地址线和数据线复用,故配置时地址线和数据线是一样的。Nand Flash接口如下图(摘自Open746I-C原理图)。 [[File:112310ll3vlhh9kh39lvs9.png]] [[File:112311wop3p2loryuwywup.png]] FMC的存储区域外部储存分配图如图。其中Nand Flash为储存区域3,4x64MB。起始地址为0x8000 0000。 [[File:112311a1zniqxdi24umjmn.png]] <b style="font-family: 微软雅黑; font-size: 14px;">五、Nand Flash控制时序</b> <b style="font-family: 微软雅黑; font-size: 14px;"> </b> <b> </b> 和前面介绍的串行Nor Flash芯片W25Q128FV类似,Nand Flash也是通过指令控制的,在这里简单讲解一下Nand Flash的控制时序,讲解这部分只要是为了加深对Nand Flash的了解,和学习看时序图,实际编程的时候是不需要用到的,这部分ST公司已经提供nand flash的库了,我们只需调用函数控制Nand flash即可,不需要再理会底层。 下面为Nand Flash操作指令: [[File:112312o9us90jjecs66zok.png]] 如下编程操作和读操作的时序。首先先拉低NCE片选,只有选中芯片才能让他工作。 Nand Flash是通过 ALE/CLE 来区分数据线上的数据是命令(CLE有效),地址(ALE有效)还是数据(CLE/ALE都无效)。通过NWE/NRE来区分数据线上的数据是写操作(NWE有效)还是读操作(NRE有效)。 [[File:112312to7yioyqmmgquqs5.png]] [[File:112313n1cgmojngcco6px8.png]] <b style="font-family: 微软雅黑; font-size: 14px;"> </b> 下面为发送命令的时序图,已经对应的时间参数表: [[File:112314yrrv8ok5oonzjqtn.png]] [[File:112315q33li3g3vh323ja2.png]] 用FMC控制Nand Flash 我们只需要知道访问波形图中的四个时间参数既可。 [[File:112315dvivv2z9vx2jyvrg.png]] 从上这三个图我们可以知道: MEMxSET = tCLS - tWP >= 0ns MEMxWAIT = tWP >= 12ns MEMxHOLED = tCLH >= 5ns MEMxHIZ = tCLS - tDS >= 0ns <b style="font-family: 微软雅黑; font-size: 14px;">六、新建工程</b> <b style="font-family: 微软雅黑; font-size: 14px;"> <b style="font-size: 14px;"> 复制串口printf的工程,修改文件夹名。击STM32F746I.ioc打开STM32cubeMX的工程文件重新配置,选择NCE3开启NAND Flash,数据地址线选择8 bits,Ready or Busy选择 NWAIT。</b></b> <b style="font-family: 微软雅黑; font-size: 14px;"> </b> [[File:112315y8r8k6nryre8xgky.png]] FMC配置NAND Flash如下:使能ECC校验,建立保存等待等时间参数设置可以见上一节的时序图时间参数。 FMC是挂载到AHB时钟线上,频率等于系统时钟频率,即216M,时钟周期为 1 /216 MHz = ~4.6ns。 NAND属性信息根据前面介绍的K91FG080U0E存储结构配置。 [[File:112315vxpd2r05j9rc4cop.png]] 生成报告以及代码,编译程序。在fmc.c文件中可以看到初始化函数。在stm32f7xx_hal_nand.h头文件中可以看到NAND Flash的操作函数。 声明变量: RxBuffer,TxBnffer为读写缓存,大小可以Nand flash一页的长度;NAND_ID储存ID信息,WriteReadAddr为存储Nand Flash操作地址。 <syntaxhighlight lang="python"> /* USER CODE BEGIN PV */</syntaxhighlight> <syntaxhighlight lang="python"> /* Private variables ---------------------------------------------------------*/</syntaxhighlight> <syntaxhighlight lang="python"> /* for K9F1G08 */</syntaxhighlight> <syntaxhighlight lang="python"> #define NAND_PAGE_SIZE ((uint16_t)0x0800) /* 2 * 1024 bytes per page w/o Spare Area */</syntaxhighlight> <syntaxhighlight lang="python"> NAND_IDTypeDef NAND_ID;</syntaxhighlight> <syntaxhighlight lang="python"> NAND_AddressTypeDef WriteReadAddr;</syntaxhighlight> <syntaxhighlight lang="python"> static</syntaxhighlight> <syntaxhighlight lang="python"> uint8_t TxBuffer [NAND_PAGE_SIZE];</syntaxhighlight> <syntaxhighlight lang="python"> static</syntaxhighlight> <syntaxhighlight lang="python"> uint8_t RxBuffer [NAND_PAGE_SIZE];</syntaxhighlight> <syntaxhighlight lang="python"> uint16_t i;</syntaxhighlight> <syntaxhighlight lang="python"> /* USER CODE END PV */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight>添加应用程序,程序中先读取Nand Flash ID,然后配置操作地址,对页进行擦除,写,读等操作。 <syntaxhighlight lang="python"> </syntaxhighlight> <syntaxhighlight lang="python"> <code style="color: rgb(221, 17, 68); font-family: Consolas, 'Bitstream Vera Sans Mono', 'Courier New', Courier, monospace !important; font-size: 1em !important;"> </syntaxhighlight><syntaxhighlight lang="python"> /* USER CODE BEGIN 2 */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "\r\nNandFlash Example \r\n\r\n"</syntaxhighlight><syntaxhighlight lang="python"> );</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> /* Read the NAND memory ID */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> HAL_NAND_Read_ID(&hnand1, &NAND_ID);</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "Nand Flash ID = 0x%02X,0x%02X,0x%02X,0x%02X "</syntaxhighlight><syntaxhighlight lang="python"> ,NAND_ID.Maker_Id, NAND_ID.Device_Id,</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> NAND_ID.Third_Id, NAND_ID.Fourth_Id );</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> if</syntaxhighlight> <syntaxhighlight lang="python"> ((NAND_ID.Maker_Id == 0xEC) && (NAND_ID.Device_Id == 0xF1)</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> && (NAND_ID.Third_Id == 0x80) && (NAND_ID.Fourth_Id == 0x15))</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> {</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "Type = K9F1G08U0A\r\n"</syntaxhighlight><syntaxhighlight lang="python"> );</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> }</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> else</syntaxhighlight> <syntaxhighlight lang="python"> if</syntaxhighlight> <syntaxhighlight lang="python"> ((NAND_ID.Maker_Id == 0xEC) && (NAND_ID.Device_Id == 0xF1)</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> && (NAND_ID.Third_Id == 0x00) && (NAND_ID.Fourth_Id == 0x95))</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> {</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "Type = K9F1G08U0B\r\n"</syntaxhighlight><syntaxhighlight lang="python"> ); </syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> }</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> else</syntaxhighlight> <syntaxhighlight lang="python"> if</syntaxhighlight> <syntaxhighlight lang="python"> ((NAND_ID.Maker_Id == 0xAD) && (NAND_ID.Device_Id == 0xF1)</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> && (NAND_ID.Third_Id == 0x80) && (NAND_ID.Fourth_Id == 0x1D))</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> {</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "Type = HY27UF081G2A\r\n"</syntaxhighlight><syntaxhighlight lang="python"> ); </syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> }</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> else</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> {</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "Type = Unknow\r\n"</syntaxhighlight><syntaxhighlight lang="python"> );</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> }</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> /* NAND memory address to write to */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> WriteReadAddr.Zone = 0x00;</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> WriteReadAddr.Block = 0x00;</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> WriteReadAddr.Page = 0x00;</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> /* Erase the NAND first Block */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> HAL_NAND_Erase_Block(&hnand1,&WriteReadAddr);</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> /* Fill the buffer to send */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> for</syntaxhighlight> <syntaxhighlight lang="python"> (i = 0; i < NAND_PAGE_SIZE; i++ )</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> {</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> TxBuffer[i] = i;</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> }</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> /* Write data to FMC NAND memory */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> HAL_NAND_Write_Page(&hnand1, &WriteReadAddr, TxBuffer, 1);</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "\r\nWritten to the number of£º \r\n"</syntaxhighlight><syntaxhighlight lang="python"> );</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> for</syntaxhighlight><syntaxhighlight lang="python"> (i = 0; i < 2048; i++)</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "0x%02X \r"</syntaxhighlight><syntaxhighlight lang="python"> ,TxBuffer[i]);</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> HAL_Delay(100);</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> /* Read data from FMC NAND memory */</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> HAL_NAND_Read_Page(&hnand1, &WriteReadAddr, RxBuffer, 1);</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "\r\nRead receive: \r\n"</syntaxhighlight><syntaxhighlight lang="python"> );</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> for</syntaxhighlight><syntaxhighlight lang="python"> (i = 0; i < 2048; i++)</syntaxhighlight> <syntaxhighlight lang="python"> </syntaxhighlight><syntaxhighlight lang="python"> printf</syntaxhighlight><syntaxhighlight lang="python"> (</syntaxhighlight><syntaxhighlight lang="python"> "0x%02X \r"</syntaxhighlight><syntaxhighlight lang="python"> ,RxBuffer[i]); </syntaxhighlight></code>
返回至
STM32CubeMX系列教程20:Nand Flash
。
导航
导航
首页
最近更改
随机页面
MediaWiki帮助
首页
首页
树莓派
主机
配件包
外壳
键鼠
电源
扩展板
显示屏
墨水屏
摄像模块
通信模块
继电器
电机驱动板
游戏机
产品分类
树莓派
Arduino
micro:bit
STM32
Espressif
WiFi模块
蓝牙模块
无线模块
LoRa模块
4G模块
GSM
GPRS
以太网
导航模块
北斗卫星
GPS
LCD
墨水屏
OLED
摄像头
USB模块
串口模块
RS232
RS485
CAN
传感器
温度模块
湿度模块
气压模块
继电器
电机模块
指纹模块
电平转换
音频模块
编程器
Wiki工具
Wiki工具
特殊页面
页面工具
页面工具
用户页面工具
更多
链入页面
相关更改
页面信息
页面日志