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存储器进行读写操作的例程,从开发环境准备到代码编写再到调试运行都有详细的步骤说明,并给出了注意事项和总结。
- 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每页的变更。