使用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.测试结果