声明
我使用的是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方向可以像这样做