关于STM32H743ZI SDMMC 1线模式下Stream模式写数据卡死的问题

CMD53读写数据,小于等于512字节时用stream模式,大于512字节时用block模式。
这在STM32F103和STM32F407的SDIO下测试过,都没问题。
然而同样的代码在STM32H743的SDMMC下运行,结果是:
(1)4线模式下,CMD53读写数据,不管是否使用IDMA, Stream/Block模式均正常。
(2)1线模式下,不管是否使用IDMA,情况如下:

方式情况
CMD53 Stream模式读数据正常
CMD53 Stream模式写数据卡死在while循环
CMD53 Block模式读数据正常
CMD53 Block模式写数据正常

为什么偏偏是STM32H7下的SDMMC无法用CMD53 Stream模式发数据呢?
研究了半天,发现是HAL库的问题。笔者用的HAL库版本是STM32Cube_FW_H7_V1.9.0。

仔细阅读STM32H743的Reference Manual,发现H7的SDMMC_DCTRL寄存器里面一共有四种传输模式:

然而,V1.9的HAL库里面,只给了我们两种选择:

也就是说SDMMC_DataInitTypeDef结构体的TransferMode成员要么选SDMMC_TRANSFER_MODE_BLOCK模式,要么选SDMMC_TRANSFER_MODE_STREAM模式,还剩下两种模式没法选。要是强行让TransferMode=SDMMC_DCTRL_DTMODE_0,那么IS_SDMMC_TRANSFER_MODE(MODE)返回0,SDMMC_ConfigData函数会报assert failed错误。

当TransferMode=SDMMC_TRANSFER_MODE_STREAM的时候,DTMODE=10,根据参考手册,此时恰好选择的是eMMC Stream data transfer模式,而且手册上明确说明了此模式仅在1线模式下有效。

要想解决这个问题,那就只有改HAL库的stm32h7xx_ll_sdmmc.h头文件了。增加SDMMC_TRANSFER_MODE_MULTIBYTE选项,当MODE等于这个新选项时IS_SDMMC_TRANSFER_MODE(MODE)要返回1:

#define SDMMC_TRANSFER_MODE_MULTIBYTE            SDMMC_DCTRL_DTMODE_0
#define IS_SDMMC_TRANSFER_MODE(MODE) (((MODE) == SDMMC_TRANSFER_MODE_BLOCK) || \
                                      ((MODE) == SDMMC_TRANSFER_MODE_MULTIBYTE) || \
                                      ((MODE) == SDMMC_TRANSFER_MODE_STREAM))

然后TransferMode改成SDMMC_TRANSFER_MODE_MULTIBYTE就可以了,问题解决!

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
STM32H743是一款高性能的微控制器,它内置了SDMMC控制器,可以用于SD卡和MMC卡的读操作。下面是使用STM32CubeMX和RT-Thread Studio进行SDMMC配置的详细过程: 1. 打开STM32CubeMX,选择对应的芯片型号,打开SDMMC功能。 2. 配置SDMMC时钟,使其与SD卡或MMC卡的时钟匹配。 3. 配置SDMMC数据线和命令线,使其与SD卡或MMC卡的接口匹配。 4. 生成代码并导入到RT-Thread Studio中。 5. 在RT-Thread Studio中编SDMMC操作的代码,例如: ```c #include "stm32h7xx_hal.h" #include "drv_sdmmc.h" #define SDMMC_BLOCK_SIZE 512 SD_HandleTypeDef hsd1; int sdmmc_init(void) { hsd1.Instance = SDMMC1; hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING; hsd1.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE; hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE; hsd1.Init.BusWide = SDMMC_BUS_WIDE_1B; hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE; hsd1.Init.ClockDiv = 2; if (HAL_SD_Init(&hsd1) != HAL_OK) { return -1; } return 0; } int sdmmc_read(uint32_t block_addr, uint8_t *buf, uint32_t block_cnt) { if (HAL_SD_ReadBlocks(&hsd1, buf, block_addr, block_cnt, SDMMC_TIMEOUT) != HAL_OK) { return -1; } return 0; } int sdmmc_write(uint32_t block_addr, uint8_t *buf, uint32_t block_cnt) { if (HAL_SD_WriteBlocks(&hsd1, buf, block_addr, block_cnt, SDMMC_TIMEOUT) != HAL_OK) { return -1; } return 0; } ``` 以上代码中,sdmmc_init()函数用于初始化SDMMC控制器,sdmmc_read()函数用于读取SD卡或MMC卡中的数据sdmmc_write()函数用于向SD卡或MMC卡中数据

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巨大八爪鱼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值