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块。

其中:每页中的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 == 026. {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(void2. {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_ID2. {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 NumPageToWrite2. {//传入参数:写入数据,写入初始地址,要写几页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_READY6. {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_READY28. {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 Address2. {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. 2. 3. 4. 5. #define NAND_PAGE_SIZE #define NAND_BLOCK_SIZE #define NAND_ZONE_SIZE #defineNAND_SPARE_AREA_SIZE #define NAND_MAX_ZONE ((uint16_t0x0800 /* 512 bytes per page w/o Spare Area */// 每页 2K ((uint16_t0x0040 /* 32x512 bytes pages per block *///64 个页 ((uint16_t0x0400 /* 1024 Block per zone *///1024 个快((uint16_t0x0040 /* last 16 bytes as spare area */ ((uint16_t0x0001 /* 4 zones of 1024 block */ 复制代码修改完即可实现 512B 至 2K 每页的变更。

合集下载

STM32F使用内部FLASH程序详解

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

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控制器分析和代码

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]。

20-STM32CubeMX系列教程20-Nand Flash

20-STM32CubeMX系列教程20-Nand Flash
FMC 配置 NAND Flash 如下:使能 ECC 校验,建立保存等待等时间参数设置可以见上一节的 时序图时间参数。 FMC 是挂载到 AHB 时钟线上,频率等于系统时钟频率,即 216M,时钟周期为 1 /216 MHz = ~4.6ns。 NAND 属性信息根据前面介绍的 K91FG080U0E 存储结构配置。
/* 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 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中程序的步骤

通过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

STM32内部FLASH读写操作详解

STM32芯片内部的FLASH存储器,主要用于存储我们代码。

如果内部FLASH存储完我们的代码还有剩余的空间,那么这些剩余的空间我们就可以利用起来,存储一些需要掉电保存的数据。

本文以STM32103ZET为例。

STM32103ZET属于大容量产品,其闪存模块组织如下:其主存储器大小为512KB分为256页,每页大小都为2KB我们的程序般默认烧写到第0页的起始地址(0x08000000)处。

当BOOT引脚和BOOT引脚都接GND寸,就是从这个地址开始运行代码的。

这个地址在keil中可以看到:F 面对STM32内部FLASH 进行简单的读写测试:内部FLASH 读写测试 流程图如下:本流程图省略异常情况,只考虑成功的情况:f-Q Options for Target 'FLASH'一丄Utvice Til i«l I Output ] Li itinc | Ustr | C/C++ | AsmLinker Debue Vtiiitws\tSTHicroetedonici SR32F103ZEOpef^g syseiTi : |Sysem \^ewer Rle.{MHi): Bll-Cod* GeniFon —ARM Compter: | Use default cwnpiter veraion 5刁厂 Lse Cjoss-^ottile OrtimiiatorIv Lse Micro LIBotCancelCeCa-olts Help假如我们要下载的程序大小为4.05KB , 则第0、1、2页用于保存我们的程序,我们需要掉电保存的数据只能保存在第 3~第255页这一部分空间内。

我们最终要下载的程序大小可在工程对应的 .map 文件中看到。

.map 文件可以双击工程的Target 的名字快速打开,如:hrlphdrt Tool ; SVM 応 inJ 艸 hti 単 ,-■k ,A 弟=*七住」Mitw J 咖3口知,樹;卜( J... —. ■丹 Ft E4R vl«* PiQjtit “Ml Dtbug•ffli11 htBj£画 IF b.农-I r sj fLASj- In 討mi■. 1.7 viieiiii '.L二KP;L 叭1祠£ -L 二El 仍恤■走r二匚 top.gt £Jt±』CMS5三Q StriPaiph thr.ci二uc4114出, + e 4H ULiJry T'^CiJbd Mt*LMb|HELL ・md " D*fca ] ■W Egf icrtBli 畤TCT P Hmucfi>n 3 Hlih —b kp C b4i-i3 Jhdn_c.driR.Hbloral HD Size Ifodt + ・□ palFl*Total R>I 51■疋c £RM Eta - Zr TZatJ) Totdg flW S 上电 jt 屁It + 觀尿H * 也 G SU TL Use CustziEFife示例代码:本例的关键代码如下(以读写第255页为例):/******************************************************************************************************** -------------------------------------- STM32 Demo ------------------------工程说明:STM32内部FLASH实验作者:ZhengNian博客: zhengnianli.github.io公众号:嵌入式大杂烩********************************************************************************************************/#defi ne MAIN_CONFIG#i nclude "con fig.h"/* STM32F103ZET6有256页,每一页的大小都为2KB */#defi ne ADDR_FLASH _P AGE_255 ((ui nt32_t)0x0807F800) /* Page255 2KB *//* FLASH读写测试结果*/#defi ne #defi ne #defi ne/* Flash 读写测试buf */ #defi ne BufferSize 6ui nt16_t usFlashWriteBuf[BufferSize]= {0x0101,0x0202,0x0303,0x0404,0x0505,0x0606}; ui nt16_t usFlashReadBuf[BufferSize] = {0};/*供本文件调用的函数声明*/ static int FlashReadWriteTest(void);*********************************** ** 函数:main参数:void 返回:无 说明:主函数********************************************************************* ***********************************/ int main(v oid) {/*上电初始化*/ Sysl nit();/*内部Flash 读写测试*/if (TEST_SUCCESS == FlashReadWriteTest()) prin tf("Flash test success!' n"); } else {prin tf("Flash test failed!\n"); } while (1) {} }*************************************函数:FlashReadWriteTest ,内部Flash 读写测试函数 ** 参数:void**返回:TEST_ERROR :错误(擦除、写入错误) TEST_SUCCESS:成功TEST_FAILED :失败 **说明:无********************************************************************************************************/ static int FlashReadWriteTest(void) {TEST_ERROR -1 TEST_SUCCESS 0 TEST_FAILED 1 /*/*错误(擦除、写入错误)*/ /*成功*/失败*/uin t32_t ucStartAddr;/*解锁*/FLASH_U nIockO;/*擦除操作*/ ucStartAddr = ADDR_FLASH _P AGE_255;if (FLASH_CO MP LETE != FLAsH_Erase Page(ucStartAddr)) { prin tf("Erase Error!\n"); return TEST_ERROR;}elseucStartAddr = ADDR_FLASH _P AGE_255;printf("擦除成功,此时FLASH中值为:\n");for (i nt i = 0; i < BufferSize; i++){usFlashReadBuf[i] = *(ui nt32_t*)ucStartAddr;prin tf("ucFlashReadBuf[%d] = 0x%.4x\n", i, usFlashReadBuf[i]); ucStartAddr += 2;}}/*写入操作*/ucStartAddr = ADDR_FLASH _P AGE_255;printf("\n往FLASH中写入的数据为:\n");for (i nt i = 0; i < BufferSize; i++){if (FLASH_CO MP LETE != FLASH _P rogramHalfWord(ucStartAddr, usFlashWriteBuf[i])) {prin tf("Write Error!\n");return TEST_ERROR;} "prin tf("ucFlashWriteBuf[%d] = 0x%.4x\n", i, usFlashWriteBuf[i]); ucStartAddr += 2;} /*上锁*/ FLASH_Lock();/*读取操作*/ucStartAddr = ADDR_FLASH _P AGE_255;printf("\n 从FLASH 中读出的数据为:\n"); for (i nt i = 0; i < BufferSize; i++) {usFlashReadBuf[i] = *(__10 uin t16_t*)ucStartAddr;prin tf("ucFlashReadBuf[%d] = 0x%.4x\n", i, usFlashReadBuf[i]); ucStartAddr += 2; }/*读出的数据与写入的数据做比较*/ for (i nt i = 0; i < BufferSize; i++) {if (usFlashReadBuf[i] != usFlashWriteBuf[i]) {return TEST_FAILED; } }return TEST_SUCCESS; }/******************************************************************** *************************************** End Of File********************************************************************* ***********************************/(1)进行解锁操作STM32的闪存编程是由内嵌的闪存编程/擦除控制器(FPEC )管理,这个模块包含的寄存器如下:STM32复位后,FPEC 模块是被保护的, 不能写入FLASH_CR 寄存器;通 过写入特定的序列到FLASH_KEYF 寄存器可以打开FPEC 模块(即写入KEY1和KEY2 ,只有在写保护被解除后,我们才能操作相关寄存器。

STM32闪存编程手册


页2/21
术语
下面列出了本文档中所用到的术语和缩写的简要说明:
z 小容量产品是指闪存存储器容量在16K~32K字节之间的STM32F101xx,STM32F102xx和 STM32F103xx微控制器产品。
z 中容量产品是指闪存存储器容量在64K~128K字节之间的STM32F101xx,STM32F102xx 和STM32F103xx微控制器产品。
PM0042 编程手册
STM32F10xxx闪存编程
简介
本编程手册介绍了如何烧写STM32F101xx、STM32F102xx和STM32F103xx微控制器的闪存存 储器。为方便起见,在本文中出特别说明外,统称它们为STM32F10xxx。 STM32F10xxx内嵌的闪存存储器可以用于在线编程(ICP)或在程序中编程(IAP)烧写。 在线编程(In-Circuit Programming – ICP)方式用于更新闪存存储器的全部内容,它通过JTAG、 SWD协议或系统加载程序(Bootloader)下载用户应用程序到微控制器中。ICP是一种快速有效的 编程方法,消除了封装和管座的困扰。 与ICP方式对应,在程序中编程(In-Application Programming – IAP)可以使用微控制器支持的任 一种通信接口(如I/O端口、USB、CAN、UART、I2C、SPI等)下载程序或数据到存储器中。IAP 允许用户在程序运行时重新烧写闪存存储器中的内容。然而,IAP要求至少有一部分程序已经 使用ICP烧到闪存存储器中。 闪存接口是在AHB协议上实现了对指令和数据的访问,它通过对存储器的预取缓存,加快了存 储器的访问;闪存接口还实现了在所有工作电压下对闪存编程和擦除所需的逻辑电路,这里还 包括访问和写入保护以及选项字节的控制。

STM32F103VE-FSMC 的设置

33 - HSYNC 34 - LEDA 35 - LED1 36 - LED2 37 - LED3 38 - LED4 39 - X+ 40 - Y+
41 - X- 42 - Y- 43 - GND 44 - GND 45 - VCC
*/
void LCD_CtrlLinesConfig(void)
/*设置存储器类型*/
FSMC_NORSRAMInitStructure.FSMC_MemoryType = FSMC_MemoryType_SRAM;
/*设置数据宽度*/
FSMC_NORSRAMInitStructure.FSMC_MemoryDataWidth = FSMC_MemoryDataWidth_16b;
p.FSMC_AddressHoldTime = 1; /*ADDHOLD 地址保持时间*/
p.FSMC_DataSetupTime = 20; /*DATAST 数据建立时间*/
p.FSMC_BusTurnAroundDuration = 0; /*BUSTURN 总线返转时间*/
p.FSMC_CLKDivision = 0; /*CLKDIV 时钟分频*/
* Function Name : LCD_FSMCConfig
* Description : Configures the Parallel interface (FSMC) for LCD(Parallel mode)
* Input : None
* Output : None
* Return : None
/* Set PD.00(D2), PD.01(D3), PD.04(NOE), PD.05(NWE), PD.07(NE1), PD.08(D13),
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档