本帖最后由 qiousanxi 于 2019-6-27 19:41 编辑
1.驱动包括DMA和非DMA 操作,在H文件宏定义控制
#define SD_DMA 1 //是否使用DMA
2.关于SD卡的速度问题H7的板子没有1.8v所以最高速度为50M的 时钟,数据速度为25M
如果,你不是高速卡只支持25M的时钟频率,所以在这uSdHandle.Init.ClockDiv = 4;
设置为这个4 意思是ClockDiv 时钟分频
SD卡速度计算 SDMMC_CK = SDMMCCLK / (2 * ClockDiv) ,
SDMMCCLK 的时钟是用的PLL1 的 Q1 时钟分频为4 是200M
对于高速卡想用50M的时钟 需要在HAL库自己加点东西 在SD的HAL C文件中,
HAL_SD_ConfigWideBusOperation函数,2020 if判断 添加
else if(hsd->SdCard.CardType == CARD_SDHC_SDXC)
{
Init.ClockDiv = hsd->Init.ClockDiv;;
}
前提 你的卡支持高速读写,例如三星的32G 那款读90M 写20M的。 其他卡 你可以测试一下可能会不稳定,在写的时候,这个没长时间测试抱歉。
3.关于非DMA 的操作方法
使用写函数的时候
if (BSP_SD_WriteBlocks(...) == MSD_OK) //操作成功
{
timer = HAL_GetTick() + SD_TIMEOUT; //超时处理
while(timer > HAL_GETTICK())
{
if(BSP_SD_GetCardState() == SD_TRANSFER_OK)//SD卡状态查询
{
break;
}
}
}
读函数处理是一样的
4.DMA的操作
使用写函数的时候 如果需要使用系统 参考ST STM32Cube_FW_H7_V1.2.0ProjectsSTM32H743I_EVALApplicationsFatFsFatFs_uSD_DMA_RTOS 下的例程根据不同的RTOS 自行修改就行
alignedAddr = (uint32_t)buff & ~0x1F; //字节对其处理 我没有做透写所以需要刷
SCB_CleanDCache_by_Addr((uint32_t*)alignedAddr, count*BLOCKSIZE + ((uint32_t)count - alignedAddr)); //cache处理 DMA发送之前需要处理 读函数在读取完成后处理cache
if(BSP_SD_WriteBlocks_DMA((uint32_t*)buff,(uint32_t) (sector),count) == MSD_OK) //DMA 写操作
{
timer = HAL_GetTick() + SD_TIMEOUT; //先要等待DMA 完成
while(timer > HAL_GetTick())
{
if (BSP_SD_GetDmaState() == SD_TRANSFER_OK) //这个处理在DMA的回调函数中
{
break;
}
}
timer = HAL_GetTick() + SD_TIMEOUT;
while(timer > HAL_GetTick()) //在等待 SD 卡的状态
{
if (BSP_SD_GetCardState() == SD_TRANSFER_OK)
{
break;
}
}
}
2019-6.27更新
如果SD卡 无法识别吧时钟分频改为4
可以看下我这个帖子
一周热门 更多>