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

【STM32F769】实现SD卡的FATFS

[复制链接]
lugl 发布时间:2025-3-15 14:30

1、新建基于STM32F769的基础工程,打开RCC、SYS、USART外设,此处略过。

2、打开SDMMC2,选择SD 4bits模式。时钟分频为4。

image.png

3、打开DMA发送与接收中断,并使能所有的中断。

image.png

4、打开FATFS,按下图选择:

image.png

5、打开使能DMA收发数据:

image.png

6、配置PLLQ时钟频率为48MHz,SDMMC的时钟源选择PLLQ

image.png

image.png

7、在工程设置中,按下图所示,输入自己工程的名称,项目文件夹、以及修改栈堆的大小。

image.png

8、生成工程后,使用vscode的STM32 VS Code Extension导入刚才生成的工程。

image.png

image.png

7、打开工程后,进入sdmmc.c修改MX_SDMMC2_SD_Init内容,添加初始化代码如下:

void MX_SDMMC2_SD_Init(void)
{

  /* USER CODE BEGIN SDMMC2_Init 0 */
  hsd2.Instance = SDMMC2;
  hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd2.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
  hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd2.Init.BusWide = SDMMC_BUS_WIDE_1B;
  hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd2.Init.ClockDiv = 4;
  if (HAL_SD_Init(&hsd2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_SD_ConfigWideBusOperation(&hsd2, SDMMC_BUS_WIDE_4B) != HAL_OK)
  {
    Error_Handler();
  }
  return;
  /* USER CODE END SDMMC2_Init 0 */

  /* USER CODE BEGIN SDMMC2_Init 1 */

  /* USER CODE END SDMMC2_Init 1 */
  hsd2.Instance = SDMMC2;
  hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd2.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
  hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd2.Init.BusWide = SDMMC_BUS_WIDE_4B;
  hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd2.Init.ClockDiv = 4;
  /* USER CODE BEGIN SDMMC2_Init 2 */

  /* USER CODE END SDMMC2_Init 2 */

}

9、在main.c添加测试代码:

  uint8_t wtext[] = "This is STM32 working with FatFs"; /* File write buffer */
  res = f_write(&file, wtext, sizeof(wtext) - 1, (void *)&byteswritten); // Exclude the null terminator
  if (res != FR_OK || byteswritten != sizeof(wtext) - 1)
  {
    printf("Failed to write to file test.txt\n");
    f_close(&file);
    return;
  }
  f_close(&file);
  if(f_open(&file, "test.txt", FA_READ) != FR_OK)
  {
    printf("Failed to open file test.txt\n");
    return;
  }
  else
  {
    printf("File test.txt opened successfully\n");  
    res = f_read(&file, rtext, sizeof(rtext) - 1, (void *)&bytesread); // Ensure space for null terminator
    if (res != FR_OK || bytesread == 0)
    {
      printf("Failed to read from file test.txt\n");
      f_close(&file);
      return;
    }
    else
    {
      rtext[bytesread] = '\0'; // Null-terminate the read data
      printf("File test.txt read successfully\n");
      printf("Read %lu bytes from file test.txt\n", bytesread);
      printf("Read data: %s\n", rtext);
      f_close(&file);
    }
  }

下载到开发板后,在串口中可以成功看到写入与读取的打印信息。

image.png

image.png
收藏 评论2 发布时间:2025-3-15 14:30

举报

2个回答
〃聪聪哥哥 回答时间:2025-3-17 19:43:39

楼主您好!

这个地方的代码:

hsd2.Init.BusWide = SDMMC_BUS_WIDE_1B; 这个地方为什么配置成这样的模式?

而且代码下方,判断了一下:这个地方不会进 error_handler() ;这个错误的中断马?

  if (HAL_SD_ConfigWideBusOperation(&hsd2, SDMMC_BUS_WIDE_4B) != HAL_OK)
  {
    Error_Handler();
  }


  /* USER CODE BEGIN SDMMC2_Init 0 */
  hsd2.Instance = SDMMC2;
  hsd2.Init.ClockEdge = SDMMC_CLOCK_EDGE_RISING;
  hsd2.Init.ClockBypass = SDMMC_CLOCK_BYPASS_DISABLE;
  hsd2.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  hsd2.Init.BusWide = SDMMC_BUS_WIDE_1B;
  hsd2.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_DISABLE;
  hsd2.Init.ClockDiv = 4;
  if (HAL_SD_Init(&hsd2) != HAL_OK)
  {
    Error_Handler();
  }
  if (HAL_SD_ConfigWideBusOperation(&hsd2, SDMMC_BUS_WIDE_4B) != HAL_OK)
  {
    Error_Handler();
  }
lugl 回答时间:2025-3-18 05:14:49

hsd2.Init.BusWide = SDMMC_BUS_WIDE_1B; 这个地方为什么配置成这样的模式?

而且代码下方,判断了一下:这个地方不会进 error_handler() ;这个错误的中断马?

1、根据SD的通信原理,需要选使用数据宽度为1bit来初始化,然后才能进行4bit通信。如果你一开始使用4bit来初始化,就会死活通信不上,他这个是stm32cubeMX的bug,不知道他们想不想修复。

2、error_handler()默认官方是个死循环,就是卡在那里,不让程序继续下去了。当然用户也可以自己实现这个函数,当然你也可以去掉这个函数。

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