STM32L4使用HAL库SDMMC+DMA读写SD卡的问题
原创
©著作权归作者所有:来自51CTO博客作者天外飞仙CUG的原创作品,请联系作者获取转载授权,否则将追究法律责任
之前介绍过使用STM32F4系列的单片机SDIO接口读写SD卡及文件系统的教程,可参考《STM32CubeMX之SDIO+FatFS读写SD卡》。最近使用L4系列的,SDMMC接口+DMA读写SD卡,总是失败,发现了点问题,这里分享给大家。
还是使用STM32CubeMX进行配置:
使能DMA收发:
打开中断:
文件系统等其它配置这里不再介绍,可参考之前的文章。生成代码后,添加文件系统操作的相关程序:
retSD = f_mount(&SDFatFS, (TCHAR const*)SDPath, 1);retSD = f_open(&SDFile,"DATAFILE.txt",FA_READ|FA_OPEN_EXISTING);
运行时发现总是出错,改为非DMA方式就可以了。查了半天也不知道哪里的问题,后来对比官方的例程发现了问题。生成的代码中,SD卡的驱动文件bsp_drive_sd.c中,读写函数是没有红框中的部分的,需要自己加上。
上述两个函数也需要自己加上,从官方的例程中拷过来就行。
HAL_StatusTypeDef SD_DMAConfigRx(SD_HandleTypeDef *hsd)
{
HAL_StatusTypeDef status = HAL_ERROR;
/* Configure DMA Rx parameters */
hdma_sdmmc1_rx.Instance = DMA2_Channel4;
hdma_sdmmc1_rx.Init.Request = DMA_REQUEST_7;
hdma_sdmmc1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_sdmmc1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdmmc1_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdmmc1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdmmc1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdmmc1_rx.Init.Mode = DMA_NORMAL;
hdma_sdmmc1_rx.Init.Priority = DMA_PRIORITY_LOW;
/* Associate the DMA handle */
__HAL_LINKDMA(hsd,hdmarx,hdma_sdmmc1_rx);
/* Stop any ongoing transfer and reset the state*/
HAL_DMA_Abort(&hdma_sdmmc1_rx);
/* Deinitialize the Channel for new transfer */
HAL_DMA_DeInit(&hdma_sdmmc1_tx);
/* Configure the DMA Channel */
status = HAL_DMA_Init(&hdma_sdmmc1_rx);
return (status);
}
/**
* @brief Configure the DMA to transmit data to the SD card
* @retval
* HAL_ERROR or HAL_OK
*/
HAL_StatusTypeDef SD_DMAConfigTx(SD_HandleTypeDef *hsd)
{
HAL_StatusTypeDef status;
/* SDMMC1_TX Init */
hdma_sdmmc1_tx.Instance = DMA2_Channel5;
hdma_sdmmc1_tx.Init.Request = DMA_REQUEST_7;
hdma_sdmmc1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_sdmmc1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_sdmmc1_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_sdmmc1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
hdma_sdmmc1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_WORD;
hdma_sdmmc1_tx.Init.Mode = DMA_NORMAL;
hdma_sdmmc1_tx.Init.Priority = DMA_PRIORITY_LOW;
/* Associate the DMA handle */
__HAL_LINKDMA(hsd, hdmatx, hdma_sdmmc1_tx);
/* Stop any ongoing transfer and reset the state*/
HAL_DMA_Abort(&hdma_sdmmc1_tx);
/* Deinitialize the Channel for new transfer */
HAL_DMA_DeInit(&hdma_sdmmc1_rx);
/* Configure the DMA Channel */
status = HAL_DMA_Init(&hdma_sdmmc1_tx);
return (status);
}
F4单片机的SDIO+DMA读写是不需要这样操作的,这里就没有深入去研究了。
添加完成后,再运行程序,一切正常!
欢迎关注公众号"嵌入式技术开发",大家可以后台给我留言沟通交流。如果觉得该公众号对你有所帮助,也欢迎推荐分享给其他人。