摘要:

  • cubemax 工程建立(主要描述SDIO和FATFS配置部分,实际上还添加了串口用作调试打印)
  • 代码示例
  • 主函数、fatfs、sdio接口之间的层次关系

 

cubemax工程建立:

首先,找到SDIO,进行配置。SDIO的模式有1bit、4bits总线模式,根据板子的原理图进行选择。SDIO其他参数保持默认,只修改SDIO时钟分频因子。这个时钟分频出来的频率就是SDIO_CK引脚输出的频率,分频公式:SDIOCLK/ (CLKDIV+2)。SDIOCLK=HCLK。我的开发板时钟是168MHz,这里分频系数为6,也就是168/(6+2) = 21MHz。(如果测试发现读写失败,可以尝试增大分频系数)

 SDIO_CK输出的频率为21MHz,比较大,所以这里使用DMA收发数据。

SDIO的全局中断打开。这里我把SDIO中断优先级设置得比DMA中断高。因为我希望SDIO操作结束之后再进行DMA操作。

添加FATFS,模式选择" SD Card "

Set Defines--->Locale and Namespace Parameters:

  " CODE_PAGE(code page on target) "选择 Simplified Chinese GBK(支持中文编码)

  " USE_LFN(Use Long Filename)" 选择 Enabled with static working buffer on the BBS(支持长文件名,使用BSS静态工作缓冲区)

其他参数保持默认

 Advanced Settings--->SDIO/SDMMC--->Use dma template 选择 Enable

最后,增大栈空间,避免空间溢出的问题。

 

 代码示例:

FRESULT res;
extern SD_HandleTypeDef hsd;
HAL_SD_CardInfoTypeDef SDCardInfo; //SD卡信息结构体
FATFS fs; // 文件系统对象
FIL fil; // 文件对象
char buff[512]; // 数据缓存区

(下面代码添加到main函数中)

res = f_mount(&fs,"",1);//挂载

//得到卡的信息并输出到串口1
HAL_SD_GetCardInfo(&hsd, &SDCardInfo);//获取SD卡信息
printf("Card Type:%ld\r\n",SDCardInfo.CardType); //卡类型
printf("Card CardVersion:%ld\r\n",SDCardInfo.CardVersion);//CardVersion
printf("Card RCA:%ld\r\n",SDCardInfo.RelCardAdd);//卡相对地址
printf("Card Capacity:%ld MB\r\n",(uint32_t)(SDCardInfo.LogBlockNbr)>>11); //显示容量
printf("Card BlockSize:%ld\r\n\r\n",SDCardInfo.LogBlockSize);//显示块大小

//打开文件
if(f_open(&fil, "test.txt", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
{
  f_puts("SD card write test!", &fil);
  f_close(&fil);
}
if(f_open(&fil, "test.txt", FA_READ) == FR_OK)
{
  f_gets(buff, sizeof(buff), &fil);
  f_close(&fil);
}

Res = f_mount(NULL,"",1);//取消挂载

printf(buff);//打印sd卡读到得内容

主函数、fatfs、sdio接口之间的层次关系