[STM32H7] STM32H7S78-DK测评】-进阶任务之SD卡读写

[复制链接]
2135|3
 楼主| HuaWng 发表于 2024-10-12 12:38 | 显示全部楼层 |阅读模式
本帖最后由 HuaWng 于 2024-10-12 16:02 编辑

FatFs 是一个针对嵌入式系统设计的通用 FAT 文件系统模块,由日本工程师 ChaN 开发。它兼容 FAT12、FAT16 和 FAT32 文件系统,这是在许多嵌入式设备中广泛使用的存储格式。以下是 FatFs 文件系统的一些关键特性:
  • 轻量级和可移植性:FatFs 旨在占用较小的内存空间,非常适合资源受限的嵌入式系统。它使用 ANSI C 编写,可以很容易地移植到不同的平台。
  • 多卷支持:FatFs 支持使用多卷,即可以在同一系统中同时挂载多个存储设备或分区。
  • Unicode 支持:提供了对长文件名的支持,并且支持多种字符编码,包括 Unicode,因此能够处理各种语言的文件名。
  • 线程安全性:可以配置为线程安全,使得在多任务环境中使用时避免数据竞争问题。
  • 配置灵活性:FatFs 提供各种配置选项,可以根据特定需求对功能、内存使用等进行调整。
  • 兼容性强:支持针对不同的底层存储介质(如 SD 卡、闪存)定制化实现,因此非常灵活。


SDMMC接口的全称叫SD/SDIO MMC card host interface,SD/SDIO MMC 卡 主机接口,通俗的来说,就是这个接口支持SD 卡,支持SDIO设备,支持MMC卡。STM32H7S78-DK板载了SD卡槽,可以方便的使用H7自带的SDMMC接口来对该卡片进行读写操作。

912936709fbabd98b1.png

原理图:
383796709fbcf56c67.png

引脚配置:
452486709fc640ff31.png

功能配置:
407416709fc7bebb3f.png

初始化代码:
  1. void HAL_SD_MspInit(SD_HandleTypeDef* hsd)
  2. {
  3.   GPIO_InitTypeDef GPIO_InitStruct = {0};
  4.   RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};
  5.   if(hsd->Instance==SDMMC1)
  6.   {
  7. PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_SDMMC12;
  8.     PeriphClkInit.Sdmmc12ClockSelection = RCC_SDMMC12CLKSOURCE_PLL2S;
  9.     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  10.     {
  11.       Error_Handler();
  12.     }

  13. __HAL_RCC_SDMMC1_CLK_ENABLE();

  14.     __HAL_RCC_GPIOD_CLK_ENABLE();
  15.     __HAL_RCC_GPIOC_CLK_ENABLE();

  16.     GPIO_InitStruct.Pin = GPIO_PIN_2;
  17.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  18.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  19.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  20.     GPIO_InitStruct.Alternate = GPIO_AF11_SDMMC1;
  21.     HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);

  22.     GPIO_InitStruct.Pin = GPIO_PIN_10;
  23.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  24.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  25.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  26.     GPIO_InitStruct.Alternate = GPIO_AF12_SDMMC1;
  27.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  28.     GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_8|GPIO_PIN_9;
  29.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
  30.     GPIO_InitStruct.Pull = GPIO_NOPULL;
  31.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
  32.     GPIO_InitStruct.Alternate = GPIO_AF11_SDMMC1;
  33.     HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

  34. HAL_NVIC_SetPriority(SDMMC1_IRQn, 0, 0);

  35.   RCC_OscInitTypeDef RCC_OscInitStruct = {0};

  36.   RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  37.   RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  38.   RCC_OscInitStruct.HSIDiv = RCC_HSI_DIV1;
  39.   RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  40.   RCC_OscInitStruct.PLL1.PLLState = RCC_PLL_ON;
  41.   RCC_OscInitStruct.PLL1.PLLSource = RCC_PLLSOURCE_HSI;
  42.   RCC_OscInitStruct.PLL1.PLLM = 16;
  43.   RCC_OscInitStruct.PLL1.PLLN = 275;
  44.   RCC_OscInitStruct.PLL1.PLLP = 2;
  45.   RCC_OscInitStruct.PLL1.PLLQ = 2;
  46.   RCC_OscInitStruct.PLL1.PLLR = 2;
  47.   RCC_OscInitStruct.PLL1.PLLS = 2;
  48.   RCC_OscInitStruct.PLL1.PLLT = 2;
  49.   RCC_OscInitStruct.PLL1.PLLFractional = 0;
  50.   RCC_OscInitStruct.PLL2.PLLState = RCC_PLL_NONE;
  51.   RCC_OscInitStruct.PLL3.PLLState = RCC_PLL_NONE;
  52.   if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  53.   {
  54.     /* Initialization error */
  55.     while(1);
  56.   }

  57. __HAL_RCC_SDMMC1_FORCE_RESET();
  58.   __HAL_RCC_SDMMC1_RELEASE_RESET();

  59.   /* NVIC configuration for SDMMC interrupts */
  60.   HAL_NVIC_EnableIRQ(SDMMC1_IRQn);
  61.   /* USER CODE END SDMMC1_MspInit 1 */

  62.   }

  63. }


功能模块初始化:
  1. void MX_SDMMC1_SD_Init(void)
  2. {
  3. hsd1.Instance = SDMMC1;
  4.   hsd1.Init.ClockEdge = SDMMC_CLOCK_EDGE_FALLING;
  5.   hsd1.Init.ClockPowerSave = SDMMC_CLOCK_POWER_SAVE_DISABLE;
  6.   hsd1.Init.BusWide = SDMMC_BUS_WIDE_4B;
  7.   hsd1.Init.HardwareFlowControl = SDMMC_HARDWARE_FLOW_CONTROL_ENABLE;
  8.   hsd1.Init.ClockDiv = 0x02;
  9.   if (HAL_SD_Init(&hsd1) != HAL_OK)
  10.   {
  11.     Error_Handler();
  12.   }
  13. }

核心读写代码:
  1. static int32_t FS_FileOperations(void)
  2. {
  3.   FRESULT res; /* FatFs function common result code */
  4.   uint32_t byteswritten, bytesread; /* File write/read counts */
  5.   uint8_t rtext[100]; /* File read buffer */

  6.   /* Register the file system object to the FatFs module */
  7.   if(f_mount(&SDFatFs, (TCHAR const*)SDPath, 0) == FR_OK)
  8.   {
  9.     /* Create and Open a new text file object with write access */
  10.     if(f_open(&SDFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
  11.     {

  12.       /* Write data to the text file */
  13.       res = f_write(&SDFile, (const void *)wtext, sizeof(wtext), (void *)&byteswritten);

  14.       if((byteswritten > 0) && (res == FR_OK))
  15.       {
  16.         /* Close the open text file */
  17.         f_close(&SDFile);

  18.         /* Open the text file object with read access */
  19.         if(f_open(&SDFile, "STM32.TXT", FA_READ) == FR_OK)
  20.         {
  21.           /* Read data from the text file */
  22.           res = f_read(&SDFile, ( void *)rtext, sizeof(rtext), (void *)&bytesread);
  23.           printf("\r\n%s", rtext);
  24.           if((bytesread > 0) && (res == FR_OK))
  25.           {
  26.             /* Close the open text file */
  27.             f_close(&SDFile);

  28.             /* Compare read data with the expected data */
  29.             if(bytesread == byteswritten)
  30.             {

  31.               /* Success of the demo: no error occurrence */
  32.               return 0;
  33.             }
  34.           }
  35.         }
  36.       }
  37.     }
  38.   }
  39.   /* Error */
  40.   return -1;
  41. }

串口输出结果:
324176709fb309355c.png



把SD卡插入读卡器,在电脑中查看文本:
64906709fb5c0a549.png


然后

Amazingxixixi 发表于 2024-10-31 16:15 | 显示全部楼层
是SD接口还是SPI接口模拟的?
suncat0504 发表于 2024-10-31 17:23 | 显示全部楼层
读写SD,很实用的功能。
地瓜patch 发表于 2024-10-31 18:37 来自手机 | 显示全部楼层
这个文件系统是用的操作系统内的么
您需要登录后才可以回帖 登录 | 注册

本版积分规则

6

主题

38

帖子

0

粉丝
快速回复 在线客服 返回列表 返回顶部