|
本帖最后由 xiao菜鸡 于 2023-6-2 09:51 编辑
对SDRAM进行测试容量大小的操作,发现地址写入有问题,不知道是哪里出问题了,想要请教一下,谢谢啦
初始化代码如下
void InitExtSDRAM(void)
{
FMC_SDRAM_TimingTypeDef SDRAM_Timing;
SDRAM_Handler.Instance=FMC_SDRAM_DEVICE; //SDRAM在BANK5,6
SDRAM_Handler.Init.SDBank=FMC_SDRAM_BANK1; //SDRAM接在BANK5上
SDRAM_Handler.Init.ColumnBitsNumber=FMC_SDRAM_COLUMN_BITS_NUM_9; //列数量
SDRAM_Handler.Init.RowBitsNumber=FMC_SDRAM_ROW_BITS_NUM_13; //行数量
SDRAM_Handler.Init.MemoryDataWidth=FMC_SDRAM_MEM_BUS_WIDTH_16; //数据宽度为16位
SDRAM_Handler.Init.InternalBankNumber=FMC_SDRAM_INTERN_BANKS_NUM_4; //一共4个BANK
SDRAM_Handler.Init.CASLatency=FMC_SDRAM_CAS_LATENCY_3; //CAS为3
SDRAM_Handler.Init.WriteProtection=FMC_SDRAM_WRITE_PROTECTION_DISABLE; //失能写保护
SDRAM_Handler.Init.SDClockPeriod=FMC_SDRAM_CLOCK_PERIOD_2; //SDRAM时钟为HCLK/2=200M/2=100M=10ns
SDRAM_Handler.Init.ReadBurst=FMC_SDRAM_RBURST_ENABLE; //使能突发
SDRAM_Handler.Init.ReadPipeDelay=FMC_SDRAM_RPIPE_DELAY_0; //读通道延时
SDRAM_Timing.LoadToActiveDelay=2; //加载模式寄存器到激活时间的延迟为2个时钟周期
SDRAM_Timing.ExitSelfRefreshDelay=8; //退出自刷新延迟为8个时钟周期
SDRAM_Timing.SelfRefreshTime=6; //自刷新时间为6个时钟周期
SDRAM_Timing.RowCycleDelay=6; //行循环延迟为6个时钟周期
SDRAM_Timing.WriteRecoveryTime=2; //恢复延迟为2个时钟周期
SDRAM_Timing.RPDelay=2; //行预充电延迟为2个时钟周期
SDRAM_Timing.RCDDelay=2; //行到列延迟为2个时钟周期
HAL_SDRAM_Init(&SDRAM_Handler,&SDRAM_Timing);
SDRAM_Initialization_Sequence(&SDRAM_Handler); //发送SDRAM初始化序列
}
void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram)
{
uint32_t temp=0;
//SDRAM控制器初始化完成以后还需要按照如下顺序初始化SDRAM
SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_CLK_ENABLE,1,0); //时钟配置使能
Delay_us(500); //至少延时200us
SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_PALL,1,0); //对所有存储区预充电
SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_AUTOREFRESH_MODE,8,0);//设置自刷新次数
//配置模式寄存器,SDRAM的bit0~bit2为指定突发访问的长度,
//bit3为指定突发访问的类型,bit4~bit6为CAS值,bit7和bit8为运行模式
//bit9为指定的写突发模式,bit10和bit11位保留位
temp=(uint32_t)SDRAM_MODEREG_BURST_LENGTH_1 | //设置突发长度:1(可以是1/2/4/8)
SDRAM_MODEREG_BURST_TYPE_SEQUENTIAL | //设置突发类型:连续(可以是连续/交错)
SDRAM_MODEREG_CAS_LATENCY_3 | //设置CAS值:3(可以是2/3)
SDRAM_MODEREG_OPERATING_MODE_STANDARD | //设置操作模式:0,标准模式
SDRAM_MODEREG_WRITEBURST_MODE_SINGLE; //设置突发写模式:1,单点访问
SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_LOAD_MODE,1,temp); //设置SDRAM的模式寄存器
//刷新频率计数器(以SDCLK频率计数),计算方法:
//COUNT=SDRAM刷新周期/行数-20=SDRAM刷新周期(us)*SDCLK频率(Mhz)/行数
//我们使用的SDRAM刷新周期为64ms,SDCLK=200/2=100Mhz,行数为8192(2^13).
//所以,COUNT=64*1000*100/8192-20=762
HAL_SDRAM_ProgramRefreshRate(&SDRAM_Handler,762);
}
测试外部SDRAM代码如下
uint32_t TestExtSDRAM2(uint16_t MB)
{
uint32_t i;
uint32_t *pSRAM;
uint8_t *pBytes;
uint32_t err;
uint32_t TestSize=0;
const uint8_t ByteBuf[4] = {0x55, 0xA5, 0x5A, 0xAA};
TestSize=MB*1024*1024;
/* 写SRAM */
pSRAM = (uint32_t *)EXT_SDRAM_STARTADDR;
for (i = 0; i < TestSize / 4; i++)
{
*pSRAM++ = i;
}
/* 读SRAM */
err = 0;
pSRAM = (uint32_t *)EXT_SDRAM_STARTADDR;
for (i = 0; i < TestSize / 4; i++)
{
if (*pSRAM++ != i)
{
err++;
}
}
if (err > 0)
{
return (4 * err);
}
/* 对SRAM 的数据求反并写入 */
pSRAM = (uint32_t *)EXT_SDRAM_STARTADDR;
for (i = 0; i < TestSize / 4; i++)
{
*pSRAM = ~*pSRAM;
pSRAM++;
}
/* 再次比较SDRAM的数据 */
err = 0;
pSRAM = (uint32_t *)EXT_SDRAM_STARTADDR;
for (i = 0; i < TestSize / 4; i++)
{
if (*pSRAM++ != (~i))
{
err++;
}
}
if (err > 0)
{
return (4 * err);
}
/* 测试按字节方式访问, 目的是验证 FSMC_NBL0 、 FSMC_NBL1 口线 */
pBytes = (uint8_t *)EXT_SDRAM_STARTADDR;
for (i = 0; i < sizeof(ByteBuf); i++)
{
*pBytes++ = ByteBuf;
}
/* 比较SDRAM的数据 */
err = 0;
pBytes = (uint8_t *)EXT_SDRAM_STARTADDR;
for (i = 0; i < sizeof(ByteBuf); i++)
{
if (*pBytes++ != ByteBuf)
{
err++;
}
}
if (err > 0)
{
return err;
}
return 0;
}
测试结果如图所示
|
|