STM32使用FSMC控制NAND flash 例程
FSMC配置
一、基本概念(详细内容见st网站stm32应用笔记AN2784)1. FSMC配置控制一个NOR闪存存储器,需要FSMC提供下述功能:●选择合适的存储块映射NOR闪存存储器:共有4个独立的存储块可以用于与NOR闪存、SRAM和PSRAM存储器接口,每个存储块都有一个专用的片选管脚。
●使用或禁止地址/数据总线的复用功能。
●选择所用的存储器类型:NOR闪存、SRAM或PSRAM。
●定义外部存储器的数据总线宽度:8或16位。
●使用或关闭同步NOR闪存存储器的突发访问模式。
●配置等待信号的使用:开启或关闭,极性设置,时序配置。
●使用或关闭扩展模式:扩展模式用于访问那些具有不同读写操作时序的存储器。
因为NOR闪存/SRAM控制器可以支持异步和同步存储器,用户只须根据存储器的参数配置使用到的参数。
FSMC提供了一些可编程的参数,可以正确地与外部存储器接口。
依存储器类型的不同,有些参数是不需要的。
当使用一个外部异步存储器时,用户必须按照存储器的数据手册给出的时序数据,计算和设置下列参数:●ADDSET:地址建立时间●ADDHOLD:地址保持时间●DATAST:数据建立时间●ACCMOD:访问模式这个参数允许FSMC可以灵活地访问多种异步的静态存储器。
共有4种扩展模式允许以不同的时序分别读写存储器。
在扩展模式下,FSMC_BTR用于配置读操作,FSMC_BWR用于配置写操作。
(译注:如果读时序与写时序相同,只须使用FSMC_BTR即可。
)如果使用了同步的存储器,用户必须计算和设置下述参数:●CLKDIV:时钟分频系数●DATLAT:数据延时如果存储器支持的话,NOR闪存的读操作可以是同步的,而写操作仍然是异步的。
当对一个同步的NOR闪存编程时,存储器会自动地在同步与异步之间切换;因此,必须正确地设置所有的参数。
2. 时序计算如上所述,对于异步NOR闪存存储器或类似的存储,有不同的访问协议。
首先要确定对特定存储器所需要使用的操作协议,选择的依据是不同的控制信号和存储器在读或写操作中的动作。
STM32F使用内部FLASH程序详解
STM32F0xx_FLASH_PAGE15_STARTADDR,
EEPPROM_PACKAGEHEAD );
/*Write length*/
FLASH_ProgramHalfWord( STM32F0xx_FLASH_PAGE15_STARTADDR+2 , length );
/*Write datas*/
但是,我们的数据是打包的(详见 2.2),所以还需要: 根据报头判断是不是有效数据 根据长度判断要读取多少数据 最后才是读出数据 4.1、判断数据有效性:
我们通过报头来判断数据是不是自己写入的。也就是判断 flash 第 15 页的第 1、2 个字 节是不是 0xaa55,如果不是,那这段数据是无效的。另外再判断一下长度字段,如果长度等 于 0,也就是后面没有数据,那这段数据也是无效的。
* Input
: buff:pointer of first data, length: write length
* Output
:
* Return
: true/false
*******************************************************************************/
* Function Name : readPackedMessageFromFlash
* Description : Read packed message form flash
* Input
: buff:point to first location of received buffer.length:Maxmum
* Input
: None
* Output
STM32-FSMC-NOR FLASH
一、基本概念(详细内容见st网站stm32应用笔记AN2784)1. FSMC配置控制一个NOR闪存存储器,需要FSMC提供下述功能:●选择合适的存储块映射NOR闪存存储器:共有4个独立的存储块可以用于与NOR闪存、SRAM和PSRAM存储器接口,每个存储块都有一个专用的片选管脚。
●使用或禁止地址/数据总线的复用功能。
●选择所用的存储器类型:NOR闪存、SRAM或PSRAM。
●定义外部存储器的数据总线宽度:8或16位。
●使用或关闭同步NOR闪存存储器的突发访问模式。
●配置等待信号的使用:开启或关闭,极性设置,时序配置。
●使用或关闭扩展模式:扩展模式用于访问那些具有不同读写操作时序的存储器。
因为NOR闪存/SRAM控制器可以支持异步和同步存储器,用户只须根据存储器的参数配置使用到的参数。
FSMC提供了一些可编程的参数,可以正确地与外部存储器接口。
依存储器类型的不同,有些参数是不需要的。
当使用一个外部异步存储器时,用户必须按照存储器的数据手册给出的时序数据,计算和设置下列参数:●ADDSET:地址建立时间●ADDHOLD:地址保持时间●DATAST:数据建立时间●ACCMOD:访问模式这个参数允许FSMC可以灵活地访问多种异步的静态存储器。
共有4种扩展模式允许以不同的时序分别读写存储器。
在扩展模式下,FSMC_BTR用于配置读操作,FSMC_BWR用于配置写操作。
(译注:如果读时序与写时序相同,只须使用FSMC_BTR即可。
)如果使用了同步的存储器,用户必须计算和设置下述参数:●CLKDIV:时钟分频系数●DATLAT:数据延时如果存储器支持的话,NOR闪存的读操作可以是同步的,而写操作仍然是异步的。
当对一个同步的NOR闪存编程时,存储器会自动地在同步与异步之间切换;因此,必须正确地设置所有的参数。
2. 时序计算如上所述,对于异步NOR闪存存储器或类似的存储,有不同的访问协议。
首先要确定对特定存储器所需要使用的操作协议,选择的依据是不同的控制信号和存储器在读或写操作中的动作。
STM32系列FSMC控制器分析和代码
1、FSMC初初了解:FSMC 包括4个模块:(1)AHB接口(包括FSMC配置寄存器)(2)NOR闪存和PSRAM控制器(驱动LCD的时候LCD就好像一个PSRAM的里面只有2个16位的存储空间,一个是DATA RAM 一个是CMD RAM)(3)NAND闪存和PC卡控制器(4)外部设备接口我们驱动TFT很明显用的是第二个模块:NOR闪存。
2、FSMC的外设地址选择FSMC _Bank 用来选择外接存储器的地址,FSMC所控制的外存储器所映射的地址是0x6000 0000 ~ 0x9fff ffff其中属于NOR FLASH 的是0x6000 0000 ~ 0x6fff ffff ,然后这部分的地址空间又被分为四份,每份64MB, 编号是BANK1 ~ BANK 4 ,每个BANK 都有一个片选引脚。
而这四个分存储块的片选,则使用NE[4:1]来选择。
数据线/地址线/控制线是共享的。
NE1 ->Bank1 NE2->Bank2 NE3->Bank3 NE4->Bank4第一块:6000 0000h--63ff ffffh第二块:6400 0000h--67ff ffffh第三块:6800 0000h--6bff ffffh第四块:6c00 0000h--6fff ffffh3、FSMC 驱动LCDFSMC提供了所有的LCD控制器的信号:FSMC_D[16:0]:16bit的数据总线FSMC NEx:分配给NOR的256M,再分为4个区,每个区用来分配一个外设,这四个外设的片选分为是NE1-NE4,对应的引脚为:PD7—NE1,PG9—NE2,PG10-NE3,PG12—NE4FSMC NOE:输出使能,连接LCD的RD脚。
FSMC NWE:写使能,连接LCD的RW脚。
FSMC Ax:用在LCD显示RAM和寄存器之间进行选择的地址线,即该线用于选择LCD的RS脚,该线可用地址线的任意一根线,范围:FSMC_A[25:0]。
STM32的常用外设驱动程序的开发
设计研发2021.01STM32的常用外设驱动程序的开发沈镐哲(绍兴文理学院数理信息学院,浙江绍兴,312000)摘要:围绕不同应用场景的嵌入式芯片应用是国内外电子行业的研究热点,在人工智能、物联网、工业互联网等领域有着广泛的应用。
基于Cortex-M3内核的STM32微控制器由于其功能众多、易于应用、家族齐全,受到业界的广泛欢迎。
本文讨论了STM32常用外设驱动库的结构,并在实例基础上分析了驱动开发,可以作为初学者的参考。
关键字:STM32;Cortex-M;常用外设驱动开发;应用拓展Developme n t of comm o n peripheral drivers for STM32Shen Haozhe(Department of Physics and Electrical Engineering,Shaoxing College of Arts and Sciences,Shaoxing Zhejiang,312000)Abstract:Embedded chip application around different application scenarios is a research hotspot inthe electronics industry at home and abroad,and it has a wide range of applications in artificial intelligence,Internet of Things,industrial Internet and other fields.The STM32microcontroller based on Cortex-M3kernel is widely welcomed in the industry due to its numerous functions,easy application and complete family.This paper discusses the strueture of the common peripheral driver library of STM32,and analyzes the driver development on the basis of an example,which can be used asa reference for beginners.Keywords:STM32:Cortex-M;Commonperipherals drive development;Application development0引言科技发展日益迅猛,具有低成本、低功耗、高性能、可裁剪、功能多等优势ARM结构的STM32系列单片机成为市场主流的芯片。
STM32使用FSMC控制NAND flash 例程概要
本文原创于观海听涛,原作者版权所有,转载请注明出处。
近几天开发项目需要用到STM32驱动NAND FLASH,但由于开发板例程以及固件库是用于小页(512B,我要用到的FLASH为1G bit的大页(2K,多走了两天弯路。
以下笔记将说明如何将默认固件库修改为大页模式以驱动大容量NAND,并作驱动。
本文硬件:控制器:STM32F103ZET6,存储器:HY27UF081G2A首先说一下NOR与NAND存储器的区别,此类区别网上有很多,在此仅大致说明:1、Nor读取速度比NAND稍快2、Nand写入速度比Nor快很多3、NAND擦除速度(4ms远快于Nor(5s4、Nor 带有SRAM接口,有足够的地址引脚来寻址,可以很轻松的挂接到CPU 地址和数据总线上,对CPU要求低5、NAND用八个(或十六个引脚串行读取数据,数据总线地址总线复用,通常需要CPU支持驱动,且较为复杂6、Nor主要占据1-16M容量市场,并且可以片内执行,适合代码存储7、NAND占据8-128M及以上市场,通常用来作数据存储8、NAND便宜一些9、NAND寿命比Nor长10、NAND会产生坏块,需要做坏块处理和ECC更详细区别请继续百度,以上内容部分摘自神舟三号开发板手册下面是NAND的存储结构:由此图可看出NAND存储结构为立体式正如硬盘的盘片被分为磁道,每个磁道又分为若干扇区,一块nand flash也分为若干block,每个block分为如干page。
一般而言,block、page之间的关系随着芯片的不同而不同。
需要注意的是,对于flash的读写都是以一个page开始的,但是在读写之前必须进行flash 的擦写,而擦写则是以一个block为单位的。
我们这次使用的HY27UF081G2A其PDF介绍:Memory Cell Array= (2K+64 Bytes x 64 Pages x 1,024 Blocks由此可见,该NAND每页2K,共64页,1024块。
20-STM32CubeMX系列教程20-Nand Flash
/* Erase the NAND first Block */ HAL_NAND_Erase_Block(&hnand1,&WriteReadAddr);
/* Fill the buffer to send */ for (i = 0; i < NAND_PAGE_SIZE; i++ ) {
TxBuffer[i] = i; }
下面为发送命令的时序图,已经对应的时间参数表:
用 FMC 控制 Nand Flash 我们只需要知道访问波形图中的四个时间参数既可。 从上这三个图我们可以知道:
MEMxSET = tCLS - tWP >= 0ns MEMxWAIT = tWP >= 12ns MEMxHOLED = tCLH >= 5ns MEMxHIZ = tCLS - tDS >= 0ns 六、新建工程 复制串口 printf 的工程,修改文件夹名。击 STM32F746I.ioc 打开 STM32cubeMX 的工程文件 重新配置,选择 NCE3 开启 NAND Flash,数据地址线选择 8 bits,Ready or Busy 选择 NWAIT。
NOR Flash:允许随机存取存储器上的任何区域,以编码应用为主,其功能多与运算相关 Nand Flash:主要功能是存储资料,适合储存卡之类的大量数据的存储。
stm32f4 flash读写例程
一、概述STM32F4是ST公司推出的一款高性能的32位微控制器,它具有强大的性能和丰富的外设资源,广泛应用于工业控制、消费电子、通信设备等领域。
其中,STM32F4的Flash存储器模块具有较大的存储容量和快速的读写速度,非常适合用来存储程序代码和数据。
本文将介绍如何使用STM32F4的Flash存储器模块进行读写操作的例程。
二、开发环境准备1. 基本硬件准备:准备一块STM32F4开发板,如STM32F407ZGT6开发板。
一台电脑,安装了Keil或者其他的开发环境。
2. 软件准备:在电脑上安装好STM32CubeMX和Keil或者其他的开发环境。
三、创建工程1. 打开STM32CubeMX,新建一个工程,选择对应的芯片型号,例如选择STM32F407ZGT6。
2. 配置时钟树,使得系统时钟为想要的频率,一般选择高频率以获得更快的Flash读写速度。
3. 配置Flash存储器,选择合适的扇区大小和擦写次数。
4. 生成代码,导出工程。
四、编写代码1. 在Keil或者其他的开发环境中打开刚刚生成的工程。
2. 找到Flash读写相关的API,一般在芯片提供的库函数中可以找到。
3. 根据需要编写Flash读写的代码,例如可以编写一个函数来实现向Flash写入数据的功能。
五、编译下载1. 编译代码,生成bin文件。
2. 将bin文件下载到STM32F4开发板中,可以使用ST-Link或者其他下载工具来完成。
六、调试运行1. 确保下载成功,重启开发板。
2. 进行调试,观察Flash读写是否正常。
七、注意事项1. 在进行Flash写入操作时,一定要小心谨慎,避免对程序的正常运行造成影响。
2. 在进行Flash擦除操作时,务必注意擦除的范围,避免擦除了不该擦除的数据。
3. 在进行Flash读写操作时,需要留意Flash的特性和限制,以免造成不必要的麻烦。
八、总结本文介绍了如何在STM32F4开发板上使用Flash存储器进行读写操作的例程,从开发环境准备到代码编写再到调试运行都有详细的步骤说明,并给出了注意事项和总结。
通过FSMC总线执行NORFLASH中程序的步骤
通过FSMC总线执行NORFLASH中程序的步骤
从外部NOR闪存存储器执行代码
大容量的STM32F10xxx内置了多达512K字节的闪存存储器,对于多数应用是足够了。
需要更多存储器容量的应用,可以使用外加的NOR闪存存储器。
本节说明了如何使用外部NOR闪存存储器运行用户程序。
这需要2个重要的步骤:
●
加载用户程序至外部NOR存储器:这个操作需要对开发工具进行特别的配置:在链接文件中,必须指定NOR闪存存储器的开始地址(或任何其它地址),这是需要放置用户程序的地址。
●
执行用户代码:一旦用户程序代码加载到NOR闪存存储器,在内部闪存存储器中需要有一段配置FSMC的程序,配置好FSMC后可以跳转至(NOR闪存存储器中的)用户程序代码执行。
当然MDK下也可以吧FSMC的配置信息写到DeBug脚本文件里。
STM32L4灵活的静态内存控制器(FMC)介绍
• Memory data width: • Synchronous or asynchronous Mode • Multiplexed or not multiplexed memory • Continuous FMC_clock generation in Aysnchronous/synchronous mode. • Wait feature enable or disable • Extended mode: read timings and protocol are different to write.
0x63FF FFFF
NOR / PSRAM / OneNAND
0x6000 0000
0x6400 0000 0x67FF FFFF
Bank1 chip select 2 64 MB Bank1 chip select 3 64 MB Bank1 chip select 4 64 MB
Bank 1 4x64 MB
– Common memory space – Attribute memory space
• Each memory space is divided into 3 subsection:
– Data section: first 32KB in the common/attribute memory space
NOR Memory Controller
FMC_A[25:0]
02/07/2015
STM32F42xx Technical Training
8
• Memory type:
– 8 bit /16 bit
NOR/PSRAM Controller features configuration
stm32f103c8 flash读写例程
以下是一个使用STM32F103C8微控制器进行Flash读写的例程:```c#include "stm32f10x.h"#include "stm32f10x_flash.h"void Flash_Init(void){FLASH_DeInit(); // 关闭所有已启用的闪存接口FLASH_EraseSector(FLASH_Addr_0); // 擦除第一个扇区FLASH_Write_Enable(); // 使能写操作}uint32_t Flash_Read(uint32_t ReadAddr, uint8_t *pBuffer){uint32_t ReadData;if (ReadAddr >= FLASH_Addr_Start_Page && ReadAddr < FLASH_Addr_End_Page) {FLASH_Lock(); // 锁定闪存,防止其他操作干扰FLASH_Unlock(); // 解锁闪存FLASH_EraseSector(ReadAddr); // 擦除指定地址的扇区FLASH_Write_Enable(); // 使能写操作FLASH_ProgramWord(ReadAddr, *pBuffer); // 写入数据到指定地址FLASH_Lock(); // 再次锁定闪存FLASH_Unlock(); // 解锁闪存FLASH_Read(ReadAddr, &ReadData); // 从指定地址读取数据FLASH_Lock(); // 再次锁定闪存FLASH_Unlock(); // 解锁闪存}else{ReadData = 0;}return ReadData;}uint32_t Flash_Write(uint32_t WriteAddr, uint8_t *pBuffer){uint32_t WriteData;if (WriteAddr >= FLASH_Addr_Start_Page && WriteAddr < FLASH_Addr_End_Page) {FLASH_Lock(); // 锁定闪存,防止其他操作干扰FLASH_Unlock(); // 解锁闪存FLASH_EraseSector(WriteAddr); // 擦除指定地址的扇区FLASH_Write_Enable(); // 使能写操作FLASH_ProgramWord(WriteAddr, *pBuffer); // 写入数据到指定地址FLASH_Lock(); // 再次锁定闪存FLASH_Unlock(); // 解锁闪存FLASH_Read(WriteAddr, &WriteData); // 从指定地址读取数据FLASH_Lock(); // 再次锁定闪存FLASH_Unlock(); // 解锁闪存}else{WriteData = 0;}return WriteData;}```这个例程包含了一个初始化函数`Flash_Init()`,用于初始化Flash设备。
关于STM32的FLASH操作
关于STM32的FLASH操作STM32是一款由意法半导体(STMicroelectronics)推出的32位精简型单片机系列。
它采用了ARM Cortex-M内核,并在Flash和内存等方面进行了优化,提供了强大的性能和丰富的外设功能。
FLASH是STM32芯片上的一种非易失性存储器,可以用于存储应用程序代码、数据、配置信息等。
在STM32中进行FLASH操作可以通过编程和标准库函数两种方式实现。
下面将依次介绍这两种方法的使用。
一、编程方式编程方式是直接对FLASH进行底层的读写操作,需要对相关寄存器进行配置和控制。
1.写入数据在STM32的FLASH中写入数据的操作需要经历以下步骤:1) 解锁FLASH:通过FLASH_Unlock(函数解锁FLASH,使其可写入。
2) 擦除FLASH:通过FLASH_ErasePage(函数擦除要写入的FLASH扇区。
3) 写入数据:通过FLASH_ProgramByte(、FLASH_ProgramHalfWord(、FLASH_ProgramWord(等函数对FLASH进行数据写入。
4) 上锁FLASH:通过FLASH_Lock(函数上锁FLASH,防止误操作。
以下是一个简单的例子,演示如何通过编程方式对STM32的FLASH进行数据写入:```c#include "stm32f10x_flash.h"void ConfigureFlash(void)FLASH_Unlock(; // 解锁FlashFLASH_ClearFlag(FLASH_FLAG_EOP , FLASH_FLAG_PGERR ,FLASH_FLAG_WRPRTERR); // 清除状态标志FLASH_ErasePage(FLASH_START_ADDR); // 擦除扇区FLASH_Lock(; // 上锁Flash```2.读取数据读取STM32的FLASH数据需要通过指针的方式直接读取存储器的地址,如下所示:```c#define READ_FLASH(addr) (*(volatile uint32_t*)(addr))void ReadFlash(void)uint32_t data = READ_FLASH(FLASH_START_ADDR);//在这里对读取的数据进行处理```二、标准库函数方式STM32提供了一套标准库函数,方便开发者进行FLASH操作。
三星K9F1G08U0E(128MB,NANDFLASH)STM32平台驱动程序(模拟时序)
三星K9F1G08U0E(128MB,NANDFLASH)STM32平台驱动程序(模拟时序)STM32平台下模拟时序驱动K9F1G08U0E,主要⽬的为了解、学习NAND FLASH的功能特性,没有使⽤STM32的FSMC(⽕龙开发板硬件为模拟时序驱动),纯粹⾃娱⾃乐,如对你有帮助,不胜荣幸,呵呵。
C⽂件内容:1 #include "NAND512W3A2C.h"2/*3作者:毕⼩乐4⽇期:2019.01.245版本:V1.0067驱动代码针对K9F1G08U0E时序⽽写,K9F1G08U0E与NAND512W3A2C,Pin to Pin兼容。
8驱动运⾏平台STM32F103。
9驱动实现功能:101)Page Read112) Page Program123) Block Erase134) Read Status145) Read ID15PE0~PE7 -> DB00~DB0716PD6 -> CL17PD5 -> AL18PD14 -> W19PD15 -> R20PD7 -> CS21PB5 -> R/B22*/23static void NAND512_Delay_uS(int tick)24 {25int i;26while(tick>0)27 {28 tick--;29for(i=0;i<10;i++)30 __nop();31 }32 }33void NAND512_DB_OutPut(void)34 {35 GPIO_InitTypeDef GPIO_InitStructure;3637 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_338 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;39 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;40 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;41 GPIO_Init(GPIOE, &GPIO_InitStructure);42 }43void NAND512_DB_InPut(void)44 {45 GPIO_InitTypeDef GPIO_InitStructure;4647 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_348 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7;49 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;50 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;51 GPIO_Init(GPIOE, &GPIO_InitStructure);52 }53char NAND512_DB_Read(void)54 {55char dat;56 NAND512_DB_InPut();57 __nop();58 dat = GPIO_ReadInputData(GPIOE) & 0x00FF;59return dat;60 }61void NAND512_DB_Write(char Data)62 {63 u16 temp;64 NAND512_DB_OutPut();65// __nop();71void NAND512_IO_Init(void)72 {73 GPIO_InitTypeDef GPIO_InitStructure;7475 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOD76 | RCC_APB2Periph_GPIOE, ENABLE);7778/*CL*/79 GPIO_InitStructure.GPIO_Pin = NAND512_CL_PIN;80 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;81 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;82 GPIO_Init(NAND512_CL_PORT, &GPIO_InitStructure);8384/*AL*/85 GPIO_InitStructure.GPIO_Pin = NAND512_AL_PIN;86 GPIO_Init(NAND512_AL_PORT, &GPIO_InitStructure);8788/*W*/89 GPIO_InitStructure.GPIO_Pin = NAND512_W_PIN;90 GPIO_Init(NAND512_W_PORT, &GPIO_InitStructure);9192/*R*/93 GPIO_InitStructure.GPIO_Pin = NAND512_R_PIN;94 GPIO_Init(NAND512_R_PORT, &GPIO_InitStructure);9596/*CE*/97 GPIO_InitStructure.GPIO_Pin = NAND512_CE_PIN;98 GPIO_Init(NAND512_CE_PORT, &GPIO_InitStructure);99100/*R/B*/101 GPIO_InitStructure.GPIO_Pin = NAND512_RB_PIN;102 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;103 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;104 GPIO_Init(NAND512_RB_PORT, &GPIO_InitStructure);105106 NAND512_CL_LOW;107 NAND512_AL_LOW;108 NAND512_R_HIGH;109 NAND512_W_HIGH;110 NAND512_CE_HIGH;111 }112113//读状态寄存器信息114char NAND512_Read_Status(void)115 {116char dat;117118 NAND512_CL_LOW;119 NAND512_W_HIGH;120 NAND512_R_HIGH;121 NAND512_CE_HIGH;122 NOP;123124 NAND512_Delay_uS(5);125 NAND512_CL_HIGH;126 NOP;127 NOP;128 NAND512_CE_LOW;129 NOP;130 NOP;131 NOP;132 NAND512_W_LOW;133 NAND512_DB_Write(0x70);134 NOP;135 NAND512_W_HIGH;136137 NAND512_Delay_uS(5);138 NAND512_CL_LOW;139 NOP;140 NOP;141//CE状态保持不变142143 NAND512_Delay_uS(10);144 NAND512_R_LOW;145 NOP;146 dat = NAND512_DB_Read();147 NAND512_Delay_uS(5);148 NAND512_R_LOW;149 NAND512_Delay_uS(5);155156void NAND512_Read_ID(char* Buf)157 {158char i = 0;159160 NAND512_CL_LOW;161 NAND512_AL_LOW;162 NAND512_R_HIGH;163 NAND512_W_HIGH;164 NAND512_CE_HIGH;165 NAND512_Delay_uS(5);166167 NAND512_CL_HIGH;168 NAND512_W_LOW;169 NAND512_Delay_uS(5);170 NAND512_CE_LOW;171 NAND512_DB_Write(0x90);172 NAND512_Delay_uS(5);173 NAND512_W_HIGH;174 NAND512_Delay_uS(5);175176 NAND512_CL_LOW;177 NAND512_Delay_uS(20);178 NAND512_AL_HIGH;179 NAND512_Delay_uS(20);180 NAND512_W_LOW;181 NAND512_DB_Write(0x00); //写地址0182 NAND512_Delay_uS(5);183 NAND512_W_HIGH;184 NAND512_Delay_uS(10);185 NAND512_AL_LOW;186 NAND512_Delay_uS(20);187188for(i=0;i<5;i++)189 {190 NAND512_R_LOW;191 NAND512_Delay_uS(10);192 Buf[i] = NAND512_DB_Read();193 NAND512_R_HIGH;194 NAND512_Delay_uS(10);195 }196197return ;198 }199200void NAND512_Page_Read(char* Buf,int Len,int Add)201 {202int Bank_Index,Page_Index,Page_Start_Add;203int Add_New,j;204char i;205206 Bank_Index = Add / BANK_SIZE;207 Page_Index = (Add % BANK_SIZE) / PAGE_SIZE;208 Page_Start_Add = Add % PAGE_SIZE;209 Add_New = (((Bank_Index<<6) | Page_Index)<<16) | Page_Start_Add; 210211 NAND512_CL_LOW;212 NAND512_AL_LOW;213 NAND512_W_HIGH;214 NAND512_R_HIGH;215 NAND512_CE_HIGH;216 NAND512_Delay_uS(10);217218 NAND512_CE_LOW;219 NAND512_Delay_uS(5);220 NAND512_CL_HIGH;221 NAND512_W_LOW;222 NAND512_DB_Write(0x00);223 NAND512_Delay_uS(5);224 NAND512_W_HIGH;225 NAND512_Delay_uS(5);226 NAND512_CL_LOW;227 NAND512_Delay_uS(5);228 NAND512_AL_HIGH;229 NAND512_Delay_uS(5);230231//发送地址232for(i=0;i<4;i++)233 {239 NAND512_Delay_uS(10);240 }241 NAND512_AL_LOW;242 NAND512_Delay_uS(5);243 NAND512_CL_HIGH;244 NAND512_Delay_uS(5);245 NAND512_W_LOW;246 NAND512_Delay_uS(5);247 NAND512_DB_Write(0x30);248 NAND512_Delay_uS(5);249 NAND512_W_HIGH;250 NAND512_Delay_uS(5);251 NAND512_CL_LOW;252 NAND512_Delay_uS(5);253254while(NAND512_RB_STATUS == 0);255 NAND512_Delay_uS(5);256257for(j=0;j<Len;j++)258 {259 NAND512_R_LOW;260 NAND512_Delay_uS(5);261 Buf[j] = NAND512_DB_Read();262 NAND512_Delay_uS(5);263 NAND512_R_HIGH;264 NAND512_Delay_uS(10);265 }266267return;268 }269270char NAND512_Page_Write(char* Buf,int Len,int Add)271 {272int Bank_Index,Page_Index,Page_Start_Add;273int Add_New,j;274char i,Status;275276 Bank_Index = Add / BANK_SIZE;277 Page_Index = (Add % BANK_SIZE) / PAGE_SIZE;278 Page_Start_Add = Add % PAGE_SIZE;279 Add_New = (((Bank_Index<<6) | Page_Index)<<16) | Page_Start_Add; 280281 NAND512_CL_LOW;282 NAND512_AL_LOW;283 NAND512_W_HIGH;284 NAND512_R_HIGH;285 NAND512_CE_HIGH;286 NAND512_Delay_uS(10);287288 NAND512_CE_LOW;289 NAND512_Delay_uS(5);290 NAND512_CL_HIGH;291 NAND512_W_LOW;292 NAND512_DB_Write(0x80);293 NAND512_Delay_uS(5);294 NAND512_W_HIGH;295 NAND512_Delay_uS(5);296 NAND512_CL_LOW;297 NAND512_Delay_uS(5);298 NAND512_AL_HIGH;299 NAND512_Delay_uS(5);300301//发送地址302for(i=0;i<4;i++)303 {304 NAND512_W_LOW;305 NAND512_Delay_uS(5);306 NAND512_DB_Write(Add_New>>8*i);307 NAND512_Delay_uS(10);308 NAND512_W_HIGH;309 NAND512_Delay_uS(10);310 }311 NAND512_AL_LOW;312 NAND512_Delay_uS(5);313314for(j=0;j<Len;j++)315 {316 NAND512_W_LOW;317 NAND512_Delay_uS(5);324 NAND512_CL_HIGH;325 NAND512_Delay_uS(5);326 NAND512_W_LOW;327 NAND512_Delay_uS(5);328 NAND512_DB_Write(0x10);329 NAND512_Delay_uS(5);330 NAND512_W_HIGH;331 NAND512_Delay_uS(5);332333while(NAND512_RB_STATUS == 0);334 NAND512_Delay_uS(5);335336 Status = NAND512_Read_Status();337338if((Status & 0x01) == 0)339return1;340else341return0;342 }343344char NAND512_Block_Erase(int Add)345 {346int Bank_Index,Page_Index;347int Add_New;348char i,Status;349350 Bank_Index = Add / BANK_SIZE;351 Page_Index = (Add % BANK_SIZE) / PAGE_SIZE; 352 Add_New = (Bank_Index<<6) | Page_Index;353354 NAND512_CL_LOW;355 NAND512_AL_LOW;356 NAND512_W_HIGH;357 NAND512_R_HIGH;358 NAND512_CE_HIGH;359 NAND512_Delay_uS(10);360361 NAND512_CE_LOW;362 NAND512_Delay_uS(5);363 NAND512_CL_HIGH;364 NAND512_W_LOW;365 NAND512_DB_Write(0x60);366 NAND512_Delay_uS(5);367 NAND512_W_HIGH;368 NAND512_Delay_uS(5);369 NAND512_CL_LOW;370 NAND512_Delay_uS(5);371 NAND512_AL_HIGH;372 NAND512_Delay_uS(5);373374//发送地址375for(i=0;i<2;i++)376 {377 NAND512_W_LOW;378 NAND512_Delay_uS(5);379 NAND512_DB_Write(Add_New>>8*i);380 NAND512_Delay_uS(10);381 NAND512_W_HIGH;382 NAND512_Delay_uS(10);383 }384 NAND512_AL_LOW;385 NAND512_Delay_uS(5);386387 NAND512_CL_HIGH;388 NAND512_Delay_uS(5);389 NAND512_W_LOW;390 NAND512_Delay_uS(5);391 NAND512_DB_Write(0xD0);392 NAND512_Delay_uS(5);393 NAND512_W_HIGH;394 NAND512_Delay_uS(5);395 NAND512_CL_LOW;396 NAND512_Delay_uS(5);397398while(NAND512_RB_STATUS == 0);399 NAND512_Delay_uS(5);400401 Status = NAND512_Read_Status();H⽂件内容:1 #ifndef NAND512W3A2C__H2#define NAND512W3A2C__H34 #include "stm32f10x.h"56#define NAND512_CL_PORT GPIOD7#define NAND512_AL_PORT GPIOD8#define NAND512_W_PORT GPIOD9#define NAND512_R_PORT GPIOD10#define NAND512_CE_PORT GPIOD11#define NAND512_RB_PORT GPIOB12#define NAND512_WP_PORT /*GPIOD*/1314#define NAND512_CL_PIN GPIO_Pin_615#define NAND512_AL_PIN GPIO_Pin_516#define NAND512_W_PIN GPIO_Pin_1417#define NAND512_R_PIN GPIO_Pin_1518#define NAND512_CE_PIN GPIO_Pin_719#define NAND512_RB_PIN GPIO_Pin_520#define NAND512_WP_PIN /*GPIO_Pin_5*/2122#define NAND512_CL_CLK RCC_APB2Periph_GPIOD23#define NAND512_AL_CLK RCC_APB2Periph_GPIOD24#define NAND512_W_CLK RCC_APB2Periph_GPIOD25#define NAND512_R_CLK RCC_APB2Periph_GPIOD26#define NAND512_CE_CLK RCC_APB2Periph_GPIOD27#define NAND512_RB_CLK RCC_APB2Periph_GPIOB28#define NAND512_WP_CLK /*RCC_APB2Periph_GPIOD*/2930#define NAND512_CE_LOW GPIO_ResetBits(NAND512_CE_PORT,NAND512_CE_PIN)31#define NAND512_CE_HIGH GPIO_SetBits(NAND512_CE_PORT,NAND512_CE_PIN)32#define NAND512_CL_LOW GPIO_ResetBits(NAND512_CL_PORT,NAND512_CL_PIN)33#define NAND512_CL_HIGH GPIO_SetBits(NAND512_CL_PORT,NAND512_CL_PIN)34#define NAND512_AL_LOW GPIO_ResetBits(NAND512_AL_PORT,NAND512_AL_PIN)35#define NAND512_AL_HIGH GPIO_SetBits(NAND512_AL_PORT,NAND512_AL_PIN)36#define NAND512_W_LOW GPIO_ResetBits(NAND512_W_PORT,NAND512_W_PIN)37#define NAND512_W_HIGH GPIO_SetBits(NAND512_W_PORT,NAND512_W_PIN)38#define NAND512_R_LOW GPIO_ResetBits(NAND512_R_PORT,NAND512_R_PIN)39#define NAND512_R_HIGH GPIO_SetBits(NAND512_R_PORT,NAND512_R_PIN)4041#define NAND512_RB_STATUS GPIO_ReadInputDataBit(NAND512_RB_PORT,NAND512_RB_PIN) 4243#define NOP __nop()44#define BANK_SIZE 13107245#define PAGE_SIZE 20484647extern void NAND512_IO_Init(void);48extern char NAND512_Read_Status(void);49extern void NAND512_Read_ID(char* Buf);50extern void NAND512_Page_Read(char* Buf,int Len,int Add);51extern char NAND512_Page_Write(char* Buf,int Len,int Add);52extern char NAND512_Block_Erase(int Add);53#endif。
关于STM32的FLASH操作
关于STM32的FLASH操作STM32是STMicroelectronics公司开发的一系列32位ARM Cortex-M微控制器。
在STM32微控制器中,FLASH (快闪存储器)是用于存储应用程序和数据的重要组件。
在本文中,我们将详细介绍STM32的FLASH操作。
1.FLASH简介:FLASH是一种可擦除可编程的非易失性存储器,常用于存储应用程序代码和数据。
STM32微控制器的FLASH存储器由多个扇区组成。
每个扇区的大小可以是1KB、2KB、4KB或16KB,具体取决于所使用的芯片型号。
FLASH的主要特点包括可擦除、可编程和快速存取。
2.FLASH的特点:2.1 可擦除:FLASH存储器中的数据可以通过擦除操作来清除。
擦除操作可以是扇区擦除(Sector Erase)或全片擦除(Mass Erase)。
扇区擦除只清除指定的扇区,而全片擦除则清除整个FLASH存储器。
2.2 可编程:FLASH存储器中的数据可以通过编程操作来写入。
编程操作可以是半字编程(Half-Word Program)或字编程(Word Program)。
半字编程一次可以写入16位的数据,而字编程一次可以写入32位的数据。
2.3快速存取:FLASH存储器具有快速存取速度,使得应用程序可以在很短的时间内从FLASH中读取数据。
3.FLASH操作注意事项:在进行STM32的FLASH操作时,需要注意以下几个方面:3.1对于每个扇区的擦除操作,只能在原来数据全为‘1’的情况下进行。
因此,在进行擦除操作之前,应该先将该扇区的数据写为全‘1’。
3.2进行编程操作时,只能将数据从‘1’写为‘0’,而不能将数据从‘0’写为‘1’。
因此,在进行编程操作之前,应该先将该数据所在的字节或半字擦除为全‘1’。
3.3FLASH存储器的数据写入操作需要采取双字节对齐的方式。
如果数据不是双字节对齐,则必须先将数据拷贝到对齐的缓冲区中,再进行编程操作。
stm32 flash读写例程
stm32 flash读写例程摘要:1.STM32 Flash存储器概述2.STM32 Flash读写操作步骤3.STM32 Flash读写实例4.注意事项正文:一、STM32 Flash存储器概述STM32 Flash存储器分为两个区域:系统区域和用户区域。
系统区域存储固件和启动代码,用户区域用于存储用户数据。
STM32提供了丰富的库函数和HAL(硬件层)驱动程序,方便开发者实现对Flash存储器的读写操作。
二、STM32 Flash读写操作步骤1.初始化:对Flash模块进行初始化,包括时钟、GPIO等。
2.擦除:在进行写入操作前,需要对目标区域进行擦除。
擦除方式以页为单位。
3.写入:将数据写入Flash存储器。
注意写入地址为奇数时可能会出错。
4.读取:从Flash存储器中读取数据。
三、STM32 Flash读写实例以下是一个简单的STM32 Flash读写实例:1.定义Flash 写入数据函数:```cvoid FlashWrite(uint32_t add, uint16_t dat) {// 打开Flash控制时钟RCCHSICMD(ENABLE);// 设置Flash写入地址FLASH_WriteAddress = add;// 写入16位数据FLASH_DataWrite(dat);// 等待Flash写入完成while (FLASH_BusyStatus != 0);// 关闭Flash控制时钟RCCHSICMD(DISABLE);}```2.定义Flash 读取数据函数:```cuint16_t FlashRead(uint32_t add){// 打开Flash控制时钟RCCHSICMD(ENABLE);// 设置Flash读取地址FLASH_ReadAddress = add;// 读取16位数据uint16_t data = FLASH_DataRead();// 关闭Flash控制时钟RCCHSICMD(DISABLE);return data;}```四、注意事项1.Flash 读写操作时,需注意地址和数据长度。
STM32使用FSMC控制NANDflash例程
STM32使用FSMC控制NANDflash例程本文原创于观海听涛,原作者版权所有,转载请注明出处。
近几天开发项目需要用到STM32驱动NAND FLASH,但由于开发板例程以及固件库是用于小页(512B),我要用到的FLASH为1G bit的大页(2K),多走了两天弯路。
以下笔记将说明如何将默认固件库修改为大页模式以驱动大容量NAND,并作驱动。
本文硬件:控制器:STM32F103ZET6,存储器:HY27UF081G2A首先说一下NOR与NAND存储器的区别,此类区别网上有很多,在此仅大致说明:1、Nor读取速度比NAND稍快2、Nand写入速度比Nor快很多3、NAND擦除速度(4ms)远快于Nor(5s)4、Nor 带有SRAM接口,有足够的地址引脚来寻址,可以很轻松的挂接到CPU地址和数据总线上,对CPU要求低5、NAND用八个(或十六个)引脚串行读取数据,数据总线地址总线复用,通常需要CPU支持驱动,且较为复杂6、Nor主要占据1-16M容量市场,并且可以片内执行,适合代码存储7、NAND占据8-128M及以上市场,通常用来作数据存储8、NAND便宜一些9、NAND寿命比Nor长10、NAND会产生坏块,需要做坏块处理和ECC更详细区别请继续百度,以上内容部分摘自神舟三号开发板手册下面是NAND的存储结构:由此图可看出NAND存储结构为立体式正如硬盘的盘片被分为磁道,每个磁道又分为若干扇区,一块nand flash也分为若干block,每个block分为如干page。
一般而言,block、page之间的关系随着芯片的不同而不同。
需要注意的是,对于flash的读写都是以一个page开始的,但是在读写之前必须进行flash 的擦写,而擦写则是以一个block为单位的。
我们这次使用的HY27UF081G2A其PDF介绍:Memory Cell Array= (2K+64) Bytes x 64 Pages x 1,024 Blocks由此可见,该NAND每页2K,共64页,1024块。
安富莱STM32F103ZE-EK开发板用户手册(V2.1)
安富莱S T M32F103Z E-E K开发板用户手册版本:V2.1安富莱电子开发网W W W.A R M F L Y.C O M友情提示:本文档是最新版硬件(REV 2.0)的用户手册,旧版硬件和新版硬件的差别请参考文档末尾的“硬件特殊说明”。
官方网站发布的软件主要针对新版硬件,REV 1.0版用户下载新版软件时,务必阅读“REV 2.0和REV1.0硬件差别”。
由于采购价格和采购渠道的差异,不同时间段出厂的板子配置的SRAM、NOR Flash和NandFlash的具体型号可能不同,但是容量是符合要求的。
光盘上提供的例程均支持所有曾经用到过的芯片。
1.产品规格简介STM32F103ZE-EK开发板以STM32F103ZET6(LQFP144)为核心。
STM32F103ZE 是ST(意法半导体)公司推出的ARM Crotex-M3产品线中功能最强大的一款CPU。
片内集成512kB Flash、64kB RAM、1个USB、1个CAN、 8个定时器、5个USART、3个ADC、2个DAC、3个SPI、2个I2C、2个I2S、1个SDIO、112个GPIO、FSMC总线(支持NOR,NAND,SRAM)。
CPU主频72MHz,广泛适用于各种应用场合。
本开发板具备丰富的硬件资源,配套的试验例程均提供源代码,文档齐备,非常适合于学习和项目评估。
硬件资源■ 8M晶振作为MCU的时钟,32768晶振用于RTC ■ 1M字节SRAM,16M字节NOR Flash,128M字节NADN Flash■ 2M字节串行Flash,256字节串行EEPROM■ 1个SD/MMC卡座■ 1个CAN2.0A/B接口■ 2个RS232串口■ 1个RS485接口■ 1个USB2.0全速DEVICE接口■ 1个USB2.0全速HOST接口■ 1个100M/10M以太网接口■ I2S音频CODEC(24bit,48kHz),1个立体声耳机插座,1个MIC插座,1个咪头,1个扬声器■ 3.0寸TFT真彩触摸LCD(WQVGA,400x240)■ 集成FM调频收音机模块■ 1个红外遥控接收模块,1个红外遥控发射器 ■ 1个5向摇杆,1个Reset按钮、1个wakeup按钮、1个自定义按钮■ 4个自定义LED,1个电源LED,1个音频LED■ 1个CR1220电池座■ 1个精密可调电阻连接到ADC输入■ 所有的GPIO引到2.54mm间距焊盘■ 1个DAC引出端子,1个PWM引出端子■ 标准2.54mm间距JTAG插座■ 2个BNC输入端子,集成双通道示波器电路,具备AC/DC切换、输入增益切换开关■ 3种供电方式:USB电缆、外接5V电源、JTAG 调试接口(J-LINK仿真器)■ 1个电源开关,上下电时无需拔插电缆■ 3种启动方式:用户Flash、系统存储器、SRAM ■ 用拨码开关取代跳线帽,避免跳线帽丢失■ 板子规格:14cm x 12cm软件资源■ 提供100多个试验例程■ 提供uCOS_II+ucGUI例程和文档■ 即将展开USB虚拟示波器项目源码■ 即将移植ucLinux (硬件资源已满足要求)■ 更多的软件资源将在发布包装清单(标配)■STM32F103ZE-EK开发板1块■ 3.0寸TFT触摸显示模块1块■1根串口线、1根网线、1根USB电缆■开发板配套光盘1张标配件实物:选配件实物:2.入门须知2.1.注意事项(1)外接电源必须是5.0V 的直流电源,插头有极性,内正外负。
STM32内部FLASH读写操作详解(附代码)
(2)擦除将要写的页STM32 的 FLASH 在编程的时候,也必须要求其写⼊地址的 FLASH 是被擦除了的(也就是其值必须是 0XFFFF),否则⽆法写⼊,在 FLASH_SR 寄存器的 PGERR 位将得到⼀个警告。
STM32 的闪存擦除分为两种:页擦除和整⽚擦除。
也就是其最⼩擦除单位为1页,尽管你只需往某页⾥写10个字节数据或者更少的数据,你也必须先擦除该页(2*1024个字节)。
我们这⾥使⽤按页擦除,固件库中按页擦除的函数为:左右滑动查看全部代码>>>/* 按页擦除 */FLASH_Status FLASH_ErasePage(uint32_t Page_Address);其返回值为枚举:左右滑动查看全部代码>>>typedef enum{ FLASH_BUSY = 1, /* 忙 */ FLASH_ERROR_PG, /* 编程错误 */FLASH_ERROR_WRP, /* 写保护错误 */ FLASH_COMPLETE, /* 操作完成 */FLASH_TIMEOUT /* 操作超时 */}FLASH_Status;(3)往上⼀步擦写成功的页写⼊数据STM32 闪存的编程每次必须写⼊16 位。
虽然固件库中有如下三个写操作的函数:左右滑动查看全部代码>>>FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data);FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data);FLASH_StatusFLASH_ProgramOptionByteData(uint32_t Address, uint8_t Data);分别为按字(32bit)写⼊、按半字(16bit)写⼊、按字节(8bit)写⼊函数。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
本文原创于观海听涛,原作者版权所有,转载请注明出处。
近几天开发项目需要用到STM32驱动NAND FLASH,但由于开发板例程以及固件库是用于小页(512B),我要用到的FLASH为1G bit的大页(2K),多走了两天弯路。
以下笔记将说明如何将默认固件库修改为大页模式以驱动大容量NAND,并作驱动。
本文硬件:控制器:STM32F103ZET6,存储器:HY27UF081G2A首先说一下NOR与NAND存储器的区别,此类区别网上有很多,在此仅大致说明:1、Nor读取速度比NAND稍快2、Nand写入速度比Nor快很多3、NAND擦除速度(4ms)远快于Nor(5s)4、Nor 带有SRAM接口,有足够的地址引脚来寻址,可以很轻松的挂接到CPU地址和数据总线上,对CPU要求低5、NAND用八个(或十六个)引脚串行读取数据,数据总线地址总线复用,通常需要CPU支持驱动,且较为复杂6、Nor主要占据1-16M容量市场,并且可以片内执行,适合代码存储7、NAND占据8-128M及以上市场,通常用来作数据存储8、NAND便宜一些9、NAND寿命比Nor长10、NAND会产生坏块,需要做坏块处理和ECC更详细区别请继续百度,以上内容部分摘自神舟三号开发板手册下面是NAND的存储结构:由此图可看出NAND存储结构为立体式正如硬盘的盘片被分为磁道,每个磁道又分为若干扇区,一块nand flash也分为若干block,每个block分为如干page。
一般而言,block、page之间的关系随着芯片的不同而不同。
需要注意的是,对于flash的读写都是以一个page开始的,但是在读写之前必须进行flash 的擦写,而擦写则是以一个block为单位的。
我们这次使用的HY27UF081G2A其PDF介绍:Memory Cell Array= (2K+64) Bytes x 64 Pages x 1,024 Blocks由此可见,该NAND每页2K,共64页,1024块。
其中:每页中的2K为主容量Data Field,64bit为额外容量Spare Field。
Spare Field用于存贮检验码和其他信息用的,并不能存放实际的数据。
由此可算出系统总容量为2K*64*1024=134217728个byte,即1Gbit。
NAND闪存颗粒硬件接口:由此图可见,此颗粒为八位总线,地址数据复用,芯片为SOP48封装。
软件驱动:(此部分写的是伪码,仅用于解释含义,可用代码参见附件)主程序:1. #define BUFFER_SIZE 0x2000 //此部分定义缓冲区大小,即一次写入的数据2. #define NAND_HY_MakerID 0xAD //NAND厂商号3. #define NAND_HY_DeviceID 0xF1 //NAND器件号4. /*配置与SRAM连接的FSMC BANK2 NAND*/5. NAND_Init();6. /*读取Nand Flash ID并打印*/7. NAND_ReadID(&NAND_ID);复制代码Tips:NAND器件的ID包含四部分:1st Manufacturer Code2nd Device Identifier3rd Internal chip number, cell Type, Number of Simultaneously Programmedpages.4th Page size, spare size, Block size, Organization1. if((NAND_ID.Maker_ID == NAND_HY_MakerID) && (NAND_ID.Device_ID == NAND_HY_DeviceID)) //判断器件符合2. {3. /*设置NAND FLASH的写地址*/4. WriteReadAddr.Zone = 0x00;5. WriteReadAddr.Block = 0x00;6. WriteReadAddr.Page = 0x05;7. /*擦除待写入数据的块*/8. status = NAND_EraseBlock(WriteReadAddr); //写入前必须擦出9. /*将写Nand Flash的数据BUFFER填充为从0x25开始的连续递增的一串数据*/10. Fill_Buffer(TxBuffer, BUFFER_SIZE , 0x25); //填充数据以测试11. /*将数据写入到Nand Flash中。
WriteReadAddr:读写的起始地址*/12. status = NAND_WriteSmallPage(TxBuffer, WriteReadAddr, PageNumber); //主要写入函数,此部分默认为小页需要修改13. /*从Nand Flash中读回刚写入的数据。
riteReadAddr:读写的起始地址*/14. status = NAND_ReadSmallPage (RxBuffer, WriteReadAddr, PageNumber); //读取主要函数,也需要修改15.16. /*判断读回的数据与写入的数据是否一致*/17. for(j = 0; j < BUFFER_SIZE; j++)18. {19. if(TxBuffer[j] != RxBuffer[j])20. {21. WriteReadStatus++;22. }23. }24.25. if (WriteReadStatus == 0)26. {27. printf("\n\r Nand Flash读写访问成功");28. GPIO_ResetBits(GPIO_LED, DS2_PIN);29. }30. else31. {32. printf("\n\r Nand Flash读写访问失败");33. printf("0x%x",WriteReadStatus);34.35. GPIO_ResetBits(GPIO_LED, DS3_PIN);36.37. }38. }39. else40. {41. printf("\n\r 没有检测到Nand Flash的ID");42. GPIO_ResetBits(GPIO_LED, DS4_PIN);43. }复制代码fsmc_nand.c文件:1. void NAND_Init(void)2. {3. GPIO_InitTypeDef GPIO_InitStructure;4. FSMC_NAND_PCCARDTimingInitTypeDef p;5. FSMC_NANDInitTypeDef FSMC_NANDInitStructure;6.7. /*FSMC总线使用的GPIO组时钟使能*/8. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE |9. RCC_APB2Periph_GPIOF | RCC_APB2Periph_GPIOG, ENABLE);10.11. /*FSMC CLE, ALE, D0->D3, NOE, NWE and NCE2初始化,推挽复用输出*/12. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11 | GPIO_Pin_12 | GPIO_Pin_14 | GPIO_Pin_15 |13. GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_4 | GPIO_Pin_5 |14. GPIO_Pin_7;15. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;16. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;17. GPIO_Init(GPIOD, &GPIO_InitStructure);18. /*FSMC数据线FSMC_D[4:7]初始化,推挽复用输出*/19. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9 | GPIO_Pin_10;20. GPIO_Init(GPIOE, &GPIO_InitStructure);21. /*FSMC NWAIT初始化,输入上拉*/22. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;23. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;24. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;25. GPIO_Init(GPIOD, &GPIO_InitStructure);26. /*FSMC INT2初始化,输入上拉*/27. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6;28. GPIO_Init(GPIOG, &GPIO_InitStructure);29. /*--------------FSMC 总线存储器参数配置------------------------------*/30. p.FSMC_SetupTime = 0x1; //建立时间31. p.FSMC_WaitSetupTime = 0x3; //等待时间32. p.FSMC_HoldSetupTime = 0x2; //保持时间33. p.FSMC_HiZSetupTime = 0x1; //高阻建立时间34. FSMC_NANDInitStructure.FSMC_Bank = FSMC_Bank2_NAND; //使用FSMC BANK235. FSMC_NANDInitStructure.FSMC_Waitfeature = FSMC_Waitfeature_Enable; //使能FSMC的等待功能36. FSMC_NANDInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_8b; //NAND Flash的数据宽度为8位37. FSMC_NANDInitStructure.FSMC_ECC = FSMC_ECC_Enable; //使能ECC特性38. FSMC_NANDInitStructure.FSMC_ECCPageSize = FSMC_ECCPageSize_2048Bytes; //ECC页大小204839. FSMC_NANDInitStructure.FSMC_TCLRSetupTime = 0x00;40. FSMC_NANDInitStructure.FSMC_TARSetupTime = 0x00;41. FSMC_NANDInitStructure.FSMC_CommonSpaceTimingStruct = &p;42. FSMC_NANDInitStructure.FSMC_AttributeSpaceTimingStruct = &p;43. FSMC_NANDInit(&FSMC_NANDInitStructure);44. /*!使能FSMC BANK2 */45. FSMC_NANDCmd(FSMC_Bank2_NAND, ENABLE);46. }复制代码1. void NAND_ReadID(NAND_IDTypeDef* NAND_ID)2. {3. uint32_t data = 0;4. /*!< Send Command to the command area */5. *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = 0x90;6. *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;7. /*!< Sequence to read ID from NAND flash */8. data = *(__IO uint32_t *)(Bank_NAND_ADDR | DATA_AREA);9. NAND_ID->Maker_ID = ADDR_1st_CYCLE (data);//四个周期读取四个ID10. NAND_ID->Device_ID = ADDR_2nd_CYCLE (data);11. NAND_ID->Third_ID = ADDR_3rd_CYCLE (data);12. NAND_ID->Fourth_ID = ADDR_4th_CYCLE (data);13. }复制代码1. uint32_t NAND_WriteSmallPage(uint8_t *pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite)2. {//传入参数:写入数据,写入初始地址,要写几页3. uint32_t index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;4. uint32_t status = NAND_READY, size = 0x00;5. while((NumPageToWrite != 0x00) && (addressstatus == NAND_VALID_ADDRESS) && (status == NAND_READY))6. {7. /*!< Page write command and address */8. *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_AREA_A;9. *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE0;10. *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;11. *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = 0x00;//添加此句12. *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);13. *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);14. // *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);//原版有此句15. /*!< Calculate the size */16. size = NAND_PAGE_SIZE + (NAND_PAGE_SIZE * numpagewritten);//统计写入数目17. /*!< Write data */18. for(; index < size; index++)19. {20. *(__IO uint8_t *)(Bank_NAND_ADDR | DATA_AREA) = pBuffer[index];21. }22.23. *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_WRITE_TRUE1;24. /*!< Check status for successful operation */25. status = NAND_GetStatus();26.27. if(status == NAND_READY)28. {29. numpagewritten++;30. NumPageToWrite--;31. /*!< Calculate Next small page Address */32. addressstatus = NAND_AddressIncrement(&Address);33. }34. }35.36. return (status | addressstatus);37. }复制代码读取函数同理修改1. uint32_t NAND_EraseBlock(NAND_ADDRESS Address)2. {3. *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE0;4. *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_1st_CYCLE(ROW_ADDRESS);5. *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_2nd_CYCLE(ROW_ADDRESS);6. // *(__IO uint8_t *)(Bank_NAND_ADDR | ADDR_AREA) = ADDR_3rd_CYCLE(ROW_ADDRESS);//两次即可7. *(__IO uint8_t *)(Bank_NAND_ADDR | CMD_AREA) = NAND_CMD_ERASE1;8. return (NAND_GetStatus());9. }复制代码fsmc_nand.h文件:1. #define NAND_PAGE_SIZE ((uint16_t)0x0800) /* 512 bytes per page w/o Spare Area *///每页2K2. #define NAND_BLOCK_SIZE ((uint16_t)0x0040) /* 32x512 bytes pages per block *///64个页3. #define NAND_ZONE_SIZE ((uint16_t)0x0400) /* 1024 Block per zone *///1024个快4. #define NAND_SPARE_AREA_SIZE ((uint16_t)0x0040) /* last 16 bytes as spare area */5. #define NAND_MAX_ZONE ((uint16_t)0x0001) /* 4 zones of 1024 block */复制代码修改完即可实现512B至2K每页的变更。