cc1989summer 发表于 2024-10-1 21:25

【STM32H7S78-DK】⑤SD卡读写(基于FatFS)

<div class='showpostmsg'> 本帖最后由 cc1989summer 于 2024-10-1 21:31 编辑

<p>本篇分享SD卡的读写(基于FatFS)</p>

<p>为什么要基于FatFS呢。</p>

<p>理论上把SD当作EEPROM做存储用不就可以了吗。事实上这样存在的最大问题是:不兼容,单片机能识别,但因为没有文件系统,电脑、数码相机等无法识别。</p>

<p>用在嵌入式系统中的常用文件系统就是<strong>FatFS</strong>。(事实上还有款轻量版 <strong>Petit-FatFS:</strong>Petit FatFs 是FatFs的精简版,<strong>比较适用于低端8位/16位&nbsp;单片机 中</strong>。 可以用在小RAM的单片机中,RAM可以小于扇区的RAM(512bytes)中)</p>

<p>详见我很早以前移植到MSP430的帖子:<a href="https://bbs.eeworld.com.cn/thread-322657-1-1.html" target="_blank">https://bbs.eeworld.com.cn/thread-322657-1-1.html</a></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p><strong>FatFs 是面向小型嵌入式系统的一种通用的 FAT 文件系统。</strong>它完全是由 AISI C 语言编写并且完全独立于底层的 I/O 介质。因此它可以很容易地不加修改地移植到其他的处理器当中,如 8051、 PIC、 AVR、 SH、 Z80、 H8、 ARM 等。 FatFs 支持 FAT12、 FAT16、FAT32 等格式利用文件系统的各种函数,&nbsp;所以可以利用FatFs对 SPI Flash 芯片以&ldquo;文件&rdquo;格式进行读写操作。</p>

<p>FATFS优点:免费开源,专门为小型嵌入式系统设计,c编写,支持FAT12, FAT16 与 FAT32,支持多种存储媒介,有独立的缓冲区,可对多个文件进行读写,可裁剪的文件系统(极为重要)。</p>

<p>官方网址:</p>

<p><a href="http://elm-chan.org/fsw/ff/00index_e.html" target="_blank">http://elm-chan.org/fsw/ff/00index_e.html</a></p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<div style="text-align: left;"></div>

<p>&nbsp;</p>

<p>下面是FATFS的常见函数,有文件操作、目录操作、磁盘管理等。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>与MCU底层紧密相关的是下图中的绿色部分:mmc.c/spi.c/device.h</p>

<p>&nbsp;</p>

<div style="text-align: left;"></div>

<p>&nbsp;</p>

<p>言归正传:</p>

<p>&nbsp;STM32H7S78-DK使用的是SDMMC1模块(STM32H7S7L8具有两个SD模块:SDMMC1、SDMMC2)</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>microSD对应的接口:支持4位数据端口(SDMMC1_D0、SDMMC1_D1、SDMMC1_D2、SDMMC1_D3,很多低端MCU仅支持1位数据端口,速度较慢)</p>

<p> &nbsp;</p>

<p>回到CubeMX,我们设置SDMMC1为4位数据:<strong>SD 4 bit wide bus</strong></p>

<p>对应的GPIO就自动设置好了</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>在middleware and softpacks中启用FATFS,选中SD,并进行进一步参数配置,开启DMA等。</p>

<p>同时启用Free-RTOS,进行相关任务配置。</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>设置字符集为简体中文:</p>

<p> &nbsp;&nbsp;&nbsp;</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>生成的代码中SD卡已经设置好了:</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>在Fatfs.c中定义两个字符串。</p>

<p>我们将写入到SD卡。</p>

<pre>
<code>const static uint8_t wtext[] = "The STM32H7S78-DK Discovery kit is a complete demonstration and development platform for the Arm® Cortex®‑M7 core‑based STM32H7S7L8H6H microcontroller."; /* File write buffer */
const static uint8_t wtext1[] = "大江东去,浪淘尽,千古风流人物。故垒西边,人道是,三国周郎赤壁。乱石穿空,惊涛拍岸,卷起千堆雪。江山如画,一时多少豪杰。遥想公瑾当年,小乔初嫁了(liǎo),雄姿英(yīng)发。羽扇纶(guān)巾,谈笑间,樯橹灰飞烟灭。故国神游,多情应笑我,早生华(huā)发。人生如梦,一尊还酹(lèi)江月。"; /* File write buffer */</code></pre>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p>最为关键的FatFs 操作函数。</p>

<pre>
<code>static void FS_FileOperations(void)
{
FRESULT res;                                          /* FatFs function common result code */
uint32_t byteswritten, bytesread;                     /* File write/read counts */

//挂载SD卡到文件系统

/* Register the file system object to the FatFs module */
if(f_mount(&amp;SDFatFs, (TCHAR const*)SDPath, 0) == FR_OK)
{
    /* check whether the FS has been already created */
    if (isFsCreated == 0)
    {
      if(f_mkfs(SDPath, &amp;OptParm, workBuffer, sizeof(workBuffer)) != FR_OK)
      {
      HAL_GPIO_WritePin(LED2_GPIO_Port, LED2_Pin, GPIO_PIN_RESET);
      return;
      }
      isFsCreated = 1;
    }

//在SD卡上新建一个文件,把字符串1写入到文件中。

    /* Create and Open a new text file object with write access */
   if(f_open(&amp;SDFile, "STM32.TXT", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
   {
       /* Write data to the text file */
       res = f_write(&amp;SDFile, (const void *)wtext, sizeof(wtext), (void *)&amp;byteswritten);

       if((byteswritten &gt; 0) &amp;&amp; (res == FR_OK))
       {
         /* Close the open text file */
         f_close(&amp;SDFile);

         /* Open the text file object with read access */
         if(f_open(&amp;SDFile, "STM32.TXT", FA_READ) == FR_OK)
         {
         /* Read data from the text file */
         res = f_read(&amp;SDFile, ( void *)rtext, sizeof(rtext), (void *)&amp;bytesread);

         if((bytesread &gt; 0) &amp;&amp; (res == FR_OK))
         {
             /* Close the open text file */
             f_close(&amp;SDFile);

             /* Compare read data with the expected data */
             if(bytesread == byteswritten)
             {
               /* Success of the demo: no error occurrence */
               HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
               return;
             }
         }
         }
       }
   }


//在SD卡上新建一个文件,把字符串2写入到文件中。


   /* Create and Open a new text file object with write access */
   if(f_open(&amp;SDFile, "POEM.TXT", FA_CREATE_ALWAYS | FA_WRITE) == FR_OK)
   {
       /* Write data to the text file */
       res = f_write(&amp;SDFile, (const void *)wtext1, sizeof(wtext1), (void *)&amp;byteswritten);

       if((byteswritten &gt; 0) &amp;&amp; (res == FR_OK))
       {
         /* Close the open text file */
         f_close(&amp;SDFile);

         /* Open the text file object with read access */
         if(f_open(&amp;SDFile, "POEM.TXT", FA_READ) == FR_OK)
         {
         /* Read data from the text file */
         res = f_read(&amp;SDFile, ( void *)rtext, sizeof(rtext), (void *)&amp;bytesread);

         if((bytesread &gt; 0) &amp;&amp; (res == FR_OK))
         {
             /* Close the open text file */
             f_close(&amp;SDFile);

             /* Compare read data with the expected data */
             if(bytesread == byteswritten)
             {
               /* Success of the demo: no error occurrence */
               HAL_GPIO_WritePin(LED1_GPIO_Port, LED1_Pin, GPIO_PIN_RESET);
               return;
             }
         }
         }
       }
   }




</code></pre>

<p>&nbsp;</p>

<p>我们将随开发板赠送的micro-SD安装至卡槽,运行程序。</p>

<p>&nbsp;</p>

<p>&nbsp;</p>

<p> &nbsp;</p>

<p>&nbsp;</p>

<p>将SD卡插入读卡器连接电脑:</p>

<p>发现个问题:新创建的文件没有修改日期,待后面再折腾RTC解决了。</p>

<p>&nbsp;</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>打开文件,正是我们写入的两个字符串,可以看见中文正常显示,甚至连汉语拼音都没问题。</p>

<p>&nbsp;</p>

<div style="text-align: center;"></div>

<p>&nbsp;</p>

<p>本次分享就到这里。</p>
</div><script>                                        var loginstr = '<div class="locked">查看本帖全部内容,请<a href="javascript:;"   style="color:#e60000" class="loginf">登录</a>或者<a href="https://bbs.eeworld.com.cn/member.php?mod=register_eeworld.php&action=wechat" style="color:#e60000" target="_blank">注册</a></div>';
                                       
                                        if(parseInt(discuz_uid)==0){
                                                                                                (function($){
                                                        var postHeight = getTextHeight(400);
                                                        $(".showpostmsg").html($(".showpostmsg").html());
                                                        $(".showpostmsg").after(loginstr);
                                                        $(".showpostmsg").css({height:postHeight,overflow:"hidden"});
                                                })(jQuery);
                                        }                </script><script type="text/javascript">(function(d,c){var a=d.createElement("script"),m=d.getElementsByTagName("script"),eewurl="//counter.eeworld.com.cn/pv/count/";a.src=eewurl+c;m.parentNode.insertBefore(a,m)})(document,523)</script>

秦天qintian0303 发表于 2024-10-2 11:39

<p>嵌入式系统中的常用文件系统就是FatFS,这里的嵌入式系统都包括哪些?</p>

cc1989summer 发表于 2024-10-2 13:53

秦天qintian0303 发表于 2024-10-2 11:39
嵌入式系统中的常用文件系统就是FatFS,这里的嵌入式系统都包括哪些?

<p>Free-RTOS等:)</p>

chejm 发表于 2024-10-2 20:01

<p>楼主分享的有关SD读写的内容有点多,不过正是我需要的,非常感谢</p>

zgnasd1950 发表于 2024-10-3 03:21

页: [1]
查看完整版本: 【STM32H7S78-DK】⑤SD卡读写(基于FatFS)