f103vet6进行SD卡读写遇到初始化卡死/轮询读写失败/DMA方式读写失败的解决方案

声明

我使用的是cubmx的STM32Cube FW F1 V1.8.5固件包,其中遇到生成出的代码在初始化卡死、轮询、DMA都失效的情况,可以说完全失败,每个原因还都不一样但是层层相关。。理解并不到位,哪里有问题望大佬们指出!

初始化失败的问题

如何配置

把sdio.c文件里的hsd.Init.BusWide = SDIO_BUS_WIDE_4B;结构体成员值替换成SDIO_BUS_WIDE_1B即可通过初始化

为什么

sdio.c文件里调用了HAL_SD_Init函数,这个函数无论BusWide是SDIO_BUS_WIDE_4B/SDIO_BUS_WIDE_1B都会通过,可是HAL_SD_ConfigWideBusOperation函数在BusWide是SDIO_BUS_WIDE_4B时会出问题

hsd.Init.BusWide在HAL_SD_ConfigWideBusOperation函数里的流程

问题就出在这个条件:hsd->ErrorCode != HAL_SD ERROR_NONE

它在hsd.Init.BusWide=SDIO_BUS_WIDE_4B时是不会成立的,else部分做的是SD卡传输配置,而它根本不配置

为什么这里会再配置结构体呢?不是已经配置过了嘛?

这是因为SD配置分为:初始化、数据传输,两种,初始化SD卡必须要用初始化配置,SD卡初始化部分由HAL_SD_Init层层调用实现的,数据传输配置就是HAL_SD_ConfigWideBusOperation实现

轮询方式读写数据不成功

轮询方式速度不能太高

如何配置

修改分频

sdio.c文件里的MX_SDIO_SD_Init函数里能看到

这个 hsd.Init.ClockDiv配置将它配置成小于24MHZ,不成功再逐步往小的配置再测试直到读写成功为止

例如ClockDiv我填入1,写入函数会执行失败,而大于5的时候可以成功读写,这速度已经远小于24MHZ了,但是ClockDiv我填入1时DMA任然可以胜任高速读写

DMA方式读写不成功

DMA不需要如轮询方式一样改这么多,首先把hsd.Init.BusWide = SDIO_BUS_WIDE_4B;结构体成员值替换成SDIO_BUS_WIDE_1B,然后在接收/发送完成回调函数最后部分添加__HAL_DMA_DISABLE宏关掉DMA

一般而言对于更加高级的板子,配置DMA部分都能看到tx/rx两个配置通道,而对于f103VET6来说,只有一个DMA通道能用。。。

对比一下DMA读写函数的实现

HAL_SD_WriteBlocks_DMA函数部分代码

HAL_SD_ReadBlocks_DMA函数部分代码

都有一个HAL_DMA_Start_IT函数在,此函数实现通道方向切换的功能,这代码看着当然没问题,实际用起来发现DMA通道老是切换不成功

如何配置

sdio.c文件里的hsd.Init.BusWide = SDIO_BUS_WIDE_4B;结构体成员值替换成SDIO_BUS_WIDE_1B

然后在接收/发送完成回调函数最后部分添加__HAL_DMA_DISABLE宏关掉DMA,如图

这样是为了保证通道方向切换成功,实测确实成功了!以后其他地方要切换DMA方向可以像这样做

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值