你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【经验分享】使用STM32Cube在STM32F7开发板上实现SD+Freertos+Fatfs

[复制链接]
STMCU小助手 发布时间:2021-12-16 21:00
简介
最近项目中可能需要使用到SD卡,所以需要对SD卡的配置和使用调研,在配置过程中遇到了一些问题,在此记录一下。

STM32Cube配置
Pinout

20180521180114826.png


20180521180129690.png


只需要注意绿色部分的设定

Clock配置
20180521180815759.png


这里使用了最大的Clock,SDMMC1的时钟是48MHz

FATFS配置

20180521181353894.png


Freertos配置

20180521183255134.png


这里增大了Heap size,使用了heap_4的内存管理方式。

SD卡配置

20180521183527404.png


2018052118353658.png


在这里打开SD的全局中断,并使用DMA2的方式传输数据

NVIC配置

20180521183735142.png


SD的全局中断配置为5,DMA中断配置为6,5的优先级更高。

工程配置

20180521184020944.png


20180521184028381.png


以上就是所有的配置内容了,配置完成后,直接使用Code generate功能就能自动生成keil工程。

代码修改
初始化SD卡
我生成的工程中需要手动添加BSP_SD_Init()函数,我是在MX_FATFS_Init()之前添加的。
  1. /* StartDefaultTask function */
  2. void StartDefaultTask(void const * argument)
  3. {
  4.   BSP_SD_Init();
  5.   /* init code for FATFS */
  6.   MX_FATFS_Init();

  7.   /* USER CODE BEGIN StartDefaultTask */
  8.   /* Infinite loop */
  9.   for(;;)
  10.   {
  11.     MX_FATFS_Run();
  12.     vTaskDelay( 5000 );
  13.   }
  14.   /* USER CODE END StartDefaultTask */
  15. }
复制代码

添加DMA中断处理函数
stm32f7xx_it.c文件中,需要添加下面两个中断处理函数:
  1. void HAL_SD_TxCpltCallback(SD_HandleTypeDef *hsd)
  2. {
  3.   BSP_SD_WriteCpltCallback();
  4. }

  5. void HAL_SD_RxCpltCallback(SD_HandleTypeDef *hsd)
  6. {
  7.   BSP_SD_ReadCpltCallback();
  8. }
复制代码

创建Queue
在自动生成的Demo中,使用了SDQueueID这个Queue,但并没有自动创建它,所以需要手动创建一下。我是在SD_initialize()这个函数中创建的,具体创建的地方可能需要再仔细考虑清楚。
  1. DSTATUS SD_initialize(BYTE lun)
  2. {
  3.   osMessageQDef(myQueueSD, QUEUE_SIZE, uint8_t*);
  4.   SDQueueID = osMessageCreate(osMessageQ(myQueueSD), NULL);
  5.   return SD_CheckStatus(lun);
  6. }
复制代码

将Pin的配置改为上拉
在默认配置函数中HAL_SD_MspInit()对SDIO的Pin的默认配置是GPIO_NOPULL,但我在使用过程中发现,程序会卡死在SD_FindSCR()函数的以下这段代码中:
  1.   /*卡在这个循环中出不去*/
  2.   while(!__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXOVERR | SDMMC_FLAG_DCRCFAIL | SDMMC_FLAG_DTIMEOUT | SDMMC_FLAG_DBCKEND))
  3.   {
  4.     if(__HAL_SD_GET_FLAG(hsd, SDMMC_FLAG_RXDAVL))
  5.     {
  6.       *(tempscr + index) = SDMMC_ReadFIFO(hsd->Instance);
  7.       index++;
  8.     }

  9.     if((HAL_GetTick() - tickstart) >=  SDMMC_DATATIMEOUT)
  10.     {
  11.       return HAL_SD_ERROR_TIMEOUT;
  12.     }
  13.   }
复制代码

后面我将GPIO改为GPIO_PULLUP后解决了这个问题,具体原因暂时还不清楚。

  1.     GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_11
  2.                           |GPIO_PIN_12;
  3.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  4.     GPIO_InitStruct.Pull = GPIO_PULLUP;//GPIO_NOPULL;
  5.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  6.     GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
  7.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  8.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  9.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  10.     GPIO_InitStruct.Pull = GPIO_PULLUP;//GPIO_NOPULL;
  11.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  12.     GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
  13.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
复制代码

简单Fatfs应用
  1. void StartDefaultTask(void const * argument)
  2. {
  3.     BSP_SD_Init();
  4.   /* init code for FATFS */
  5.   MX_FATFS_Init();

  6.   /* USER CODE BEGIN StartDefaultTask */
  7.   /* Infinite loop */

  8.   for(;;)
  9.   {
  10.     /*自己实现一个Run方法,每隔5秒往SD卡中的文件写入数据*/
  11.     MX_FATFS_Run();
  12.     vTaskDelay( 5000 );
  13.   }
  14.   /* USER CODE END StartDefaultTask */
  15. }

  16. void MX_FATFS_Init(void)
  17. {
  18.   /*## FatFS: Link the SD driver ###########################*/
  19.   retSD = FATFS_LinkDriver(&SD_Driver, SDPath);

  20.   /* USER CODE BEGIN Init */
  21.   /* 在Init的时候挂载文件系统 */     
  22.   if(f_mount(&SDFatFS, SDPath,0) != FR_OK)  
  23.   {  
  24.     while(1);
  25.   }   
  26.   /* USER CODE END Init */
  27. }

  28. void MX_FATFS_Run(void)
  29. {
  30.   UINT writeBytes;
  31.   /*文件系统基本操作:打开文件,定位到文件结尾,写入内容,关闭文件*/
  32.   if(f_open(&SDFile, "SDTest.txt", FA_READ|FA_WRITE|FA_OPEN_ALWAYS) != FR_OK)
  33.   {
  34.     while(1);
  35.   }
  36.   if(f_lseek(&SDFile, f_size(&SDFile)) != FR_OK)
  37.   {
  38.     while(1);
  39.   }
  40.   if(f_write(&SDFile, "sd Loop", sizeof("sd Loop"), &writeBytes) != FR_OK)
  41.   {
  42.     while(1);
  43.   }
  44.   if(f_close(&SDFile) != FR_OK)
  45.   {
  46.     while(1);
  47.   }
  48. }
复制代码

SD写入结果:

20180521190454697.png



收藏 评论0 发布时间:2021-12-16 21:00

举报

0个回答
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版