0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用MM32F3270 FSMC驱动外部NOR Flash

jf_pJlTbmA9 来源:灵动MM32MCU 作者:灵动MM32MCU 2023-09-21 17:37 次阅读

MM32系列微控制器为用户提供了丰富的选择,可适用于工业控制智能家电、建筑安防、医疗设备以及消费类电子产品等多方位嵌入式系统设计。在某些应用中,需要较大容量的存储空间用于存储数据;这时可以通过SPI 外扩NOR Flash,NAND Flash, 或者通过SDIO扩展SD Card或TF-Card。但有些需要高速存储数据,上述方式还是不够快速,这时可以使用MM32F3270系列的FSMC来外扩并行NOR Flash来实现。

并行NOR Flash与并行SRAM和PSRAM的读写接口大部分相同,但NOR Flash的写入速度与SRAM和PSRAM比较,相对较慢,需要通过NWAIT 信号检查NOR Flash的操作状态,并做一些等待,相应的时序需要根据不同的NOR Flash芯片所规定的参数而做相应的设置即可。

本文接下来就使用MM32F3270外挂S29GL128P NOR Flash芯片来演示FSMC对NOR Flash芯片的设置与读写。

前文已经介绍了MM32F3270的FSMC的接口功能与特色。结合MM32F3270 的FSMC外部接口信号,可使用异步方式访问NOR Flash,可以选用复用或非复用方式扩展NOR Flash,还可以通过配置实现外扩8位总线或16位总线接口的NOR Flash。

wKgZomUD8zqAZJh8AAAid0QA-Go866.png 表1:FSMC控制器外部信号

MM32F3270系列MCU因为封装的原因,导致只有部分MCU产品可以通过硬件复用出全部或部分的FSMC接口的相关GPIO;外扩NOR Flash也只有使用 LQFP144引脚封装MCU芯片才能支持连接地址数据非复用和复用方式外扩并行NOR Flash;而LQFP100引脚封装芯片因地址线缩减,仅支持连接地址数据复用方式外扩并行NOR Flash。LQFP64因为无法引出足够的地址与数据总线,同样不支持外扩并行NOR Flash。

wKgZomUD89KAFD08AAAavXOcho8603.png 表2:MM32F3270不同封装芯片与NOR Flash接口

目前市场上非复用型16位数据总线接口的NOR Flash也是较为普遍,下面针对非复用方式,介绍MCU与NOR Flash的硬件原理图设计和软件寄存器配置。

在此用MM32F3270的FSMC接口扩展S29GL128P NOR Flash,其原理框图如下:

wKgaomUD89SAIoZmAAJA-neW5uY909.png 图1:NOR Flash原理框图

S29GL128P的数据按 16 位的Half Word寻址,容量128M Bit, 16M字节,从芯片手册中可以查询到S29GL128P的引脚功能描述如下:

wKgZomUD89WAcf6qAAUO9sl4L9o720.png 表3:NOR Flash引脚信号

S29GL128P可以通过CS, OE, WR, WP#, RY/BY#控制电路,结合Address与Data I/O实现对NOR Flash的读写操作。

1、FSMC非复用方式控制NOR Flash的硬件设计

wKgZomUD89aAQj5xAABpf8qvi9c372.png 表4:NOR Flash数据, 地址, 读写信号与MCU接口的引脚说明

外部设备地址映像从FSMC的角度看,FSMC外扩寻址空间用于访问最多4个FSMC地址映射空间,可以用于访问4个NOR闪存或SRAM/PSRAM存储设备,并对应的有4个专用的片选FSMC_NE[4:1]。

外部存储器划分为固定大小为64M字节的四个存储块,见下图。

wKgaomUD89iAccUZAAAMsiGarK0040.png

存储区块与片选信号对应关系:

wKgZomUD89mAb5WVAAAPxAV-oxI832.png

HADDR是需要转换到外部存储器的内部AHB地址线。HADDR[25:0]包含外部存储器地址。HADDR是字节地址,而存储器访问不都是按字节访问,因此接到存储器的地址线依存储器的数据宽度有所不同,如下表:

wKgaomUD89uAU1mpAAASelpXpcU760.png

对于16位宽度的外部存储器,FSMC将在内部使用HADDR[25:1]产生外部存储器的地址FSMC_A[24:0]。不论外部存储器的宽度是多少(16位或8位),FSMC_A[0]始终应该连到外部存储器的地址线A[0]。

根据外部NOR Flash设计原理图:

wKgaomUD89-AOyJLAAmS5t-MAgo357.png

2、FSMC非复用方式控制NOR Flash的程序设计

根据配置的接口电路配置GPIO初始化程序与FSMC初始化程序。

void FSMC_NOR_Init(void)
{
    FSMC_InitTypeDef  FSMC_InitStructure;
    FSMC_NORSRAM_Bank_InitTypeDef  FSMC_BankInitStructure;

    FSMC_NORSRAM_BankStructInit( FSMC_BankInitStructure);
    FSMC_NORSRAMStructInit( FSMC_InitStructure);
    RCC_AHB3PeriphClockCmd(RCC_AHB3ENR_FSMC, ENABLE);

    FSMC_BankInitStructure.FSMC_SMReadPipe    = 0;
    FSMC_BankInitStructure.FSMC_ReadyMode     = 0;
    FSMC_BankInitStructure.FSMC_WritePeriod   = 15;
    FSMC_BankInitStructure.FSMC_WriteHoldTime = 3;
    FSMC_BankInitStructure.FSMC_AddrSetTime   = 3;
    FSMC_BankInitStructure.FSMC_ReadPeriod    = 15;
    FSMC_BankInitStructure.FSMC_DataWidth     = FSMC_DataWidth_16bits;
    FSMC_NORSRAM_Bank_Init( FSMC_BankInitStructure, 
    FSMC_NORSRAM_BANK1);

    FSMC_InitStructure.FSMC_Mode = FSMC_Mode_NorFlash;
    FSMC_InitStructure.FSMC_TimingRegSelect = FSMC_TimingRegSelect_0;
    FSMC_InitStructure.FSMC_MemSize = FSMC_MemSize_64MB;
    FSMC_InitStructure.FSMC_MemType = FSMC_MemType_FLASH;
    FSMC_InitStructure.FSMC_AddrDataMode = FSMC_AddrDataDeMUX;
    FSMC_NORSRAMInit( FSMC_InitStructure);
}

GPIO初始化

void FSMC_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_StructInit( GPIO_InitStructure);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
    RCC_AHBPeriphClockCmd(RCC_AHBENR_GPIOB | RCC_AHBENR_GPIOC | 
    RCC_AHBENR_GPIOA | RCC_AHBENR_GPIOD | RCC_AHBENR_GPIOE | 
    RCC_AHBENR_GPIOF | RCC_AHBENR_GPIOG, ENABLE);

    GPIO_PinAFConfig(GPIOD, GPIO_PinSource4, GPIO_AF_12);  //NOE
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource5, GPIO_AF_12);  //NWE
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource6, GPIO_AF_12);  //NWAIT
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource11, GPIO_AF_12); //A16
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource12, GPIO_AF_12); //A17
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource13, GPIO_AF_12); //A18
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource14, GPIO_AF_12); //D0
    GPIO_PinAFConfig(GPIOD, GPIO_PinSource15, GPIO_AF_12); //D1
    //省略部分代码
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource0, GPIO_AF_12);  //A0
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource1, GPIO_AF_12);  //A1
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource2, GPIO_AF_12);  //A2
    GPIO_PinAFConfig(GPIOF, GPIO_PinSource3, GPIO_AF_12);  //A3
    //省略部分代码
    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_All;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
    GPIO_Init(GPIOD,  GPIO_InitStructure);

    GPIO_InitStructure.GPIO_Pin  =  GPIO_Pin_6;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_FLOATING;
    GPIO_Init(GPIOD,  GPIO_InitStructure);

    //省略部分代码

}

从选择的片选信号与FSMC外扩存储映像空间可以得出Bank2地址为0x64000000,使用该地址作为读写外部NOR Flash的基地址。

#define NOR_FLASH_START_ADDR       ((u32)0x64000000)
#define NOR_FLASH_END_ADDR         ((u32)0x67FFFFFF)
//读一个半字
u16 FSMC_NOR_ReadHalfWord(u32 ReadAddr)
{
    NOR_WRITE(ADDR_SHIFT(0x00555), 0x00AA);
    NOR_WRITE(ADDR_SHIFT(0x002AA), 0x0055);
    NOR_WRITE((NOR_FLASH_START_ADDR + ReadAddr), 0x00F0 );
/* exit autoselect (write reset command) */
    return (*(vu16*)((NOR_FLASH_START_ADDR + ReadAddr)));
}
//连续读一块半字数据
void FSMC_NOR_ReadBuffer(u16* pBuffer, u32 ReadAddr, u32 NumHalfwordToRead)
{
    NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
    NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
    NOR_WRITE((NOR_FLASH_START_ADDR + ReadAddr), 0x00F0);
/* exit autoselect (write reset command) */
    for(; NumHalfwordToRead != 0x00; NumHalfwordToRead--) {
        // Read a Halfword from the NOR
        *pBuffer++ = *(vu16*)((NOR_FLASH_START_ADDR + ReadAddr));
        ReadAddr = ReadAddr + 2;
    }
}

读写外部NOR Flash与读写外部SRAM的操作,地址寻址方式是一样的,但NOR Flash的写数据有较大的不同。

以单个Word编程为例,如下为写单个Word的流程图与实现代码:

wKgaomUD8-GATKFvAAGOoGAeqs4915.png

NOR_Status FSMC_NOR_WriteHalfWord(u32 WriteAddr, u16 Data)
{
    NOR_WRITE(ADDR_SHIFT(0x0555), 0x00AA);
    NOR_WRITE(ADDR_SHIFT(0x02AA), 0x0055);
    NOR_WRITE(ADDR_SHIFT(0x0555), 0x00A0);
    NOR_WRITE((NOR_FLASH_START_ADDR + WriteAddr), Data);

    return (FSMC_NOR_GetStatus(Program_Timeout));
}

通过MindMotion的官网下载MM32F3270 lib_Samples:

工程路径如下:

~MM32F327x_SamplesLibSamplesFSMCFSMC_NOR

可以看到详细的样例与功能操作。

下章的题目为《使用MM32F3270 的FSMC驱动外部OLED》讲解通过FSMC外扩并口OLED的实现。

来源:灵动MM32MCU
免责声明:本文为转载文章,转载此文目的在于传递更多信息,版权归原作者所有。本文所用视频、图片、文字如涉及作品版权问题,请联系小编进行处理

审核编辑 黄宇

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 芯片
    +关注

    关注

    453

    文章

    50383

    浏览量

    421716
  • NOR flash
    +关注

    关注

    2

    文章

    89

    浏览量

    22977
  • FSMC
    +关注

    关注

    0

    文章

    55

    浏览量

    38107
收藏 人收藏

    评论

    相关推荐

    灵动微课堂 (第188讲) | 使用MM32F3270 FSMC驱动TFT-LCD

    的需求在全世界范围内极大增长。本文介绍了如何使用 MM32F3270FSMC(灵活的静态存储控制器)来驱动8080接口的TFT-LCD。 01 MM32F3270
    发表于 10-29 17:12

    MM32F3270系列32位MCU的特点有哪些

    上海灵动微电子推出全新主流型MM32F3270系列32位MCU,此款MM32F3270系列是基于M3内核的32位微控制器,MM32F3270适用于要求高集成度的高性能控制领域,如:工业控制、消防监控
    发表于 11-03 07:20

    灵动微课堂 (第189讲) | 使用MM32F3270 FSMC驱动SRAM

    _SRAM\下章的题目为《使用MM32F3270FSMC驱动外部NOR Flash》讲解通过
    发表于 11-10 09:22

    灵动微课堂 (第190讲) | 使用MM32F3270 FSMC驱动外部NOR Flash

    演示FSMCNOR Flash芯片的设置与读写。前文已经介绍了MM32F3270FSMC的接口功能与特色。结合
    发表于 11-19 09:29

    灵动微课堂 (第191讲) | 使用MM32F3270 FSMC驱动OLED

    了如何使用 MM32F3270FSMC(灵活的静态存储控制器)来驱动6800接口的OLED。1//MM32F3270 FSMC的简要介绍
    发表于 11-29 10:45

    如何采用MM32F3270单片机的FSMC接口来扩展SRAM

    够支持应用的需要,就要用外扩SRAM/PSRAM的方式来扩展。这时可以采用MM32F3270片内的FSMC接口来扩展SRAM/PSRAM。   灵动微MM32F3270系列32位MCU是基于M3内核
    发表于 11-19 16:32 642次阅读

    【国产MCU移植】MM32F3270 EVBoard

    【国产MCU移植】MM32F3270 EVBoard
    发表于 12-03 17:21 5次下载
    【国产MCU移植】<b class='flag-5'>MM32F3270</b> EVBoard

    MM32F3270控制器的主要特点

    灵动微全新主流型MM32F3270系列32位MCU现已开始批量供货。该系列MCU搭载了M3内核,主频最高可达120兆赫兹,提供最高512KB Flash和128KB SRAM,并集成了丰富的通信接口
    发表于 12-07 17:26 1231次阅读

    使用MM32F3270单片机FSMC驱动外部NORFlash

    还是不够快速,这时可以使用MM32F3270系列的FSMC来外扩并行NOR Flash来实现。   并行NOR
    发表于 12-07 17:31 787次阅读

    基于MM32F3270 以太网 Client使用

    接下来给大家介绍基于TCP包的通讯。内容分为基于MM32F3270以太网Client的使用与基于MM32F3270以太网Server的使用。
    发表于 02-08 15:10 0次下载
    基于<b class='flag-5'>MM32F3270</b> 以太网 Client使用

    MM32F3270 ADC注入通道

    MM32F3270 ADC注入通道
    的头像 发表于 09-27 15:59 949次阅读
    <b class='flag-5'>MM32F3270</b> ADC注入通道

    使用MM32F3270的SDIO驱动SD卡

    使用MM32F3270的SDIO驱动SD卡
    的头像 发表于 09-27 15:56 703次阅读
    使用<b class='flag-5'>MM32F3270</b>的SDIO<b class='flag-5'>驱动</b>SD卡

    使用MM32F3270 FSMC驱动OLED

    使用MM32F3270 FSMC驱动OLED
    的头像 发表于 09-27 15:30 893次阅读
    使用<b class='flag-5'>MM32F3270</b> <b class='flag-5'>FSMC</b><b class='flag-5'>驱动</b>OLED

    使用MM32F3270 FSMC驱动TFT-LCD

    使用MM32F3270 FSMC驱动TFT-LCD
    的头像 发表于 09-27 15:34 925次阅读
    使用<b class='flag-5'>MM32F3270</b> <b class='flag-5'>FSMC</b><b class='flag-5'>驱动</b>TFT-LCD

    基于MM32F3270以太网Client使用

    基于MM32F3270以太网Client使用
    的头像 发表于 09-27 15:44 667次阅读
    基于<b class='flag-5'>MM32F3270</b>以太网Client使用