硬汉嵌入式论坛

 找回密码
 立即注册
查看: 454|回复: 9
收起左侧

[STM32H7] STM32H7 FMC SDRAM读写

[复制链接]
回帖奖励 10 个金币 回复本帖可获得 10 个金币奖励! 每人限 1 次(中奖概率 10%)

3

主题

8

回帖

17

积分

新手上路

积分
17
发表于 2023-11-16 16:45:47 | 显示全部楼层 |阅读模式
FMC接口控制SDRAM,连续读写断断续续出错,跪请大神帮忙看看,卡了一天了!


FMC初始化配置代码:


SDRAM初始化代码:



读写测试代码:


    printf("SDRAM 读写测试-8位\r\n");
   
    *(__IO uint8_t *) (Bank5_SDRAM_ADDR) = (uint8_t)writedata_8;

    readdata_8 = *(__IO uint8_t *)(Bank5_SDRAM_ADDR);

    printf("readdata_8 :%x\r\n", readdata_8);

    printf("SDRAM 读写测试-16位\r\n");

    *(__IO uint16_t *) (Bank5_SDRAM_ADDR) = (uint16_t)writedata_16;

    readdata_16 = *(__IO uint16_t *)(Bank5_SDRAM_ADDR);
    printf("readdata_16 :%x\r\n", readdata_16);


    *(__IO uint16_t *) (Bank5_SDRAM_ADDR + 2) = (uint16_t)(writedata_16 + 1);


    readdata_16 = *(__IO uint16_t *)(Bank5_SDRAM_ADDR + 2);
    printf("readdata_16 :%x\r\n", readdata_16);


    readdata_8 = *(__IO uint8_t *)(Bank5_SDRAM_ADDR);
    printf("readdata_8 :%x\r\n", readdata_8);


    readdata_8 = *(__IO uint8_t *)(Bank5_SDRAM_ADDR + 1);
    printf("readdata_8 :%x\r\n", readdata_8);


    readdata_8 = *(__IO uint8_t *)(Bank5_SDRAM_ADDR + 2);
    printf("readdata_8 :%x\r\n", readdata_8);


    for(i = 0; i < 8 * 1024 * 1024; i++)
    {
        writedata_8 = i;
        *(__IO uint8_t *) (Bank5_SDRAM_ADDR + i) = (uint8_t)writedata_8;

        readdata_8 = *(__IO uint8_t *)(Bank5_SDRAM_ADDR + i);

        if(readdata_8 != writedata_8)
        {
            printf("ERROR@ %x, writedata_8: %d, readdata_8: %d\r\n", Bank5_SDRAM_ADDR + i, writedata_8, readdata_8);
        }
        printf("*");
    }



打印结果:


回复

使用道具 举报

3

主题

8

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2023-11-16 16:46:59 | 显示全部楼层
  hsdram1.Instance = FMC_SDRAM_DEVICE;
  /* hsdram1.Init */
  hsdram1.Init.SDBank = FMC_SDRAM_BANK1;
  hsdram1.Init.ColumnBitsNumber = FMC_SDRAM_COLUMN_BITS_NUM_8;
  hsdram1.Init.RowBitsNumber = FMC_SDRAM_ROW_BITS_NUM_12;
  hsdram1.Init.MemoryDataWidth = FMC_SDRAM_MEM_BUS_WIDTH_16;
  hsdram1.Init.InternalBankNumber = FMC_SDRAM_INTERN_BANKS_NUM_4;
  hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  hsdram1.Init.WriteProtection = FMC_SDRAM_WRITE_PROTECTION_DISABLE;
  hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  hsdram1.Init.ReadBurst = FMC_SDRAM_RBURST_ENABLE;
  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
  /* SdramTiming */
  SdramTiming.LoadToActiveDelay = 2;
  SdramTiming.ExitSelfRefreshDelay = 7;
  SdramTiming.SelfRefreshTime = 5;
  SdramTiming.RowCycleDelay = 7;
  SdramTiming.WriteRecoveryTime = 2;
  SdramTiming.RPDelay = 2;
  SdramTiming.RCDDelay = 2;


void SDRAM_Initialization_Sequence(SDRAM_HandleTypeDef *hsdram)
{
        uint32_t temp = 0U;
       
        SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_CLK_ENABLE,1,0); //时钟配置使能
       
        HAL_Delay(1);
       
        SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_PALL,1,0);       //对所有存储区预充甿
       
        SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_AUTOREFRESH_MODE,8,0);//设置自刷新次敿
       
        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,单点访问
        printf("mode register: %x\r\n", temp);
    SDRAM_Send_Cmd(0,FMC_SDRAM_CMD_LOAD_MODE,1,temp);   //设置SDRAM的模式寄存器
       

        HAL_SDRAM_ProgramRefreshRate(&hsdram1,1543);       
}
回复

使用道具 举报

3

主题

8

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2023-11-16 17:19:50 | 显示全部楼层
打印结果:
SDRAM 读写测试-8位
readdata_8 :aa
SDRAM 读写测试-16位
readdata_16 :1234
readdata_16 :1235
readdata_8 :35
readdata_8 :12
readdata_8 :35
*************************************************************************************************************************************************        ****************************************************************************************************************ERROR@ c0000101, writedata_8: 1,         readdata_8: 67
*ERROR@ c0000102, writedata_8: 2, readdata_8: 84
*ERROR@ c0000103, writedata_8: 3, readdata_8: 85
*ERROR@ c0000104, writedata_8: 4, readdata_8: 66
*ERROR@ c0000105, writedata_8: 5, readdata_8: 78
*ERROR@ c0000106, writedata_8: 6, readdata_8: 210
*ERROR@ c0000107, writedata_8: 7, readdata_8: 117
*ERROR@ c0000108, writedata_8: 8, readdata_8: 4
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2023-11-16 17:38:41 | 显示全部楼层
是不是自己做的板子,如果是自己做的板子,优先检查焊接,论坛90%的SDRAM问题都是焊接问题导致的,程序基本都是标准配置,基本不会出错。
回复

使用道具 举报

3

主题

8

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2023-11-16 17:55:42 | 显示全部楼层
eric2013 发表于 2023-11-16 17:38
是不是自己做的板子,如果是自己做的板子,优先检查焊接,论坛90%的SDRAM问题都是焊接问题导致的,程序基本 ...

您好,我想先确认一下是我软件配置是否出错,不好意思麻烦硬件同时,
现在每次上电,连续读写出错的起始地址均不同
回复

使用道具 举报

3

主题

8

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2023-11-16 19:00:16 | 显示全部楼层
eric2013 发表于 2023-11-16 17:38
是不是自己做的板子,如果是自己做的板子,优先检查焊接,论坛90%的SDRAM问题都是焊接问题导致的,程序基本 ...

    for(i = 0; i < 8 * 1024 * 1024; i++)
    {
        //HAL_Delay(10);
        writedata_8 = i;
        *(__IO uint8_t *) (Bank5_SDRAM_ADDR + i) = (uint8_t)writedata_8;

        readdata_8 = *(__IO uint8_t *)(Bank5_SDRAM_ADDR + i);

        if(readdata_8 != writedata_8)
        {
            printf("ERROR@ %x, writedata_8: %d, readdata_8: %d\r\n", Bank5_SDRAM_ADDR + i, writedata_8, readdata_8);
        }
        printf("*");
    }
硬汉哥,现在每次读写加10ms的延时,就能读写正常,但去掉延时就出错,请教一下可能是那个地方有问题?
回复

使用道具 举报

26

主题

23

回帖

101

积分

初级会员

积分
101
发表于 2023-11-17 18:58:17 | 显示全部楼层
几层板? SDRAM 有没有等长走线?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2023-11-18 08:09:29 | 显示全部楼层
SRIlyy 发表于 2023-11-16 19:00
for(i = 0; i < 8 * 1024 * 1024; i++)
    {
        //HAL_Delay(10);

调节下着三个参数试试。

  hsdram1.Init.CASLatency = FMC_SDRAM_CAS_LATENCY_3;
  hsdram1.Init.SDClockPeriod = FMC_SDRAM_CLOCK_PERIOD_2;
  hsdram1.Init.ReadPipeDelay = FMC_SDRAM_RPIPE_DELAY_0;
回复

使用道具 举报

3

主题

8

回帖

17

积分

新手上路

积分
17
 楼主| 发表于 2023-11-18 09:43:24 | 显示全部楼层
硬汉哥,我将FMC的频率降下来后,读写测试通过了。
还想请教几个问题。
1. 如果向0xC000_0000地址写16位0x1234,那么我读0xC000_0000地址的数据应该是0x34,读0x000_0001地址的数据应该是0x12么?
2. SDRAM能够进行断电调试,断电调试,写入数据后,为什么查看memory没有变化呢?
回复

使用道具 举报

1万

主题

6万

回帖

10万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
106913
QQ
发表于 2023-11-18 09:59:11 | 显示全部楼层
SRIlyy 发表于 2023-11-18 09:43
硬汉哥,我将FMC的频率降下来后,读写测试通过了。
还想请教几个问题。
1. 如果向0xC000_0000地址写16位0 ...

MC的频率降下来后能通过,说明硬件布线确实可以改进下
1、小端格式,低地址存34,高地址12
2、断电调试怎么理解。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2024-5-10 01:39 , Processed in 0.272201 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表