5.13 FEMC 使用说明

本章说明 N32H49x 标准外设库中 FEMC 驱动的文件组成与 16 个公开函数,以及 SRAM、PSRAM、Nor_Flash、Nand_Flash、LCDDisplay 五个示例。外部存储器控制器把 SRAM、PSRAM、NOR Flash、NAND Flash 或 LCD 接口映射到芯片的存储空间;存储体选择、总线宽度、时序与扩展模式等配置规则,以及取指与访问约束请配合用户手册的“外部存储器控制器(FEMC)”章节阅读。

5.13.1 相关文件

相对路径 作用
firmware/n32h49x_std_periph_driver/inc/n32h49x_femc.h 定义存储体、数据宽度、时序、扩展模式与标志位等取值,声明 16 个公开函数
firmware/n32h49x_std_periph_driver/src/n32h49x_femc.c 实现上述 16 个函数:NOR/SRAM 与 NAND 存储体初始化、ECC、中断与标志
projects/n32h49x_EVAL/examples/FEMC/ FEMC 示例根目录,含 SRAM、PSRAM、Nor_Flash、Nand_Flash、LCDDisplay 5 个示例
projects/n32h49x_EVAL/examples/FEMC/SRAM/ 该示例的工程目录组成:MDK-ARM/、EWARM/、inc/、src/、readme.txt
projects/n32h49x_EVAL/bsp/ 该示例引用的公共板级文件:串口日志与延时函数

5.13.2 API 参考

搜索 API共 16 个函数

以下 16 个公开函数按 n32h49x_femc.h 的声明顺序分为 4 组;每个条目给出功能摘要与 n32h49x_femc.c 中该函数正上方的注释原文。

NOR/SRAM 存储体

FEMC_DeInitNorSram、FEMC_InitNorSram、FEMC_InitNorSramStruct、FEMC_EnableNorSram

NAND 存储体

FEMC_DeInitNand、FEMC_InitNand、FEMC_InitNandStruct、FEMC_EnableNand

NAND ECC

FEMC_EnableNandEcc、FEMC_RestartNandEcc、FEMC_GetEcc

NAND 中断与标志

FEMC_ConfigInt、FEMC_GetFlag、FEMC_ClrFlag、FEMC_GetITFlag、FEMC_ClrITFlag

void FEMC_DeInitNorSram(FEMC_SN_Bank_Block *Block)将 FEMC 的 SRAM/NOR 存储体寄存器复位为默认值。
源码注释
name    FEMC_DeInitNorSram.
fun     Deinitializes the FEMC SRAM/NOR Banks registers to their default reset values.
param   Block: FEMC_SN_Bank pointer to SRAM/NorFlash bank block which will beinitialized.
            - FEMC_SN_BANK_BLOCK1   FEMC SRAM/NOR Bank Block1
            - FEMC_SN_BANK_BLOCK2   FEMC SRAM/NOR Bank Block2
            - FEMC_SN_BANK_BLOCK3   FEMC SRAM/NOR Bank Block3
            - FEMC_SN_BANK_BLOCK4   FEMC SRAM/NOR Bank Block4
return  none
void FEMC_DeInitNand(FEMC_NAND_Bank *Bank)将 FEMC 的 NAND 存储体寄存器复位为默认值。
源码注释
name    FEMC_DeInitNand.
fun     Deinitializes the FEMC NAND Banks registers to their default reset values.
param   Bank: FEMC_NAND_Bank pointer to NAND bank which will beinitialized.
            - FEMC_NAND_BANK2 FEMC Bank2 NAND
            - FEMC_NAND_BANK3 FEMC Bank3 NAND
return  none
void FEMC_InitNorSram(FEMC_NorSramInitType* FEMC_NORSRAMInitStruct)根据 FEMC_NORSRAMInitStruct 中指定的参数初始化 FEMC 的 NOR/SRAM 存储体。
源码注释
name    FEMC_InitNorSram.
fun     Initializes the FEMC NOR/SRAM Bank Blocks according to the specified parameters in the FEMC_NORSRAMInitStruct.
param   FEMC_NORSRAMInitStruct : pointer to a FEMC_NorSramInitType
        structure that contains the configuration information for
        the FEMC NOR/SRAM specified Bank Blocks.
return  none
void FEMC_InitNand(FEMC_NandInitType* FEMC_NANDInitStruct)根据 FEMC_NANDInitStruct 中指定的参数初始化 FEMC 的 NAND 存储体。
源码注释
name    FEMC_InitNand.
fun     Initializes the FEMC NAND Banks according to the specified parameters in the FEMC_NANDInitStruct.
param   FEMC_NANDInitStruct pointer to a FEMC_NandInitType
        structure that contains the configuration information for the FEMC NAND specified Banks.
return  none
void FEMC_InitNorSramStruct(FEMC_NorSramInitType* FEMC_NORSRAMInitStruct)将 FEMC_NORSRAMInitStruct 的每个成员填充为其默认值。
源码注释
name    FEMC_InitNorSramStruct.
fun     Fills each FEMC_NORSRAMInitStruct member with its default value.
param   FEMC_NORSRAMInitStruct pointer to a FEMC_NorSramInitType structure which will be initialized.
return  none
void FEMC_InitNandStruct(FEMC_NandInitType* FEMC_NANDInitStruct)将 FEMC_NANDInitStruct 的每个成员填充为其默认值。
源码注释
name    FEMC_InitNandStruct.
fun     Fills each FEMC_NANDInitStruct member with its default value.
param   FEMC_NANDInitStruct pointer to a FEMC_NandInitType structure which will be initialized.
return  none
void FEMC_EnableNorSram( FEMC_SN_Bank_Block *Block, FunctionalState Cmd)使能或禁止指定的 NOR/SRAM 存储体。
源码注释
name    FEMC_EnableNorSram.
fun     Enables or disables the specified NOR/SRAM Memory Bank.
param   Block specifies the NOR/SRAM Bank Block to be used
          - FEMC_SN_BANK_BLOCK1
          - FEMC_SN_BANK_BLOCK2
          - FEMC_SN_BANK_BLOCK3
          - FEMC_SN_BANK_BLOCK4
param  Cmd :
          - ENABLE
          - DISABLE
return  none
void FEMC_EnableNand(FEMC_NAND_Bank *Bank, FunctionalState Cmd)使能或禁止指定的 NAND 存储体。
源码注释
name    FEMC_EnableNand.
fun     Enables or disables the specified NAND Memory Bank.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
param  Cmd :
          - ENABLE
          - DISABLE
return  none
void FEMC_EnableNandEcc(FEMC_NAND_Bank *Bank, FunctionalState Cmd)使能或禁止 FEMC NAND 的 ECC 功能。
源码注释
name    FEMC_EnableNandEcc.
fun     Enables or disables the FEMC NAND ECC feature.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
param  Cmd :
          - ENABLE
          - DISABLE
return  none
void FEMC_RestartNandEcc(FEMC_NAND_Bank *Bank)清除 ECC 结果并启动一次新的 ECC 过程。
源码注释
name    FEMC_RestartNandEcc.
fun     Clear ECC result and start a new ECC process.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
return  none
uint32_t FEMC_GetEcc(FEMC_NAND_Bank *Bank)返回纠错码寄存器的值。
源码注释
name    FEMC_GetEcc.
fun     Returns the error correction code register value.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
return  The Error Correction Code (ECC) value.
void FEMC_ConfigInt(FEMC_NAND_Bank *Bank, uint32_t FEMC_INT, FunctionalState Cmd)使能或禁止指定的 RTC 中断。
源码注释
name    FEMC_ConfigInt.
fun     Enables or disables the specified RTC interrupts.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
param   FEMC_INT specifies the NAND flag
          - FEMC_NAND_INT_HIGH_LEVEL
          - FEMC_NAND_INT_RASING_EDGE
          - FEMC_NAND_INT_FALLING_EDGE
param  Cmd :
          - ENABLE
          - DISABLE
return  none

使用提示: 源码注释写的是 RTC 中断,实现操作的是 Bank->STS 中由 FEMC_INT 指定的位(Bank->STS |= FEMC_INT 置位、Bank->STS &= ~FEMC_INT 清位),对应 param 中列出的 FEMC_NAND_INT_*。

FlagStatus FEMC_GetFlag(FEMC_NAND_Bank *Bank, uint32_t FEMC_FLAG)检查指定的 NAND 标志是否置位。
源码注释
name    FEMC_GetFlag.
fun     Checks whether the specified NAND flag is set or not.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
param   FEMC_FLAG specifies the NAND flag
          - FEMC_NAND_FLAG_FIFO_EMPTY
return  FlagStatus
          - SET   : the flag is set
          - RESET : the flag is reset
void FEMC_ClrFlag(FEMC_NAND_Bank *Bank, uint32_t FEMC_FLAG)清除 FEMC 的挂起标志。
源码注释
name    FEMC_ClrFlag.
fun     Clears the FEMC's pending flags.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
param   FEMC_FLAG specifies the NAND flag
          - FEMC_NAND_FLAG_FIFO_EMPTY

return  none
FlagStatus FEMC_GetITFlag(FEMC_NAND_Bank *Bank, uint32_t FEMC_FLAG)检查指定的 NAND 中断标志是否置位。
源码注释
name    FEMC_GetFlag.
fun     Checks whether the specified NAND interrupt flag is set or not.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
param   FEMC_FLAG specifies the NAND flag
          - FEMC_NAND_INT_FLAG_HIGH_LEVEL
          - FEMC_NAND_INT_FLAG_RASING_EDGE
          - FEMC_NAND_INT_FLAG_FALLING_EDGE
return  FlagStatus
          - SET   : the flag is set
          - RESET : the flag is reset

使用提示: 源码注释的 name 字段写作 FEMC_GetFlag.,与函数名 FEMC_GetITFlag 不一致,按函数名调用即可。

void FEMC_ClrITFlag(FEMC_NAND_Bank *Bank, uint32_t FEMC_FLAG)清除 FEMC 的中断挂起标志。
源码注释
name    FEMC_ClrITFlag.
fun     Clears the FEMC's interrupt pending flags.
param   Bank specifies the NAND Bank to be used
          - FEMC_NAND_BANK2
          - FEMC_NAND_BANK3
param   FEMC_FLAG specifies the NAND flag
          - FEMC_NAND_INT_FLAG_HIGH_LEVEL
          - FEMC_NAND_INT_FLAG_RASING_EDGE
          - FEMC_NAND_INT_FLAG_FALLING_EDGE
return  none

5.13.3 Demo 示例说明

本节说明 FEMC 的五个示例:SRAM、PSRAM、Nor_Flash、Nand_Flash 演示对外部存储器的读写校验,LCDDisplay 演示通过 FEMC 驱动 LCD 显示。

5.13.3.1 SRAM 读写校验

工程目录: projects/n32h49x_EVAL/examples/FEMC/SRAM/

使能 GPIO 与 FEMC 时钟→配置数据、地址与控制引脚→用 Block1 初始化外部 SRAM→写入缓冲数据→读回逐字比较并打印结果

项目 源码解读
功能 通过 FEMC 把数据写入外部 16 位 SRAM 再读回校验;
读写一致时串口打印带 pass 的通过信息,否则打印带 fail 的失败信息
源码组成 src/main.c:main、Buffer16cmp、Buffer8cmp、Fill_Buffer_16、Fill_Buffer_8;
src/femc_sram.c:FEMC_GPIO_Init、FEMC_Sram_Init、FEMC_Sram_Write_Buffer、FEMC_Sram_Read_Buffer;
inc/main.h、inc/femc_sram.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:FEMC 时钟源为 AHB,系统时钟 240MHz;
器件:外部 16 位 SRAM IS61WV102416FBLL-10TLI,选用 Block1,数据宽度 16 位,地址数据总线非复用;
引脚:数据线 PD14/PD15/PD0/PD1、PE7PE15、PD8PD10,地址线 PF0PF5、PF12PF15、PG0PG5、PD11PD13、PE3,控制线 NOE:PD4、NWE:PD5、NE:PG9、NBL0:PE0、NBL1:PE1
程序与数据路径 main 调用 FEMC_Sram_Init 完成引脚与存储体配置;
用 Fill_Buffer_16 填充发送缓冲后调用 FEMC_Sram_Write_Buffer 写入;
再调用 FEMC_Sram_Read_Buffer 读回并逐字比较,统计不一致的个数
主要 API FEMC_InitNorSramStruct、FEMC_InitNorSram、FEMC_EnableNorSram
验证方法 编译烧录上电后串口打印启动信息;
读写一致时打印带 sram 与 pass 的通过信息,否则打印带 fail 的失败信息
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
串口为 USART1(TX PA9,RX PA10,115200);
开发板上没有 SRAM,需要外接器件
核心代码解读与移植

示例先完成 GPIO 与 FEMC 时钟、引脚和 Block1 存储体配置,再写入缓冲并读回逐字比较。

数据路径: FEMC_Sram_Init 使能时钟并配置引脚 → FEMC_InitNorSramStruct 与 FEMC_InitNorSram 写入存储体配置 → FEMC_EnableNorSram 使能存储体 → main 写入并读回比较

1. 配置并初始化外部 SRAM。 FEMC_Sram_Init 使能 FEMC 时钟,按 16 位异步 SRAM 设置时序与存储体参数,再使能选定的存储体。

src/femc_sram.csrc/femc_sram.c · FEMC_Sram_Init
    /* Enable the FEMC Clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_FEMC, ENABLE);

    /*-- FEMC Configuration ----------------------------------------------------*/
    p.AddrSetTime      = FEMC_NOR_SRAM_ADDR_SETUP_TIME_2HCLK;
    p.AddrHoldTime     = FEMC_NOR_SRAM_ADDR_HOLD_TIME_2HCLK;
    p.DataSetTime      = FEMC_NOR_SRAM_DATA_SETUP_TIME(5);
    p.BusRecoveryCycle = FEMC_NOR_SRAM_BUSRECOVERY_TIME_1HCLK;
    p.ClkDiv           = FEMC_NOR_SRAM_CLK_DIV_2;
    p.DataHoldTime     = FEMC_NOR_SRAM_DATA_HOLD_TIME_2HCLK;
    p.AccMode          = FEMC_NOR_SRAM_ACC_MODE_A;

    if (block_index == 1)
    {
        Block = FEMC_SN_BANK_BLOCK1;
    }
    else if (block_index == 2)
    {
        Block = FEMC_SN_BANK_BLOCK2;
    }
    else if (block_index == 3)
    {
        Block = FEMC_SN_BANK_BLOCK3;
    }
    else if (block_index == 4)
    {
        Block = FEMC_SN_BANK_BLOCK4;
    }
    
    FEMC_InitNorSramStruct(&FEMC_NORSRAMInitStructure);
    FEMC_NORSRAMInitStructure.Block            = Block;
    FEMC_NORSRAMInitStructure.DataAddrMux      = FEMC_NOR_SRAM_MUX_DISABLE;
    FEMC_NORSRAMInitStructure.MemType          = FEMC_MEM_TYPE_SRAM;
    FEMC_NORSRAMInitStructure.MemDataWidth     = FEMC_NOR_SRAM_DATA_WIDTH_16B;
    FEMC_NORSRAMInitStructure.BurstAccMode     = FEMC_NOR_SRAM_BURST_MODE_DISABLE;
    FEMC_NORSRAMInitStructure.WaitSigPolarity  = FEMC_NOR_SRAM_WAIT_SIGNAL_LOW;
    FEMC_NORSRAMInitStructure.WrapMode         = FEMC_NOR_SRAM_WRAP_DISABLE;
    FEMC_NORSRAMInitStructure.WaitSigConfig    = FEMC_NOR_SRAM_NWAIT_BEFORE_STATE;
    FEMC_NORSRAMInitStructure.WriteEnable      = FEMC_NOR_SRAM_WRITE_ENABLE;
    FEMC_NORSRAMInitStructure.WaitSigEnable    = FEMC_NOR_SRAM_NWAIT_DISABLE;
    FEMC_NORSRAMInitStructure.ExtModeEnable    = FEMC_NOR_SRAM_EXTENDED_DISABLE;
    FEMC_NORSRAMInitStructure.WriteBurstEnable = FEMC_NOR_SRAM_BURST_WRITE_DISABLE;
    FEMC_NORSRAMInitStructure.RWTimingStruct   = &p;
    FEMC_NORSRAMInitStructure.WTimingStruct    = &p;

    FEMC_InitNorSram(&FEMC_NORSRAMInitStructure);

    /* Enable FEMC Bank1_NOR Bank */
    FEMC_EnableNorSram(Block, ENABLE);

FEMC_MEM_TYPE_SRAM 与 16 位数据宽度对应所用器件;时序结构体同时赋给读写时序,非扩展模式下一套时序即可。

2. 写入缓冲数据。 FEMC_Sram_Write_Buffer 按存储体号取得块基地址,再逐半字写入并递增地址。

src/femc_sram.csrc/femc_sram.c · FEMC_Sram_Write_Buffer
void FEMC_Sram_Write_Buffer(uint16_t* pBuffer, uint8_t block_index, uint32_t write_addr, uint32_t number)
{
    uint32_t transfer_addr;
    if (block_index == 1)
    {
        transfer_addr = Bank1_Block1_SRAM_ADDR;
    }
    else if (block_index == 2)
    {
        transfer_addr = Bank1_Block2_SRAM_ADDR;
    }
    else if (block_index == 3)
    {
        transfer_addr = Bank1_Block3_SRAM_ADDR;
    }
    else if (block_index == 4)
    {
        transfer_addr = Bank1_Block4_SRAM_ADDR;
    }
    for (; number != 0; number--) /* while there is data to write */
    {
        /* Transfer data to the memory */
        *(uint16_t*)(transfer_addr + write_addr) = *pBuffer++;

        /* Increment the address*/
        write_addr += 2;
    }
}

块基地址由存储体号决定,地址每次加 2 以对齐半字宽度;读函数与之对应。

3. 读回并比较。 main 填充发送缓冲并写入,再读回比较,统计不一致的个数后打印结果。

src/main.csrc/main.c · main
    block_index = 1;

    /*config femc ,external 16bit sram*/
    FEMC_Sram_Init(block_index);

    /* Write data to FEMC SRAM memory */
    /* Fill the buffer to send */
    Fill_Buffer_16(tx_buffer, BUFFER_SIZE, 0x1230);
    log_info("femc write external sram test\r\n");
    FEMC_Sram_Write_Buffer(tx_buffer, block_index, WRITE_READ_ADDR, BUFFER_SIZE);

    /* Read data from FEMC SRAM memory */
    log_info("femc read external sram test\r\n");
    FEMC_Sram_Read_Buffer(rx_buffer, block_index, WRITE_READ_ADDR, BUFFER_SIZE);

    /* Read back SRAM memory and check content correctness */
    for (index = 0x00; index < BUFFER_SIZE; index++)
    {
        if (rx_buffer[index] != tx_buffer[index])
        {
            wr_status++;
        }
    }

Fill_Buffer_16 写入 IndexTmp + Offset 序列,wr_status 统计不一致个数,为 0 时表示读回正确。

对应源码: src/main.c、src/femc_sram.c

5.13.3.2 PSRAM 读写校验

工程目录: projects/n32h49x_EVAL/examples/FEMC/PSRAM/

使能 GPIO 与 FEMC 时钟→配置数据、地址与控制引脚→用 Block3 初始化外部 PSRAM→写入缓冲数据→读回比较并打印结果

项目 源码解读
功能 通过 FEMC 把数据写入外部 16 位 PSRAM 再读回校验;
读写一致时串口打印带 pass 的通过信息,否则打印带 fail 的失败信息
源码组成 src/main.c:main、Buffer16cmp、Buffer8cmp、Fill_Buffer_16、Fill_Buffer_8;
src/femc_psram.c:FEMC_GPIO_Init、FEMC_Psram_Init、FEMC_Psram_Write_Buffer、FEMC_Psram_Read_Buffer;
inc/main.h、inc/femc_psram.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:FEMC 时钟源为 AHB,系统时钟 240MHz;
器件:外部 16 位 PSRAM IS66WV51216EBLLLL-70TLI,选用 Block3,数据宽度 16 位;
引脚:数据线与地址线同 SRAM 示例,控制线 NOE:PD4、NWE:PD5、NE:PG8
程序与数据路径 main 调用 FEMC_Psram_Init 完成引脚与存储体配置;
用 Fill_Buffer_16 填充发送缓冲后调用 FEMC_Psram_Write_Buffer 写入;
再调用 FEMC_Psram_Read_Buffer 读回,用 Buffer16cmp 比较并打印结果
主要 API FEMC_InitNorSramStruct、FEMC_InitNorSram、FEMC_EnableNorSram
验证方法 编译烧录上电后串口打印启动信息;
读写一致时打印带 psram 与 pass 的通过信息,否则打印带 fail 的失败信息
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
串口为 USART1(TX PA9,RX PA10,115200);
开发板上没有 PSRAM,需要外接器件
核心代码解读与移植

示例与 SRAM 示例结构一致,差别在存储体号与器件类型、时序参数。

数据路径: FEMC_Psram_Init 使能时钟并配置引脚 → FEMC_InitNorSramStruct 与 FEMC_InitNorSram 写入存储体配置 → FEMC_EnableNorSram 使能存储体 → main 写入并读回比较

1. 配置并初始化外部 PSRAM。 FEMC_Psram_Init 按 PSRAM 时序设置参数,把器件类型设为 PSRAM,并用 Block3 初始化。

src/femc_psram.csrc/femc_psram.c · FEMC_Psram_Init
    /* Enable the FEMC Clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_FEMC, ENABLE);

    FEMC_InitNorSramStruct(&FEMC_NORSRAMInitStructure);
    /*-- FEMC Configuration ----------------------------------------------------*/
    ReadWriteTiming.AddrSetTime      = FEMC_NOR_SRAM_ADDR_SETUP_TIME_12HCLK;
    ReadWriteTiming.AddrHoldTime     = FEMC_NOR_SRAM_ADDR_HOLD_TIME_2HCLK;
    ReadWriteTiming.DataSetTime      = FEMC_NOR_SRAM_DATA_SETUP_TIME(8);
    ReadWriteTiming.DataHoldTime     = FEMC_NOR_SRAM_DATA_HOLD_TIME_2HCLK;
    ReadWriteTiming.BusRecoveryCycle = FEMC_NOR_SRAM_BUSRECOVERY_TIME_2HCLK;
    ReadWriteTiming.ClkDiv           = FEMC_NOR_SRAM_CLK_DIV_2;
    ReadWriteTiming.AccMode          = FEMC_NOR_SRAM_ACC_MODE_A;

    if (block_index == 1)
    {
        Block = FEMC_SN_BANK_BLOCK1;
    }
    else if (block_index == 2)
    {
        Block = FEMC_SN_BANK_BLOCK2;
    }
    else if (block_index == 3)
    {
        Block = FEMC_SN_BANK_BLOCK3;
    }
    else if (block_index == 4)
    {
        Block = FEMC_SN_BANK_BLOCK4;
    }

    FEMC_NORSRAMInitStructure.Block            = Block;
    FEMC_NORSRAMInitStructure.DataAddrMux      = FEMC_NOR_SRAM_MUX_DISABLE;
    FEMC_NORSRAMInitStructure.MemType          = FEMC_MEM_TYPE_PSRAM;
    FEMC_NORSRAMInitStructure.MemDataWidth     = FEMC_NOR_SRAM_DATA_WIDTH_16B;
    FEMC_NORSRAMInitStructure.BurstAccMode     = FEMC_NOR_SRAM_BURST_MODE_DISABLE;
    FEMC_NORSRAMInitStructure.AsynchroWait     = FEMC_NOR_SRAM_ASYNC_NWAIT_DISABLE;
    FEMC_NORSRAMInitStructure.WaitSigPolarity  = FEMC_NOR_SRAM_WAIT_SIGNAL_LOW;
    FEMC_NORSRAMInitStructure.WrapMode         = FEMC_NOR_SRAM_WRAP_DISABLE;
    FEMC_NORSRAMInitStructure.WaitSigConfig    = FEMC_NOR_SRAM_NWAIT_BEFORE_STATE;
    FEMC_NORSRAMInitStructure.WriteEnable      = FEMC_NOR_SRAM_WRITE_ENABLE;
    FEMC_NORSRAMInitStructure.WaitSigEnable    = FEMC_NOR_SRAM_NWAIT_DISABLE;
    FEMC_NORSRAMInitStructure.ExtModeEnable    = FEMC_NOR_SRAM_EXTENDED_DISABLE;
    FEMC_NORSRAMInitStructure.WriteBurstEnable = FEMC_NOR_SRAM_BURST_WRITE_DISABLE;
    FEMC_NORSRAMInitStructure.NadvPolarity     = FEMC_NOR_SRAM_NADV_SIGNAL_HIGH;
    FEMC_NORSRAMInitStructure.RWTimingStruct   = &ReadWriteTiming;
    FEMC_NORSRAMInitStructure.WTimingStruct    = &WriteTiming;

    FEMC_InitNorSram(&FEMC_NORSRAMInitStructure);

    /* Enable FEMC Bank1 Block */
    FEMC_EnableNorSram(Block, ENABLE);

FEMC_MEM_TYPE_PSRAM 选择 PSRAM 时序模型;PSRAM 的地址建立时间比 SRAM 更长,移植时应按器件手册调整时序。

2. 写入缓冲数据。 FEMC_Psram_Write_Buffer 与 SRAM 写函数结构相同,按存储体号选择块基地址后逐半字写入。

src/femc_psram.csrc/femc_psram.c · FEMC_Psram_Write_Buffer
        transfer_addr = Bank1_Block1_PSRAM_ADDR;
    }
    else if (block_index == 2)
    {
        transfer_addr = Bank1_Block2_PSRAM_ADDR;
    }
    else if (block_index == 3)
    {
        transfer_addr = Bank1_Block3_PSRAM_ADDR;
    }
    else if (block_index == 4)
    {
        transfer_addr = Bank1_Block4_PSRAM_ADDR;
    }
    for (; number != 0; number--) /*!< while there is data to write */
    {
        /*!< Transfer data to the memory */
        *(uint16_t*)(transfer_addr + write_addr) = *pBuffer++;

        /*!< Increment the address*/
        write_addr += 2;
    }
}

块基地址与存储体一一对应,访问即映射到外部 PSRAM 的相应区域。

3. 读回并比较。 main 选定 Block3,写入后读回并用 Buffer16cmp 比较,直接得到 PASSED 或 FAILED。

src/main.csrc/main.c · main
    block_index = 3; // 1:Block1; 2:Block2; 3:Block3; 4:Block4

    /*config femc ,external 16bit sram*/
    FEMC_Psram_Init(block_index);

    /* Fill the buffer to send */
    Fill_Buffer_16(tx_buffer, BUFFER_SIZE, 0x1230);
    FEMC_Psram_Write_Buffer(tx_buffer, block_index, WRITE_READ_ADDR, BUFFER_SIZE);

    /* Read data from FEMC PSRAM memory */
    FEMC_Psram_Read_Buffer(rx_buffer, block_index, WRITE_READ_ADDR, BUFFER_SIZE);

    /* Read back PSRAM memory and check content correctness */
    wr_status = Buffer16cmp(tx_buffer, rx_buffer, BUFFER_SIZE);

    if (wr_status == PASSED)
    {
        /* OK */
        log_info("femc psram read and write test pass\r\n");
    }

Buffer16cmp 逐半字比较并返回状态;移植到其它存储体时只需修改 block_index 与对应的引脚宏。

对应源码: src/main.c、src/femc_psram.c

5.13.3.3 Nor_Flash 读写擦校验

工程目录: projects/n32h49x_EVAL/examples/FEMC/Nor_Flash/

使能 GPIO 与 FEMC 时钟→用 Block1 初始化外部 NOR Flash→读取并打印器件 ID→写入缓冲并读回比较→擦除块并校验全为 0xFF

项目 源码解读
功能 通过 FEMC 读取外部 NOR Flash 的 ID,并对其进行写入、读回校验与擦除操作;
读写与擦除都通过时串口打印带 pass 的信息,否则打印带 fail 的信息
源码组成 src/main.c:main、Buffer16cmp、Buffer8cmp、Fill_Buffer_16、Fill_Buffer_8;
src/femc_nor.c:FEMC_GPIO_Init、FEMC_Nor_Init、FEMC_Nor_ReadID、FEMC_Nor_Write_Buffer_Halfword、FEMC_Nor_Read_Buffer_Halfword、FEMC_Nor_Erase_Block;
inc/main.h、inc/femc_nor.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:FEMC 时钟源为 AHB,系统时钟 240MHz;
器件:外部 16 位 NOR Flash S29GL01GS11TFI020,选用 Block1,扩展模式使能;
引脚:数据线与地址线同上,控制线 NOE:PD4、NWE:PD5、NE:PB9、NWAIT:PD6
程序与数据路径 main 调用 FEMC_Nor_Init 完成引脚与存储体配置;
用 FEMC_Nor_ReadID 读取并打印厂商与器件 ID;
写入缓冲并读回比较,再擦除块并校验读回值全为 0xFFFF
主要 API FEMC_InitNorSramStruct、FEMC_InitNorSram、FEMC_EnableNorSram
验证方法 编译烧录上电后串口打印启动信息与器件 ID;
读写与擦除都通过时打印带 norflash 与 pass 的信息,否则打印带 fail 的信息
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
串口为 USART1(TX PA9,RX PA10,115200);
开发板上没有 NOR Flash,需要外接器件
核心代码解读与移植

示例在读写校验之外增加 ID 读取与块擦除,擦除后再次读回校验全为 0xFFFF。

数据路径: FEMC_Nor_Init 使能时钟并配置引脚 → FEMC_Nor_ReadID 读取器件 ID → FEMC_Nor_Write_Buffer_Halfword 写入 → FEMC_Nor_Read_Buffer_Halfword 读回比较 → FEMC_Nor_Erase_Block 擦除并校验

1. 配置并初始化外部 NOR Flash。 FEMC_Nor_Init 按 NOR 器件设置时序并启用扩展模式,再使能选定的存储体。

src/femc_nor.csrc/femc_nor.c · FEMC_Nor_Init
    /* Enable the FEMC Clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_FEMC, ENABLE);

    /*-- FEMC Configuration ----------------------------------------------------*/
    p.AddrSetTime      = FEMC_NOR_SRAM_ADDR_SETUP_TIME_15HCLK;
    p.AddrHoldTime     = FEMC_NOR_SRAM_ADDR_HOLD_TIME_2HCLK;
    p.DataSetTime      = FEMC_NOR_SRAM_DATA_SETUP_TIME(12);
    p.BusRecoveryCycle = FEMC_NOR_SRAM_BUSRECOVERY_TIME_1HCLK;
    p.ClkDiv           = FEMC_NOR_SRAM_CLK_DIV_2;
    p.DataHoldTime     = FEMC_NOR_SRAM_DATA_HOLD_TIME_2HCLK;
    p.AccMode          = FEMC_NOR_SRAM_ACC_MODE_B;

    if (block_index == 1)
    {
        Block = FEMC_SN_BANK_BLOCK1;
    }
    else if (block_index == 2)
    {
        Block = FEMC_SN_BANK_BLOCK2;
    }
    else if (block_index == 3)
    {
        Block = FEMC_SN_BANK_BLOCK3;
    }
    else if (block_index == 4)
    {
        Block = FEMC_SN_BANK_BLOCK4;
    }
    
    FEMC_InitNorSramStruct(&FEMC_NORSRAMInitStructure);
    FEMC_NORSRAMInitStructure.Block            = Block;
    FEMC_NORSRAMInitStructure.DataAddrMux      = FEMC_NOR_SRAM_MUX_DISABLE;
    FEMC_NORSRAMInitStructure.MemType          = FEMC_MEM_TYPE_NOR;
    FEMC_NORSRAMInitStructure.MemDataWidth     = FEMC_NOR_SRAM_DATA_WIDTH_16B;
    FEMC_NORSRAMInitStructure.BurstAccMode     = FEMC_NOR_SRAM_BURST_MODE_DISABLE;

FEMC_MEM_TYPE_NOR 选择 NOR 时序模型,扩展模式使能后可用单独的读、写时序寄存器。

2. 写入缓冲并读回比较。 main 读取器件 ID 后填充缓冲写入,读回比较得到第一个状态。

src/main.csrc/main.c · main
    /*config femc ,external 16bit nor flash*/
    FEMC_Nor_Init(block_index);

    /* read nor flash id */
    FEMC_Nor_ReadID(&Nor_id, block_index);
    
    log_info(" FEMC external norflash Manufacturer Code = 0x%x, Device ID1 = 0x%x, Device ID2 = 0x%x, Device ID3 = 0x%x \r\n", 
                Nor_id.Manufacturer_Code, Nor_id.Device_Code1, Nor_id.Device_Code2, Nor_id.Device_Code3);
    
    /* Write data to NOR memory */
    /* Fill the buffer to send */
    Fill_Buffer_16(tx_buffer, BUFFER_SIZE, 0x0001);
    FEMC_Nor_Write_Buffer_Halfword(block_index, tx_buffer, WRITE_READ_ADDR, BUFFER_SIZE); // write buffer

    /* Read data from NOR memory */
    FEMC_Nor_Read_Buffer_Halfword(block_index, rx_buffer, WRITE_READ_ADDR, BUFFER_SIZE);
    
    /* Read back NOR memory and check content correctness */
    wr_status1 = Buffer16cmp(tx_buffer, rx_buffer, BUFFER_SIZE);

FEMC_Nor_ReadID 通过两个读周期取回厂商与器件 ID,写入用 0x0001 起始序列便于区分。

3. 擦除块并校验。 示例擦除写入地址所在块,再读回校验整段都为 0xFFFF,得到第二个状态。

src/main.csrc/main.c · main
    /* Erase the NOR memory block to write on */
    FEMC_Nor_Erase_Block(block_index, WRITE_READ_ADDR);

    /* Read data from NOR memory */
    FEMC_Nor_Read_Buffer_Halfword(block_index, rx_buffer, WRITE_READ_ADDR, BUFFER_SIZE);
    
    for(i=0;i<BUFFER_SIZE;i++)
    {
        if(rx_buffer[i] != 0xFFFF)
        {
            wr_status2 = FAILED;
            break;
        }
    }

    if (wr_status1 == PASSED && wr_status2 == PASSED)
    {
        /* OK */
        log_info(" femc norflash read and write test pass \r\n");
    }

NOR 擦除后存储单元为全 1,故读回应为 0xFFFF;两个状态都为 PASSED 才判定通过。

对应源码: src/main.c、src/femc_nor.c

5.13.3.4 Nand_Flash 读写擦校验

工程目录: projects/n32h49x_EVAL/examples/FEMC/Nand_Flash/

使能 GPIO 与 FEMC 时钟→用 Bank3 初始化外部 NAND Flash→复位并读取器件 ID→擦除块并写入页→读回页面并逐字节比较

项目 源码解读
功能 通过 FEMC 对 8 位 NAND Flash 擦除块、写页与读页并校验;
同时打印读取到的器件 ID,读回一致时打印带 pass 的信息,否则打印带 fail 的信息
源码组成 src/main.c:main、Buffer16cmp、Buffer8cmp;
src/femc_nand.c:FEMC_GPIO_Init、FEMC_Nand_Init、FEMC_Nand_Reset、FEMC_Nand_ReadID、FEMC_Nand_Erase_Block、FEMC_Nand_WritePage_Byte、FEMC_Nand_ReadPage_Byte、Flash_Write_Command;
inc/main.h、inc/femc_nand.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:FEMC 时钟源为 AHB,系统时钟 240MHz;
器件:外部 8 位 NAND Flash IS34ML01G081-TLI,选用 Bank3,位宽 8 位,示例关闭 ECC;
引脚:数据线 PD14/PD15/PD0/PD1、PE7~PE10,控制线 NOE:PD4、NWE:PD5、CLE:PD11、ALE:PD12、NCE:PG9、NWAIT:PD6
程序与数据路径 main 调用 FEMC_Nand_Init 完成引脚与存储体配置;
复位后读取器件 ID,随后擦除目标块、写入一页;
清零缓冲后读回该页并逐字节比较,得到测试结果
主要 API FEMC_InitNandStruct、FEMC_InitNand、FEMC_EnableNand
验证方法 编译烧录上电后串口打印启动信息、器件 ID 与擦写读状态;
读回一致时打印带 nandflash 与 pass 的信息,否则打印带 fail 的信息
使用提示 硬件平台为评估板 N32H497VEL7_STB V1.0;
开发环境为 KEIL MDK-ARM 5.25 或 IAR EWARM 8.50.1;
串口为 USART1(TX PA9,RX PA10,115200);
开发板上没有 NAND Flash,需要外接器件
核心代码解读与移植

示例先初始化 NAND 存储体并复位、读取 ID,再擦除块、写入页并读回逐字节比较。

数据路径: FEMC_Nand_Init 使能时钟并配置引脚 → FEMC_Nand_Reset 与 FEMC_Nand_ReadID → FEMC_Nand_Erase_Block → FEMC_Nand_WritePage_Byte 写入 → FEMC_Nand_ReadPage_Byte 读回比较

1. 初始化 NAND 存储体。 main 设置位宽为 8 位、存储体为 Bank3 并调用初始化函数。

src/main.csrc/main.c · main
    log_init();
    log_info("this is a femc external nand flash demo\r\n");

    nand_flash_width = 8; // config memory bus width
    bank_id          = 3; // config band index,2:bank2;3:bank3,must config FEMC_BANK_NAND in femc_nand.c.
    bank_address     = BANK3_NAND_ADDR;
    
    FEMC_Nand_Init(bank_id, nand_flash_width);
    log_info(" nand flash test start \r\n");

位宽与存储体号必须与 femc_nand.c 中的 FEMC_BANK_NAND 配置一致,否则访问地址与器件不匹配。

2. 配置 NAND 时序与存储体。 FEMC_Nand_Init 设置建立、保持与高阻时间,按位宽选择总线宽度并使能存储体。

src/femc_nand.csrc/femc_nand.c · FEMC_Nand_Init
    /*-- FEMC Configuration ------------------------------------------------------*/
    /* Enable the FEMC Clock */
    RCC_EnableAHBPeriphClk(RCC_AHB_PERIPHEN_FEMC, ENABLE);
    
    FEMC_GPIO_Init(bank_index);

    p.SetTime     = FEMC_NAND_SETUP_TIME(0x4);
    p.WaitSetTime = FEMC_NAND_WAIT_TIME(0x6);
    p.HoldSetTime = FEMC_NAND_HOLD_TIME(0x5);
    p.HiZSetTime  = FEMC_NAND_HIZ_TIME(0x5);
    
    if(bank_index == 2)
    {
        nand_bank = FEMC_NAND_BANK2;
    }
    else if(bank_index == 3)
    {
        nand_bank = FEMC_NAND_BANK3;
    }
    
    FEMC_InitNandStruct(&FEMC_NANDInitStructure);
    FEMC_NANDInitStructure.Bank                  = nand_bank;
    FEMC_NANDInitStructure.WaitFeatureEnable     = FEMC_NAND_NWAIT_ENABLE;
    FEMC_NANDInitStructure.MemDataWidth          = bus_width == 8 ? FEMC_NAND_BUS_WIDTH_8B : FEMC_NAND_BUS_WIDTH_16B;
    FEMC_NANDInitStructure.EccEnable             = FEMC_NAND_ECC_DISABLE;
    FEMC_NANDInitStructure.EccPageSize           = FEMC_NAND_ECC_PAGE_2048BYTES;
    FEMC_NANDInitStructure.TCLRSetTime           = FEMC_NAND_CLE_DELAY_1HCLK;
    FEMC_NANDInitStructure.TARSetTime            = FEMC_NAND_ALE_DELAY_1HCLK;
    FEMC_NANDInitStructure.CommSpaceTimingStruct = &p;
    FEMC_NANDInitStructure.AttrSpaceTimingStruct = &p;

    FEMC_InitNand(&FEMC_NANDInitStructure);

    /* FEMC NAND Bank Cmd Test */
    FEMC_EnableNand(nand_bank, ENABLE);

示例关闭 ECC,时序覆盖命令与地址两个空间;开启 ECC 时需注意先清空 FIFO 再切换 ECC 使能状态。

3. 写页与读页。 FEMC_Nand_WritePage_Byte 发送写页命令与地址后逐字节写入,并用状态轮询等待完成。

src/femc_nand.csrc/femc_nand.c · FEMC_Nand_WritePage_Byte
uint32_t FEMC_Nand_WritePage_Byte(uint32_t Bank_NAND_Addr, uint8_t* pBuffer, NAND_ADDRESS Address, uint32_t NumPageToWrite)
{
    uint32_t index = 0x00, numpagewritten = 0x00, addressstatus = NAND_VALID_ADDRESS;
    uint32_t status = NAND_READY, size = 0x00;

    if(Bank_NAND_Addr == BANK2_NAND_ADDR)
    {
        if((FEMC_NAND_BANK2->CTRL & FEMC_NAND_ECC_ENABLE) != RESET)
        {
            FEMC_EnableNandEcc(FEMC_NAND_BANK2, DISABLE);
            FEMC_EnableNandEcc(FEMC_NAND_BANK2, ENABLE);
        }
    }
    else if(Bank_NAND_Addr == BANK3_NAND_ADDR)
    {
        if((FEMC_NAND_BANK3->CTRL & FEMC_NAND_ECC_ENABLE) != RESET)
        {
            FEMC_EnableNandEcc(FEMC_NAND_BANK3, DISABLE);
            FEMC_EnableNandEcc(FEMC_NAND_BANK3, ENABLE);
        }
    }

地址先经有效性判断,再逐页发送写命令、列地址与行地址并写入数据;写页前必须先擦除对应块。

对应源码: src/main.c、src/femc_nand.c

5.13.3.5 LCDDisplay 通过 FEMC 驱动 LCD

工程目录: projects/n32h49x_EVAL/examples/FEMC/LCDDisplay/

使能 GPIO 与 FEMC 时钟→用 FEMC 初始化 LCD 接口→复位并读取 LCD ID→按屏型号配置寄存器→显示两块 LOGO 图形

项目 源码解读
功能 通过 FEMC 把 LCD 映射为外部存储器并写入显示数据;
复位后读取 LCD ID,按型号初始化寄存器并显示 LOGO 图形
源码组成 src/main.c:main、LCD_Test;
src/lcd.c:LCD_Configuration、LCD_RCC_Configuration、LCD_GPIO_Configuration、LCD_FEMC_Configuration、LCD_GramScan、LCD_Clear、lcd_draw_image 等;
src/fonts.c、src/logo1.c、src/logo2.c:字库与图片数据;
inc/main.h、inc/lcd.h、inc/fonts.h、inc/n32h49x_it.h:头文件;
readme.txt:功能、环境与使用说明;
MDK-ARM/、EWARM/:Keil 与 IAR 工程
关键配置 时钟:FEMC 时钟源为 AHB,系统时钟 240MHz;
屏型号:TFT LCD 320240(ILI9341)或 800480(ILI9806G),复位后按读回的 ID 选择寄存器初始化;
引脚:CS:PG12、RS:PD13、WR:PD5、RD:PD4、RST:PH5、背光 PB5,数据线 D0~D15 同 SRAM 示例
程序与数据路径 main 调用 LCD_Configuration 完成时钟、引脚、FEMC 配置与复位;
读取 LCD ID 后按型号设置分辨率并配置寄存器;
LCD_Test 清屏后把两块 LOGO 图片绘制到屏幕
主要 API FEMC_InitNorSramStruct、FEMC_InitNorSram、FEMC_EnableNorSram
验证方法 编译下载运行后 LCD 依次显示两块 LOGO 图形;
串口打印读回的 LCD ID,用于确认屏型号
使用提示 硬件平台为全功能板 N32H497ZGL7_EVB V1.0;
开发环境为 KEIL MDK-ARM 5.34 或 IAR EWARM 8.50.1;
屏为 320240(ILI9341)或 800480(ILI9806G);
背光控制引脚为 PB5,显示效果主要靠观察屏幕
核心代码解读与移植

示例把 LCD 当作 FEMC 上的异步存储器件访问,先初始化接口与屏寄存器,再向屏幕刷新图片。

数据路径: main 调用 LCD_Configuration → LCD_FEMC_Configuration 建立 FEMC 接口 → LCD_Get_ID 读取型号 → ILI9341_REG_Config 或 ILI9806G_REG_Config 初始化 → LCD_Test 绘制图片

1. 初始化 LCD 接口并按型号配置。 LCD_Configuration 依次完成时钟、引脚、FEMC 配置与复位,再按读回的 ID 选择分辨率与寄存器初始化函数。

src/lcd.csrc/lcd.c · LCD_Configuration
void LCD_Configuration(void)
{
    LCD_RCC_Configuration();
    LCD_GPIO_Configuration();
    LCD_FEMC_Configuration();
    LCD_Reset();
    printf("\n\r LCD ID : 0x%x\n\r", LCD_Get_ID());
    if((LCD_Get_ID())==0x9341)
    {
        lcd_id = 0x9341;
        lcd_width = 240;
        lcd_height = 320;
        LCD_BL_Control(IO_STATE_LOW);
        ILI9341_REG_Config();    
    }
    else if((LCD_Get_ID())==0x9806)
    {
        lcd_id = 0x9806;
        lcd_width = 480;
        lcd_height = 800;
        LCD_BL_Control(IO_STATE_HIGH);
        ILI9806G_REG_Config();       
    }
    else
    {
    
    }
}

不同屏型号的背光有效电平与分辨率不同,示例按 ID 分别设置,移植新屏时需增加对应分支。

2. 主流程调用配置与显示。 main 先初始化日志,再调用配置、方向设置与显示函数。

src/main.csrc/main.c · main
int main(void)
{
    log_init();

#if defined(N32H49X)
    /* LCD configuration */
    LCD_Configuration();
    LCD_GramScan(0);
    LCD_Test();
#endif 

    while (1)
    {
    }
}

LCD_GramScan(0) 设置显示扫描方向,LCD_Test 负责具体画面;主循环为空,画面在初始化后一次性绘制。

3. 绘制 LOGO 图形。 LCD_Test 设置字体与颜色后清屏,再把两块 LOGO 图片按居中对齐绘制到屏幕。

src/main.csrc/main.c · LCD_Test
void LCD_Test(void)
{
    static uint8_t testCNT = 0; 

    testCNT++;

    LCD_SetFont(&Font8x16);
    LCD_SetColors(RED,WHITE);

    LCD_Clear(0,0,lcd_width,lcd_height);  
    lcd_draw_image((lcd_width - pic_logo1.width) / 2, lcd_height / 4, &pic_logo1);
    lcd_draw_image((lcd_width - pic_logo2.width) / 2, lcd_height / 3 * 2, &pic_logo2);
}

lcd_draw_image 按图片结构体逐像素写入;坐标用 lcd_width、lcd_height 计算,可自适应两种分辨率。

对应源码: src/main.c、src/lcd.c

5.13.4 注意与排障

场景 检查与建议 来源
XIP 取指访问限制 在外部存储器上取指(XIP)时不要使用 LDM、STM、LDRD、STRD 等多寄存器或双字访问指令;
这些指令会跨越取指边界导致读取错误。
用户手册
NAND ECC 切换 切换 NAND ECC 使能前应先等待 ECC 结果 FIFO 清空,并按先禁止再使能的顺序操作;
否则 ECC 结果与数据不对应。
用户手册
字节选择与写操作 未使能字节选择(NBL)时写操作不生效;
配置字节选择与写使能后才能写入存储单元。
用户手册
非对齐访问 对 FEMC 存储器的非对齐访问会被拆分为多次访问;
需要保证读写数据宽度与访问地址对齐。
用户手册
扩展模式与读写时序 扩展模式(EXTEN)使能后,写时序寄存器的配置才有效;
关闭扩展模式时读写共用一套时序。
用户手册
数据保持时间 数据保持时间(DATAHLD)应大于 0;
否则数据在保持阶段不稳定。
用户手册
时钟分频占空比 当分频系数 CLKDIV 为奇数时输出时钟为非 50% 占空比;
选择偶数分频可获得对称时钟。
用户手册
共用时钟存储体相位 同一共用时钟的多个存储体应配置一致的时钟相位与访问模式;
否则不同存储体的访问时序不匹配。
用户手册
国民技术开发套件文档中心

按芯片系列在线查阅国民技术 MCU 开发套件的芯片资料、SDK、驱动 API 与 Demo 示例说明。

© 2026 国民技术股份有限公司 版权所有粤ICP备11069485号本站使用不含 Cookie 的匿名访问统计