硬汉嵌入式论坛

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

[SD/SDIO] SDMMC1驱动eMMc,时钟大于5MHz,读写就会出错

[复制链接]

10

主题

56

回帖

86

积分

初级会员

积分
86
发表于 2025-3-5 09:53:57 | 显示全部楼层 |阅读模式
芯片是STM32H750ZBxx,SDMMC1外设3.3V驱动eMMc,8数据线。

使用cubemx生成代码,HAL库版本:1.11.2,没有使用MPU,内存使用的是AXI_RAM,阻塞式读写

eMMc是:16GB THGBMJG7C1LBAIL,8个数据线、时钟线STM32内部上拉,reset线初始化置高。


读写使用的是HAL的库函数,连续读1000次,每次1个块。问题是:
时钟大于5MHz的情况下,初始化可以成功,读CSD、CID、Ext_CSD成功,但是读写出错,应该是报超时错误。
时钟大于20MHz,初始化可以成功,读CSD失败。


MCU时钟200MHz

MCU时钟

MCU时钟

SDMMC时钟

SDMMC时钟

SDMMC时钟

SDMMC设置

SDMMC设置

SDMMC设置

SDMMC的GPIO

SDMMC的GPIO

SDMMC的GPIO



测试代码:
[C] 纯文本查看 复制代码
  HAL_MMC_CardInfoTypeDef CardInfo;
  HAL_MMC_CardCIDTypeDef CardCID;
  HAL_MMC_CardCSDTypeDef CardCSD;
  HAL_MMC_CardStateTypeDef CardState;
  HAL_MMC_StateTypeDef MMC_state;
  HAL_StatusTypeDef hal_state;
  uint8_t ExtCSD[512];

  CardState = HAL_MMC_GetCardState(&hmmc1);

  HAL_MMC_GetCardExtCSD(&hmmc1, (uint32_t *)ExtCSD, 100);
  printf("183:%x,185:%x\n",ExtCSD[183],ExtCSD[185]);

  hal_state = HAL_MMC_GetCardInfo(&hmmc1, &CardInfo);
  hal_state = HAL_MMC_GetCardCID(&hmmc1, &CardCID);
  hal_state = HAL_MMC_GetCardCSD(&hmmc1, &CardCSD);
  hal_state = HAL_MMC_GetCardExtCSD(&hmmc1, (uint32_t *)ExtCSD, 100);
  CardState = HAL_MMC_GetCardState(&hmmc1);
  MMC_state = HAL_MMC_GetState(&hmmc1);

  uint8_t mmc_data[512] = {0};
  uint8_t read_data[512] = {0};
  memset(mmc_data, 1, 100);

  hal_state = HAL_MMC_WriteBlocks_DMA(&hmmc1, mmc_data, 0, 1);
  hal_state = HAL_MMC_ReadBlocks_DMA(&hmmc1, read_data, 0, 1);

  uint16_t start_time = HAL_GetTick();
  for (uint32_t i = 0; i < 1000; i++)
  {
    hal_state = HAL_MMC_WriteBlocks(&hmmc1, mmc_data, i, 1, 100);
    if(hal_state != HAL_OK){
		printf("i=%d error=%d\n",i,hal_state);
        CardState = HAL_MMC_GetCardState(&hmmc1);
    }
  }
  uint16_t end_time = HAL_GetTick();
  uint16_t time = end_time - start_time;
  printf("Write time = %d",time);

  start_time = HAL_GetTick();
  for (uint32_t i = 0; i < 1000; i++)
  {
    hal_state = HAL_MMC_ReadBlocks(&hmmc1, mmc_data, i, 1, 100);
    if(hal_state != HAL_OK){
      MMC_state = HAL_MMC_GetState(&hmmc1);
      CardState = HAL_MMC_GetCardState(&hmmc1);
	  printf("i=%d error=%d\n",i,hal_state);
    }
  }
  end_time = HAL_GetTick();
  time = end_time - start_time;
  printf("Read time = %d",time);




















回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-5 09:58:33 | 显示全部楼层
配置为1线方式试试
回复

使用道具 举报

10

主题

56

回帖

86

积分

初级会员

积分
86
 楼主| 发表于 2025-3-5 13:36:45 | 显示全部楼层
eric2013 发表于 2025-3-5 09:58
配置为1线方式试试

4线可以到10M,20M读写死循环,
卡在SDMMC_GetCmdResp1函数中的
[C] 纯文本查看 复制代码
while (((sta_reg & (SDMMC_FLAG_CCRCFAIL | SDMMC_FLAG_CMDREND | SDMMC_FLAG_CTIMEOUT |
SDMMC_FLAG_BUSYD0END)) == 0U) || ((sta_reg & SDMMC_FLAG_CMDACT) != 0U));


1线可以到50M,
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-5 14:35:44 | 显示全部楼层
quanshimutou 发表于 2025-3-5 13:36
4线可以到10M,20M读写死循环,
卡在SDMMC_GetCmdResp1函数中的
[mw_shl_code=c,true]while (((sta_reg ...

可以降低下GPIO速度等级试试。
回复

使用道具 举报

10

主题

56

回帖

86

积分

初级会员

积分
86
 楼主| 发表于 2025-3-5 15:53:13 | 显示全部楼层
eric2013 发表于 2025-3-5 14:35
可以降低下GPIO速度等级试试。

把SDMMC的GPIO的最大输出速度改为High或medium,还是读写失败。
硬汉哥有没有STM32H7驱动eMMc的工程,让我参考参考?
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117530
QQ
发表于 2025-3-6 09:12:58 | 显示全部楼层
quanshimutou 发表于 2025-3-5 15:53
把SDMMC的GPIO的最大输出速度改为High或medium,还是读写失败。
硬汉哥有没有STM32H7驱动eMMc的工程,让 ...

我们H7-TOOL开源的APP V1.X工程,是用的eMMC

https://forum.anfulai.cn/forum.p ... &highlight=2.27
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2025-8-12 20:29 , Processed in 0.043425 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

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