使用FMC连接SDRAM扩展STM32内存

1.引脚初始化

BSP_SDRAM_GPIO_Init
void BSP_SDRAM_GPIO_Init(void)
{
    RCC_AHB1PeriphClockCmd(FMC_A0_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A1_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A2_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A3_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A4_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A5_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A6_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A7_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A8_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A9_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A10_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A11_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_A12_GPIO_CLK, ENABLE);
    
    RCC_AHB1PeriphClockCmd(FMC_BA0_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_BA1_GPIO_CLK, ENABLE);
    
    RCC_AHB1PeriphClockCmd(FMC_D0_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D1_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D2_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D3_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D4_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D5_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D6_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D7_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D8_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D9_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D10_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D11_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D12_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D13_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D14_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_D15_GPIO_CLK, ENABLE);
    
    RCC_AHB1PeriphClockCmd(FMC_CS_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_WE_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_RAS_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_CAS_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_CLK_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_CKE_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_UDQM_GPIO_CLK, ENABLE);
    RCC_AHB1PeriphClockCmd(FMC_LDQM_GPIO_CLK, ENABLE);

    GPIO_PinAFConfig(FMC_A0_GPIO_PORT, FMC_A0_PINSOURCE , FMC_A0_AF);
    GPIO_PinAFConfig(FMC_A1_GPIO_PORT, FMC_A1_PINSOURCE , FMC_A1_AF);
    GPIO_PinAFConfig(FMC_A2_GPIO_PORT, FMC_A2_PINSOURCE , FMC_A2_AF);
    GPIO_PinAFConfig(FMC_A3_GPIO_PORT, FMC_A3_PINSOURCE , FMC_A3_AF);
    GPIO_PinAFConfig(FMC_A4_GPIO_PORT, FMC_A4_PINSOURCE , FMC_A4_AF);
    GPIO_PinAFConfig(FMC_A5_GPIO_PORT, FMC_A5_PINSOURCE , FMC_A5_AF);
    GPIO_PinAFConfig(FMC_A6_GPIO_PORT, FMC_A6_PINSOURCE , FMC_A6_AF);
    GPIO_PinAFConfig(FMC_A7_GPIO_PORT, FMC_A7_PINSOURCE , FMC_A7_AF);
    GPIO_PinAFConfig(FMC_A8_GPIO_PORT, FMC_A8_PINSOURCE , FMC_A8_AF);
    GPIO_PinAFConfig(FMC_A9_GPIO_PORT, FMC_A9_PINSOURCE , FMC_A9_AF);
    GPIO_PinAFConfig(FMC_A10_GPIO_PORT, FMC_A10_PINSOURCE , FMC_A10_AF);
    GPIO_PinAFConfig(FMC_A11_GPIO_PORT, FMC_A11_PINSOURCE , FMC_A11_AF);
    GPIO_PinAFConfig(FMC_A12_GPIO_PORT, FMC_A12_PINSOURCE , FMC_A12_AF);

    GPIO_PinAFConfig(FMC_BA0_GPIO_PORT, FMC_BA0_PINSOURCE , FMC_BA0_AF);
    GPIO_PinAFConfig(FMC_BA1_GPIO_PORT, FMC_BA1_PINSOURCE , FMC_BA1_AF);

    GPIO_PinAFConfig(FMC_D0_GPIO_PORT, FMC_D0_PINSOURCE , FMC_D0_AF);
    GPIO_PinAFConfig(FMC_D1_GPIO_PORT, FMC_D1_PINSOURCE , FMC_D1_AF);
    GPIO_PinAFConfig(FMC_D2_GPIO_PORT, FMC_D2_PINSOURCE , FMC_D2_AF);
    GPIO_PinAFConfig(FMC_D3_GPIO_PORT, FMC_D3_PINSOURCE , FMC_D3_AF);
    GPIO_PinAFConfig(FMC_D4_GPIO_PORT, FMC_D4_PINSOURCE , FMC_D4_AF);
    GPIO_PinAFConfig(FMC_D5_GPIO_PORT, FMC_D5_PINSOURCE , FMC_D5_AF);
    GPIO_PinAFConfig(FMC_D6_GPIO_PORT, FMC_D6_PINSOURCE , FMC_D6_AF);
    GPIO_PinAFConfig(FMC_D7_GPIO_PORT, FMC_D7_PINSOURCE , FMC_D7_AF);
    GPIO_PinAFConfig(FMC_D8_GPIO_PORT, FMC_D8_PINSOURCE , FMC_D8_AF);
    GPIO_PinAFConfig(FMC_D9_GPIO_PORT, FMC_D9_PINSOURCE , FMC_D9_AF);
    GPIO_PinAFConfig(FMC_D10_GPIO_PORT, FMC_D10_PINSOURCE , FMC_D10_AF);
    GPIO_PinAFConfig(FMC_D11_GPIO_PORT, FMC_D11_PINSOURCE , FMC_D11_AF);
    GPIO_PinAFConfig(FMC_D12_GPIO_PORT, FMC_D12_PINSOURCE , FMC_D12_AF);
    GPIO_PinAFConfig(FMC_D13_GPIO_PORT, FMC_D13_PINSOURCE , FMC_D13_AF);
    GPIO_PinAFConfig(FMC_D14_GPIO_PORT, FMC_D14_PINSOURCE , FMC_D14_AF);
    GPIO_PinAFConfig(FMC_D15_GPIO_PORT, FMC_D15_PINSOURCE , FMC_D15_AF);

    GPIO_PinAFConfig(FMC_CS_GPIO_PORT, FMC_CS_PINSOURCE , FMC_CS_AF);
    GPIO_PinAFConfig(FMC_WE_GPIO_PORT, FMC_WE_PINSOURCE , FMC_WE_AF);
    GPIO_PinAFConfig(FMC_RAS_GPIO_PORT, FMC_RAS_PINSOURCE , FMC_RAS_AF);
    GPIO_PinAFConfig(FMC_CAS_GPIO_PORT, FMC_CAS_PINSOURCE , FMC_CAS_AF);
    GPIO_PinAFConfig(FMC_CLK_GPIO_PORT, FMC_CLK_PINSOURCE , FMC_CLK_AF);
    GPIO_PinAFConfig(FMC_CKE_GPIO_PORT, FMC_CKE_PINSOURCE , FMC_CKE_AF);
    GPIO_PinAFConfig(FMC_UDQM_GPIO_PORT, FMC_UDQM_PINSOURCE , FMC_UDQM_AF);
    GPIO_PinAFConfig(FMC_LDQM_GPIO_PORT, FMC_LDQM_PINSOURCE , FMC_LDQM_AF);    


    GPIO_InitTypeDef GPIO_Init_Struct;
    GPIO_Init_Struct.GPIO_Mode = GPIO_Mode_AF;
    GPIO_Init_Struct.GPIO_Speed = GPIO_High_Speed;
    GPIO_Init_Struct.GPIO_OType = GPIO_OType_PP;
    GPIO_Init_Struct.GPIO_PuPd = GPIO_PuPd_NOPULL;
    
    /*A0-A9 */
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4\
                               |GPIO_Pin_5|GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
    GPIO_Init(GPIOF,&GPIO_Init_Struct);
    /*A10-A12*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
    GPIO_Init(GPIOG,&GPIO_Init_Struct);
    /*BA0-BA1*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_4|GPIO_Pin_5;
    GPIO_Init(GPIOG,&GPIO_Init_Struct);
    /*D0-D3*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_14|GPIO_Pin_15;
    GPIO_Init(GPIOD,&GPIO_Init_Struct);
    /*D4-D12*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_7|GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10|GPIO_Pin_11\
                               |GPIO_Pin_12|GPIO_Pin_13|GPIO_Pin_14|GPIO_Pin_15;
    GPIO_Init(GPIOE,&GPIO_Init_Struct);
    /*D13-D15*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_8|GPIO_Pin_9|GPIO_Pin_10;
    GPIO_Init(GPIOD,&GPIO_Init_Struct);
    /*CS SDNE1 SDRAM储存区域2芯片使能*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_6;
    GPIO_Init(GPIOH,&GPIO_Init_Struct);
    /*WE SDNWE 写入使能*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_0;
    GPIO_Init(GPIOC,&GPIO_Init_Struct);
    /*RAS NRAS 行地址选通*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_11;
    GPIO_Init(GPIOF,&GPIO_Init_Struct);
    /*CAS NCAS 列地址选通*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_15;
    GPIO_Init(GPIOG,&GPIO_Init_Struct);
    /*CLK SDCLK SDRAM时钟*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_8;
    GPIO_Init(GPIOG,&GPIO_Init_Struct);
    /*CKE SDCKE1 存储区域2时钟使能*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_7;
    GPIO_Init(GPIOH,&GPIO_Init_Struct);
    /*DQM1 NBL1*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_1;
    GPIO_Init(GPIOE,&GPIO_Init_Struct);
    /*DQM0 NBL0*/
    GPIO_Init_Struct.GPIO_Pin = GPIO_Pin_0;
    GPIO_Init(GPIOE,&GPIO_Init_Struct);
}

2. 配置FMC时序

/*FMC 时序配置*/
static void BSP_FMC_SDRAM_Timing_Init(void)
{
    RCC_AHB3PeriphClockCmd(RCC_AHB3Periph_FMC, ENABLE);
    
    FMC_SDRAMInitTypeDef  FMC_SDRAMInitStructure;
    
    /*FMC时序结构体 FMC_SDRAMInitStructure.FMC_SDRAMTimingStructAC
    ELECTRICAL CHARACTERISTICS OPERATING FREQUENCY  LATENCY RELATIONSHIPS*/
    FMC_SDRAMTimingInitTypeDef FMC_SDRAMTimingInitStructure;
    FMC_SDRAMTimingInitStructure.FMC_LoadToActiveDelay = 2;//TMRD
    FMC_SDRAMTimingInitStructure.FMC_ExitSelfRefreshDelay = 7;//TXSR
    FMC_SDRAMTimingInitStructure.FMC_SelfRefreshTime = 4;//TRAS
    FMC_SDRAMTimingInitStructure.FMC_RowCycleDelay = 7;//TRC
    FMC_SDRAMTimingInitStructure.FMC_WriteRecoveryTime = 2;//TWR
    FMC_SDRAMTimingInitStructure.FMC_RPDelay = 2;//TRP
    FMC_SDRAMTimingInitStructure.FMC_RCDDelay = 2;//TRCD
    
    FMC_SDRAMInitStructure.FMC_Bank = FMC_Bank2_SDRAM;//使用SDRAM Bank2 FMC_SDRAM2
    FMC_SDRAMInitStructure.FMC_ColumnBitsNumber = FMC_ColumnBits_Number_9b;//列地址位
    FMC_SDRAMInitStructure.FMC_RowBitsNumber = FMC_RowBits_Number_13b;//行地址位
    FMC_SDRAMInitStructure.FMC_SDMemoryDataWidth = FMC_SDMemory_Width_16b;//数据位宽
    FMC_SDRAMInitStructure.FMC_InternalBankNumber = FMC_InternalBank_Number_4;//芯片Bank个数
    FMC_SDRAMInitStructure.FMC_CASLatency = FMC_CAS_Latency_2;
    FMC_SDRAMInitStructure.FMC_WriteProtection = FMC_Write_Protection_Disable;//关闭写保护
    FMC_SDRAMInitStructure.FMC_SDClockPeriod = FMC_SDClock_Period_2;//2分频
    FMC_SDRAMInitStructure.FMC_ReadBurst = FMC_Read_Burst_Enable;
    FMC_SDRAMInitStructure.FMC_ReadPipeDelay = FMC_ReadPipe_Delay_0;//
    FMC_SDRAMInitStructure.FMC_SDRAMTimingStruct = &FMC_SDRAMTimingInitStructure;
    FMC_SDRAMInit(&FMC_SDRAMInitStructure);
}

3.初始化SDRAM芯片

/*SDRAM芯片初始化*/
void BSP_SDRAM_Init(void)
{
    /*
    GPIO初始化
    */
    BSP_SDRAM_GPIO_Init();
    /*
    FMC初始化
    */
    BSP_FMC_SDRAM_Timing_Init();
    /*
    芯片初始化
    */
    FMC_SDRAMCommandTypeDef  FMC_SDRAMCommandStructure;
    
    FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_CLK_Enabled;//时钟使能
    FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;//FMC SDRAM2
    FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 0;//FMC_Command_Mode_AutoRefresh 命令使用
    FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;//FMC_Command_Mode_LoadMode 命令使用
    while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) == SET);
    FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);


    SDRAM_delay(0x0F);

    FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_PALL;//bank 预充电
    FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;//FMC SDRAM2
    FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 0;
    FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;
    while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) == SET);
    FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
    
    FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_AutoRefresh;//自刷新
    FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;//FMC SDRAM2
    FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 2;//FMC_Command_Mode_AutoRefresh 命令使用
    FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = 0;//FMC_Command_Mode_LoadMode 命令使用
    while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) == SET);
    FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
    
    FMC_SDRAMCommandStructure.FMC_CommandMode = FMC_Command_Mode_LoadMode;//设置SDRAM寄存器
    FMC_SDRAMCommandStructure.FMC_CommandTarget = FMC_Command_Target_bank2;//FMC SDRAM2
    FMC_SDRAMCommandStructure.FMC_AutoRefreshNumber = 1;//FMC_Command_Mode_AutoRefresh 命令使用
    FMC_SDRAMCommandStructure.FMC_ModeRegisterDefinition = SDRAM_MODE1;//FMC_Command_Mode_LoadMode 命令使用
    while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) == SET);
    FMC_SDRAMCmdConfig(&FMC_SDRAMCommandStructure);
    
    /* 设置刷新计数器 */
    /*刷新速率 = (COUNT + 1) x SDRAM 频率时钟
    COUNT =( SDRAM 刷新周期/行数) - 20*/
    /* 64ms/8192=7.813us  (7.813 us x FSDCLK) - 20 =683 */
    while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) == SET);
    FMC_SetRefreshCount(683);
    
    while(FMC_GetFlagStatus(FMC_Bank2_SDRAM, FMC_FLAG_Busy) == SET);
}

4.在SDRAM中创建变量

/*FMC SDRAM 数据基地址 */   
#define SDRAM_BANK2_START_ADDRESS     ((uint32_t)0xD0000000)
#define SDRAM_BANK2_END_ADDRESS       ((uint32_t)0xDFFFFFFF)

/*BSP SDRAM*/
#define BSP_SDRAM_START_ADDRESS          SDRAM_BANK2_START_ADDRESS
#define BSP_SDRAM_SIZE                   (0x00800000)
#define BSP_SDRAM_END_ADDRESS            (BSP_SDRAM_ADDRESS+BSP_SDRAM_SIZE-1)

/*创建变量*/
uint32_t SDRAM_Test __attribute__((at(BSP_SDRAM_START_ADDRESS)));

 5.写入和读出数据

#ifdef  SDRAM_TEST
    printf("\nSDRAM TEST");
    BSP_SDRAM_Init();
    printf("\n在SDRAM中创建变量SDRAM_Test,赋值0xFFFF");
    SDRAM_Test = 0xFFFF;
    printf("\nSDRAM_Test Content: 0x%X",SDRAM_Test);
    printf("\nSDRAM_Test Address: 0x%X",(uint32_t)&SDRAM_Test);
    printf("\n\n直接对SDRAM地址赋值0xAA");
    *(uint16_t *)(BSP_SDRAM_START_ADDRESS) = 0xAA;
    printf("\nBSP_SDRAM_START_ADDRESS Content: 0x%X",*(uint16_t *)(BSP_SDRAM_START_ADDRESS));
    printf("\nBSP_SDRAM_START_ADDRESS Address: 0x%X",(uint16_t *)(BSP_SDRAM_START_ADDRESS));
#endif

6.测试结果

 

posted @ 2023-10-14 10:43  Yannnnnnn  阅读(149)  评论(0编辑  收藏  举报