{"id":12974,"date":"2024-01-19T20:52:26","date_gmt":"2024-01-19T12:52:26","guid":{"rendered":"https:\/\/blog.iyatt.com\/?p=12974"},"modified":"2024-05-05T12:30:53","modified_gmt":"2024-05-05T04:30:53","slug":"arduino-%e4%bd%bf%e7%94%a8-sd-%e5%8d%a1%e6%a8%a1%e5%9d%97%ef%bc%88%e7%bc%96%e8%be%91%e4%b8%ad%ef%bc%89","status":"publish","type":"post","link":"https:\/\/blog.iyatt.com\/?p=12974","title":{"rendered":"Arduino \u4f7f\u7528 SD \u5361\u6a21\u5757\uff08\u7f16\u8f91\u4e2d\uff09"},"content":{"rendered":"<div id=\"ez-toc-container\" class=\"ez-toc-v2_0_82_2 ez-toc-wrap-center counter-hierarchy ez-toc-counter ez-toc-light-blue ez-toc-container-direction\">\n<div class=\"ez-toc-title-container\">\n<p class=\"ez-toc-title ez-toc-toggle\" style=\"cursor:pointer\">\u76ee\u5f55<\/p>\n<span class=\"ez-toc-title-toggle\"><a href=\"#\" class=\"ez-toc-pull-right ez-toc-btn ez-toc-btn-xs ez-toc-btn-default ez-toc-toggle\" aria-label=\"Toggle Table of Content\"><span class=\"ez-toc-js-icon-con\"><span class=\"\"><span class=\"eztoc-hide\" style=\"display:none;\">Toggle<\/span><span class=\"ez-toc-icon-toggle-span\"><svg style=\"fill: #999;color:#999\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" class=\"list-377408\" width=\"20px\" height=\"20px\" viewBox=\"0 0 24 24\" fill=\"none\"><path d=\"M6 6H4v2h2V6zm14 0H8v2h12V6zM4 11h2v2H4v-2zm16 0H8v2h12v-2zM4 16h2v2H4v-2zm16 0H8v2h12v-2z\" fill=\"currentColor\"><\/path><\/svg><svg style=\"fill: #999;color:#999\" class=\"arrow-unsorted-368013\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" width=\"10px\" height=\"10px\" viewBox=\"0 0 24 24\" version=\"1.2\" baseProfile=\"tiny\"><path d=\"M18.2 9.3l-6.2-6.3-6.2 6.3c-.2.2-.3.4-.3.7s.1.5.3.7c.2.2.4.3.7.3h11c.3 0 .5-.1.7-.3.2-.2.3-.5.3-.7s-.1-.5-.3-.7zM5.8 14.7l6.2 6.3 6.2-6.3c.2-.2.3-.5.3-.7s-.1-.5-.3-.7c-.2-.2-.4-.3-.7-.3h-11c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.7s.1.5.3.7z\"\/><\/svg><\/span><\/span><\/span><\/a><\/span><\/div>\n<nav><ul class='ez-toc-list ez-toc-list-level-1 ' ><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-1\" href=\"https:\/\/blog.iyatt.com\/?p=12974\/#1_%E7%8E%AF%E5%A2%83\" >1 \u73af\u5883<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-2\" href=\"https:\/\/blog.iyatt.com\/?p=12974\/#2_SD_%E5%8D%A1%E4%BF%A1%E6%81%AF%E6%98%BE%E7%A4%BA\" >2 SD \u5361\u4fe1\u606f\u663e\u793a<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-3\" href=\"https:\/\/blog.iyatt.com\/?p=12974\/#3_SdFat_%E5%BA%93%E5%86%85%E7%BD%AE%E9%94%99%E8%AF%AF%E7%B1%BB%E5%9E%8B\" >3 SdFat \u5e93\u5185\u7f6e\u9519\u8bef\u7c7b\u578b<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-4\" href=\"https:\/\/blog.iyatt.com\/?p=12974\/#4_%E6%9F%A5%E7%9C%8B%E6%96%87%E4%BB%B6%E4%BF%A1%E6%81%AF\" >4 \u67e5\u770b\u6587\u4ef6\u4fe1\u606f<\/a><\/li><li class='ez-toc-page-1 ez-toc-heading-level-1'><a class=\"ez-toc-link ez-toc-heading-5\" href=\"https:\/\/blog.iyatt.com\/?p=12974\/#5_%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E8%AF%BB%E5%86%99\" >5 \u6587\u672c\u6587\u4ef6\u8bfb\u5199<\/a><\/li><\/ul><\/nav><\/div>\n<h1><span class=\"ez-toc-section\" id=\"1_%E7%8E%AF%E5%A2%83\"><\/span>1 \u73af\u5883<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<p>Arduino UNO<br \/>\nSD \u5361\u6a21\u5757<br \/>\n<img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705219911947.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 378px; --smush-placeholder-aspect-ratio: 378\/383;\" \/><br \/>\n<img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705624894191.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 244px; --smush-placeholder-aspect-ratio: 244\/162;\" \/><\/p>\n<p>Arduino IDE 2.2.1<br \/>\nSdFat 2.2.3\uff1a<a href=\"https:\/\/github.com\/adafruit\/SdFat\">https:\/\/github.com\/adafruit\/SdFat<\/a><\/p>\n<p>\u8fd9\u4e2a\u5e93\u652f\u6301 FAT16\/FAT32\/exFAT\uff08Arduino \u5b98\u65b9\u7684 SD \u5e93\u4e0d\u652f\u6301 exFAT\uff09\uff0cFAT16 \u6bd4\u8f83\u53e4\u8001\u4e86\uff0c\u5e94\u8be5\u662f\u5728\u5185\u5b58\u5361\u666e\u904d\u51e0\u767e\u5146\u5bb9\u91cf\u7684\u65f6\u5019\uff0c\u5bb9\u91cf\u5c0f\u4e8e 2G \u7684\u5361\u4e2d\u4f7f\u7528\uff0cFAT32 \u652f\u6301\u6700\u5927 128GB\uff0c\u5355\u6587\u4ef6\u6700\u59274G\uff0cWindows 11 \u4e0a\u5bb9\u91cf\u5927\u4e8e 32G \u7684\u50a8\u5b58\u8bbe\u5907\u5c31\u4e0d\u8ba9\u683c\u5f0f\u5316\u4e3a FAT32 \u4e86\uff0c\u4e00\u822c\u4f7f\u7528\u8303\u56f4\u5927\u81f4\u5c31\u5728 2~32 \u4e4b\u95f4\u7684\uff0c\u5927\u4e8e 32G \u7684\u57fa\u672c\u5c31\u662f\u7528 exFAT \u4e86\uff0c\u73b0\u5728\u7684\u5185\u5b58\u5361\u8fd8\u6ca1\u6709\u80fd\u8fbe\u5230 exFAT \u6587\u4ef6\u7cfb\u7edf\u4e0a\u9650\u7684\uff0c\u5355\u4e2a\u6587\u4ef6\u6700\u5927\u90fd\u652f\u6301 16EB\uff081EB=<code class=\"katex-inline\">10^9<\/code>GB\uff09\u3002\u6211\u8fd9\u91cc\u5c31\u7528\u4e00\u5f20\u4ee5\u524d\u4e70\u7684 64G \u7684\u95ea\u8fea\u5185\u5b58\u5361\u6d4b\u8bd5\u3002<\/p>\n<hr \/>\n<p>\u63a5\u7ebf\uff08SPI\uff09<\/p>\n<pre><code class=\"language-katex\">\\begin{array}{l l}\nArduino &amp; SD\u5361\u6a21\u5757 \\\\\n\\hline\nGND &amp; GND \\\\\n3v3 &amp; 3.3V \\\\\nMOSI &amp; 11 \\\\\nMISO &amp; 12 \\\\\nCLK &amp; 13 \\\\\nCS &amp; 4 \\\\\n\\end{array}<\/code><\/pre>\n<p>\u6ce8\uff1a<\/p>\n<ul>\n<li>\n<p>\u683c\u5f0f\u5316\u5185\u5b58\u5361\u5efa\u8bae\u4f7f\u7528 SD \u5361\u534f\u4f1a\u7684\u8f6f\u4ef6\uff1a<a href=\"https:\/\/www.sdcard.org\/downloads\/formatter\/sd-memory-card-formatter-for-windows-download\/\">https:\/\/www.sdcard.org\/downloads\/formatter\/sd-memory-card-formatter-for-windows-download\/<\/a><br \/>\n\u6211\u7528 Windows \u7684\u683c\u5f0f\u5316\uff0c\u5185\u5b58\u5361\u59cb\u7ec8\u65e0\u6cd5\u8bfb\u53d6\u6709\u6548\u7684 MBR\uff0c\u7528\u6807\u51c6\u7684\u683c\u5f0f\u5316\u8f6f\u4ef6\u5c31\u6ca1\u95ee\u9898\u3002<br \/>\n<img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705651622331.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 409px; --smush-placeholder-aspect-ratio: 409\/430;\" \/><\/p>\n<\/li>\n<li>\n<p>\u4e2d\u6587\u6587\u4ef6\u540d\u8bfb\u53d6\u51fa\u6765\u4f1a\u663e\u793a\u95ee\u53f7\uff0c\u4f46\u662f\u597d\u8fc7 SD \u5e93\uff0c\u81f3\u5c11\u4e0d\u4f1a\u6709\u4e2d\u6587\u540d\u5c31\u5d29\u6e83\uff0c\u4fdd\u8bc1\u8fd8\u80fd\u7528\u3002<\/p>\n<\/li>\n<\/ul>\n<h1><span class=\"ez-toc-section\" id=\"2_SD_%E5%8D%A1%E4%BF%A1%E6%81%AF%E6%98%BE%E7%A4%BA\"><\/span>2 SD \u5361\u4fe1\u606f\u663e\u793a<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<pre><code class=\"language-cpp\">#include &quot;SdFat.h&quot;\n#include &quot;sdios.h&quot;\n\nconst int8_t DISABLE_CS_PIN = -1;  \/\/ \u7981\u6b62\u5176\u5b83 CS \u5f15\u811a\uff0c\u6ca1\u6709\u5176\u5b83 SPI \u8bbe\u5907\u7f6e\u4e3a -1 \u5c31\u884c\nconst uint8_t SD_CS_PIN = 4; \/\/ \u5b9a\u4e49\u4f7f\u7528\u7684 CS \u5f15\u811a\n\n\/\/ \u63a5\u53e3\u7c7b\u578b\u9009\u62e9\n\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\/\n\n#define ENABLE_DEDICATED_SPI    1 \/\/ \u8fd9\u4e2a SD \u5361\u6a21\u5757\u662f SPI \u901a\u4fe1\u7684\uff0c\u8fd9\u91cc\u6ca1\u6709\u4f7f\u7528\u5176\u5b83 SPI \u8bbe\u5907\u5c31\u662f\u4e13\u7528\u7684\n\n\/\/ SPI \u65f6\u949f\u9891\u7387\u8bbe\u7f6e\n\/\/ \u5728\u9762\u5305\u677f\u63a5\u7ebf\u6d4b\u8bd5\u7b49\u73af\u5883\u4e2d\u5efa\u8bae\u8bbe\u7f6e 4\n\/\/ \u7ebf\u8def\u8f83\u957f\uff0c\u7ebf\u8def\u7684\u7535\u5bb9\u7535\u611f\u7b49\u90fd\u53ef\u80fd\u5bf9\u9ad8\u9891\u4fe1\u53f7\u4f20\u8f93\u4ea7\u751f\u5f71\u54cd\uff0c\u5bfc\u81f4\u6570\u636e\u4e0d\u5b8c\u6574\uff0c\u91c7\u7528\u8f83\u4f4e\u7684\u901f\u5ea6\u53ef\u4ee5\u66f4\u4e3a\u7a33\u5b9a\n\/\/ \u5728\u5b9e\u9645\u90e8\u7f72\u7684\u73af\u5883\u4e2d\uff0cSD \u5361\u8fde\u63a5\u7ebf\u8def\u8981\u5c3d\u53ef\u80fd\u7684\u77ed\uff0c\u7535\u6e90\u4f9b\u7535\u7b49\u4e5f\u8981\u4fdd\u8bc1\u7a33\u5b9a\uff0c\u53ef\u4ee5\u5c1d\u8bd5\u4e0d\u8d85\u8fc7 50 \u7684\u9891\u7387\u4ee5\u83b7\u5f97\u9ad8\u901f\u8bfb\u5199\n\/\/ \u53ef\u4ee5\u4ece\u8f83\u5927\u7684\u6570\u503c\u5f00\u59cb\u5c1d\u8bd5\uff0c\u9047\u5230\u62a5\u9519\u5c31\u51cf\u5c0f\nconst uint8_t sd_sck = 4; \/\/ MHz\n\n#if HAS_SDIO_CLASS \/\/ SDIO \u63a5\u53e3\n    #define SD_CONFIG SdioConfig(FIFO_SDIO)\n#elif ENABLE_DEDICATED_SPI\n    #define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(sd_sck)) \/\/ \u4e13\u7528 SPI \u63a5\u53e3\n#else\n    #define SD_CONFIG SdSpiConfig(SD_CS_PIN, SHARED_SPI, SD_SCK_MHZ(sd_sck)) \/\/ \u5171\u4eab\u7684 SPI \u63a5\u53e3\n#endif\n\n\/\/ \u5b58\u50a8\u5185\u5b58\u5361\u4fe1\u606f\nSdFs sd;\ncid_t cid;\ncsd_t csd;\nscr_t scr;\nuint8_t cmd6Data[64];\nuint32_t eraseSize;\nuint32_t ocr;\nstatic ArduinoOutStream cout(Serial);\n\n\/**\n * @brief \u663e\u793a\u5236\u9020\u5546\u4fe1\u606f\n *\/\nvoid cidDmp()\n{\n    cout &lt;&lt; F(&quot;\\n\u5236\u9020\u5546\u6807\u8bc6\uff1a&quot;);\n    cout &lt;&lt; uppercase &lt;&lt; showbase &lt;&lt; hex &lt;&lt; int(cid.mid) &lt;&lt; dec &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u539f\u59cb\u8bbe\u5907\u5236\u9020\u5546\u6807\u8bc6\uff1a&quot;) &lt;&lt; cid.oid[0] &lt;&lt; cid.oid[1] &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u4ea7\u54c1\uff1a&quot;);\n    for (uint8_t i = 0; i &lt; 5; i++)\n    {\n        cout &lt;&lt; cid.pnm[i];\n    }\n    cout &lt;&lt; F(&quot;\\n\u7248\u672c\uff1a&quot;) &lt;&lt; cid.prvN() &lt;&lt; &#039;.&#039; &lt;&lt; cid.prvM() &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u5e8f\u5217\u53f7\uff1a&quot;) &lt;&lt; hex &lt;&lt; cid.psn() &lt;&lt; dec &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u5236\u9020\u65e5\u671f\uff1a&quot;);\n    cout &lt;&lt; cid.mdtMonth() &lt;&lt; &#039;\/&#039; &lt;&lt; cid.mdtYear() &lt;&lt; endl;\n    cout &lt;&lt; endl;\n}\n\n\/**\n * @brief \u6e05\u9664\u4e32\u53e3\u7f13\u51b2\u533a\u4e2d\u7684\u6570\u636e\n *\/\nvoid clearSerialInput()\n{\n    uint32_t m = micros();\n    do\n    {\n        if (Serial.read() &gt;= 0)\n        {\n            m = micros();\n        }\n    } while (micros() - m &lt; 10000);\n}\n\n\/**\n * @brief \u663e\u793a\u5361\u7684\u5bb9\u91cf\u548c\u64e6\u9664\u4fe1\u606f\n *\/\nvoid csdDmp()\n{\n    eraseSize = csd.eraseSize();\n    cout &lt;&lt; F(&quot;\u5bb9\u91cf\uff1a&quot;) &lt;&lt; 0.000512 * csd.capacity();\n    cout &lt;&lt; F(&quot; MB (MB = 1,000,000 bytes)\\n&quot;);\n\n    cout &lt;&lt; F(&quot;\u64e6\u9664\u5757\u5927\u5c0f\uff1a&quot;) &lt;&lt; int(eraseSize) &lt;&lt; F(&quot; blocks\\n&quot;);\n    cout &lt;&lt; F(&quot;\u5355\u5757\u64e6\u9664\u652f\u6301\uff1a&quot;);\n    if (csd.eraseSingleBlock())\n    {\n        cout &lt;&lt; F(&quot;true\\n&quot;);\n    }\n    else\n    {\n        cout &lt;&lt; F(&quot;false\\n&quot;);\n    }\n    cout &lt;&lt; F(&quot;\u64e6\u9664\u540e\u6570\u636e\u72b6\u6001\uff1a&quot;);\n    if (scr.dataAfterErase())\n    {\n        cout &lt;&lt; F(&quot;111...\\n&quot;);\n    }\n    else\n    {\n        cout &lt;&lt; F(&quot;000...\\n&quot;);\n    }\n}\n\n\/**\n * @brief \u663e\u793a\u9519\u8bef\u4ee3\u7801\u548c\u9519\u8bef\u6570\u636e\n *\/\nvoid errorPrint()\n{\n    if (sd.sdErrorCode())\n    {\n        cout &lt;&lt; F(&quot;SD \u9519\u8bef\u4ee3\u7801\uff1a&quot;) &lt;&lt; hex &lt;&lt; showbase;\n        printSdErrorSymbol(&amp;Serial, sd.sdErrorCode());\n        cout &lt;&lt; F(&quot; = &quot;) &lt;&lt; int(sd.sdErrorCode()) &lt;&lt; endl;\n        cout &lt;&lt; F(&quot;SD \u9519\u8bef\u6570\u636e\uff1a&quot;) &lt;&lt; int(sd.sdErrorData()) &lt;&lt; dec &lt;&lt; endl;\n    }\n}\n\n\/**\n * @brief \u663e\u793a\u4e3b\u5f15\u5bfc\u8bb0\u5f55\uff08MBR\uff09\n *\/\nbool mbrDmp()\n{\n    MbrSector_t mbr; \/\/ \u7528\u4e8e\u5b58\u50a8 MBR \u6570\u636e\n    bool valid = true; \/\/ MBR \u6709\u6548\u6027\u8bb0\u5f55\n    if (!sd.card()-&gt;readSector(0, (uint8_t *)&amp;mbr)) \/\/ \u8bfb\u53d6\u6247\u533a 0 \u7684\u6570\u636e\n    {\n        cout &lt;&lt; F(&quot;\\n\u8bfb\u53d6 MBR \u5931\u8d25\u3002\\n&quot;);\n        errorPrint();\n        return false;\n    }\n    cout &lt;&lt; F(&quot;\\nSD \u5206\u533a\u8868\uff1a\\n&quot;);\n    cout &lt;&lt; F(&quot;\u5206\u533a\u7f16\u53f7,\u5f15\u5bfc\u6807\u5fd7,\u8d77\u59cb\u67f1\u9762\/\u78c1\u5934\/\u6247\u533a\uff08CHS\uff09,\u5206\u533a\u7c7b\u578b,\u7ed3\u675f CHS \u503c,\u76f8\u5bf9\u6247\u533a\u6570,\u603b\u6247\u533a\u6570\\n&quot;);\n    for (uint8_t ip = 1; ip &lt; 5; ip++) \/\/ \u904d\u5386\u5206\u533a\u8868\u4e2d\u7684 4 \u4e2a\u5206\u533a\n    {\n        MbrPart_t *pt = &amp;mbr.part[ip - 1];\n        if ((pt-&gt;boot != 0 &amp;&amp; pt-&gt;boot != 0X80) || getLe32(pt-&gt;relativeSectors) &gt; csd.capacity())\n        {\n            valid = false;\n        }\n        cout &lt;&lt; int(ip) &lt;&lt; &#039;,&#039; &lt;&lt; uppercase &lt;&lt; showbase &lt;&lt; hex;\n        cout &lt;&lt; int(pt-&gt;boot) &lt;&lt; &#039;,&#039;;\n        for (int i = 0; i &lt; 3; i++)\n        {\n            cout &lt;&lt; int(pt-&gt;beginCHS[i]) &lt;&lt; &#039;,&#039;;\n        }\n        cout &lt;&lt; int(pt-&gt;type) &lt;&lt; &#039;,&#039;;\n        for (int i = 0; i &lt; 3; i++)\n        {\n            cout &lt;&lt; int(pt-&gt;endCHS[i]) &lt;&lt; &#039;,&#039;;\n        }\n        cout &lt;&lt; dec &lt;&lt; getLe32(pt-&gt;relativeSectors) &lt;&lt; &#039;,&#039;;\n        cout &lt;&lt; getLe32(pt-&gt;totalSectors) &lt;&lt; endl;\n    }\n    if (!valid)\n    {\n        cout &lt;&lt; F(&quot;\\nMBR\u65e0\u6548\uff0c\u5047\u5b9a\u4e3a\u8d85\u7ea7\u8f6f\u76d8\u683c\u5f0f\u3002\\n&quot;);\n    }\n    return true;\n}\n\nvoid dmpVol()\n{\n    cout &lt;&lt; F(&quot;\\n\u626b\u63cf\u6587\u4ef6\u7cfb\u7edf\u4e2d\uff0c\u8bf7\u7b49\u5f85\u3002\\n&quot;);\n    int32_t freeClusterCount = sd.freeClusterCount(); \/\/ \u83b7\u53d6\u5269\u4f59\u7c07\u6570\u91cf\n    if (sd.fatType() &lt;= 32)\n    {\n        cout &lt;&lt; F(&quot;\\n\u5377\u662f FAT&quot;) &lt;&lt; int(sd.fatType()) &lt;&lt; endl;\n    } else {\n    cout &lt;&lt; F(&quot;\\n\u5377\u662f exFAT\\n&quot;);\n    }\n    cout &lt;&lt; F(&quot;\u6247\u533a\u6570\u91cf\uff1a&quot;) &lt;&lt; sd.sectorsPerCluster() &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u8d77\u59cb\u6247\u533a\u4f4d\u7f6e\uff1a&quot;) &lt;&lt; sd.fatStartSector() &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u6570\u636e\u533a\u8d77\u59cb\u6247\u533a\u4f4d\u7f6e\uff1a&quot;) &lt;&lt; sd.dataStartSector() &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u7c07\u603b\u6570\uff1a&quot;) &lt;&lt; sd.clusterCount() &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u5269\u4f59\u7c07\u6570\u91cf\uff1a&quot;);\n    if (freeClusterCount &gt;= 0)\n    {\n        cout &lt;&lt; freeClusterCount &lt;&lt; endl;\n    }\n    else\n    {\n        cout &lt;&lt; F(&quot;\u5931\u8d25\uff01\\n&quot;);\n        errorPrint();\n    }\n}\n\n\/**\n * @brief \u663e\u793a\u5185\u5b58\u5361\u7c7b\u578b\n *\/\nvoid printCardType()\n{\n    cout &lt;&lt; F(&quot;\\n\u5185\u5b58\u5361\u7c7b\u578b\uff1a&quot;);\n\n    switch (sd.card()-&gt;type())\n    {\n        case SD_CARD_TYPE_SD1:\n        {\n            cout &lt;&lt; F(&quot;SD1\\n&quot;); \/\/ 1MB~2GB\n            break;\n        }\n        case SD_CARD_TYPE_SD2:\n        {\n            cout &lt;&lt; F(&quot;SD2\\n&quot;); \/\/ ~4GB\n            break;\n        }\n        case SD_CARD_TYPE_SDHC:\n        {\n            if (csd.capacity() &lt; 70000000)\n            {\n                cout &lt;&lt; F(&quot;SDHC\\n&quot;); \/\/ 4~32GB\n            }\n            else\n            {\n                cout &lt;&lt; F(&quot;SDXC\\n&quot;); \/\/ 32G~2TB\n            }\n            break;\n        }\n        default:\n        { \n            cout &lt;&lt; F(&quot;\u672a\u77e5\\n&quot;);\n        }\n    }\n}\n\n\/**\n * \u663e\u793a\u914d\u7f6e\u4fe1\u606f\n *\/\nvoid printConfig(SdSpiConfig config)\n{\n    if (DISABLE_CS_PIN &lt; 0)\n    {\n        cout &lt;&lt; F(\n            &quot;\\n\u5047\u8bbe SD \u5361\u662f\u552f\u4e00\u7684 SPI \u8bbe\u5907\\n&quot;\n            &quot;\u7f16\u8f91DISABLE_CS_PIN\u4ee5\u7981\u7528\u5176\u5b83SPI\u8bbe\u5907\u3002\\n&quot;);\n    }\n    else\n    {\n        cout &lt;&lt; F(&quot;\\n\u7981\u7528\u5f15\u811a\u4e0a\u7684SPI\u8bbe\u5907\uff1a&quot;);\n        cout &lt;&lt; int(DISABLE_CS_PIN) &lt;&lt; endl;\n        pinMode(DISABLE_CS_PIN, OUTPUT);\n        digitalWrite(DISABLE_CS_PIN, HIGH);\n    }\n    cout &lt;&lt; F(&quot;\\n\u5047\u8bbe SD \u5361\u7684 CS \u5f15\u811a\u662f\uff1a&quot;) &lt;&lt; int(config.csPin);\n    cout &lt;&lt; F(&quot;\\n\u7f16\u8f91SD_CS_PIN\u4fee\u6539\u7247\u9009\u5f15\u811a\u3002\\n&quot;);\n}\n\nvoid printConfig(SdioConfig config)\n{\n  (void)config;\n  cout &lt;&lt; F(&quot;\u5047\u8bbe\u6b63\u5728\u4f7f\u7528 SDIO \u63a5\u53e3\u3002\\n&quot;);\n}\n\nvoid setup()\n{\n    Serial.begin(9600);\n    while (!Serial) \/\/ \u7b49\u5f85 USB \u4e32\u53e3\n    {\n        yield();\n    }\n    cout &lt;&lt; F(&quot;SdFat \u7248\u672c\uff1a&quot;) &lt;&lt; SD_FAT_VERSION_STR &lt;&lt; endl;\n    printConfig(SD_CONFIG);\n}\n\nvoid loop()\n{\n    clearSerialInput();\n\n    cout &lt;&lt; F(&quot;\\n\u8f93\u5165\u4efb\u610f\u5b57\u7b26\u7ee7\u7eed\\n&quot;);\n    while (!Serial.available())\n    {\n        yield();\n    }\n    uint32_t t = millis();\n    if (!sd.cardBegin(SD_CONFIG))\n    {\n        cout &lt;&lt; F(\n            &quot;\\nSD \u521d\u59cb\u5316\u5931\u8d25\u3002\\n&quot;\n            &quot;\u4e0d\u8981\u91cd\u65b0\u683c\u5f0f\u5316\u5185\u5b58\u5361\uff01\\n&quot;\n            &quot;\u5185\u5b58\u5361\u662f\u5426\u6b63\u786e\u63d2\u5165\uff1f\\n&quot;\n            &quot;\u662f\u5426\u5b58\u5728\u63a5\u7ebf\u9519\u8bef\u6216\u8005\u63a5\u89e6\u4e0d\u826f\u7684\u95ee\u9898\uff1f\\n&quot;);\n        if (isSpi(SD_CONFIG))\n        {\n            cout &lt;&lt; F(\n            &quot;SD_CS_PIN \u662f\u5426\u8bbe\u7f6e\u4e86\u6b63\u786e\u7684\u503c\uff1f\\n&quot;\n            &quot;\u662f\u5426\u9700\u8981\u7981\u7528\u5176\u5b83 SPI \u8bbe\u5907\uff1f\\n&quot;);\n        }\n        errorPrint();\n        return;\n    }\n    t = millis() - t;\n    cout &lt;&lt; F(&quot;\u521d\u59cb\u5316\u7528\u65f6\uff1a&quot;) &lt;&lt; dec &lt;&lt; t &lt;&lt; &quot; ms&quot; &lt;&lt; endl;\n\n    if (!sd.card()-&gt;readCID(&amp;cid) || !sd.card()-&gt;readCSD(&amp;csd) || !sd.card()-&gt;readOCR(&amp;ocr) || !sd.card()-&gt;readSCR(&amp;scr))\n    {\n        cout &lt;&lt; F(&quot;\u8bfb\u53d6\u4fe1\u606f\u5931\u8d25!\\n&quot;);\n        errorPrint();\n        return;\n    }\n    printCardType();\n    cout &lt;&lt; F(&quot;\u5185\u5b58\u5361\u89c4\u8303\u7248\u672c\uff1a&quot;) &lt;&lt; 0.01 * scr.sdSpecVer() &lt;&lt; endl;\n    cout &lt;&lt; F(&quot;\u9ad8\u6570\u6a21\u5f0f\uff1a&quot;);\n    if (scr.sdSpecVer() &amp;&amp; sd.card()-&gt;cardCMD6(0X00FFFFFF, cmd6Data) &amp;&amp; (2 &amp; cmd6Data[13]))\n    {\n        cout &lt;&lt; F(&quot;true\\n&quot;);\n    } else {\n        cout &lt;&lt; F(&quot;false\\n&quot;);\n    }\n    cidDmp();\n    csdDmp();\n    cout &lt;&lt; F(&quot;\\n\u5bc4\u5b58\u5668\u503c\uff1a&quot;) &lt;&lt; uppercase &lt;&lt; showbase;\n    cout &lt;&lt; hex &lt;&lt; ocr &lt;&lt; dec &lt;&lt; endl;\n    if (!mbrDmp())\n    {\n        return;\n    }\n    if (!sd.volumeBegin())\n    {\n        cout &lt;&lt; F(&quot;\\n\u5377\u521d\u59cb\u5316\u5931\u8d25\uff0c\u5185\u5b58\u5361\u662f\u5426\u683c\u5f0f\u5316\u4e86\uff1f\\n&quot;);\n        errorPrint();\n        return;\n    }\n    dmpVol();\n}<\/code><\/pre>\n<p><img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705641860603.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 275px; --smush-placeholder-aspect-ratio: 275\/224;\" \/><br \/>\n<img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705641880931.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 402px; --smush-placeholder-aspect-ratio: 402\/75;\" \/><br \/>\n<img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705641896625.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 300px; --smush-placeholder-aspect-ratio: 300\/147;\" \/><\/p>\n<h1><span class=\"ez-toc-section\" id=\"3_SdFat_%E5%BA%93%E5%86%85%E7%BD%AE%E9%94%99%E8%AF%AF%E7%B1%BB%E5%9E%8B\"><\/span>3 SdFat \u5e93\u5185\u7f6e\u9519\u8bef\u7c7b\u578b<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<pre><code class=\"language-cpp\">#include &quot;SdFat.h&quot;\n\nvoid setup()\n{\n    Serial.begin(9600);\n    while (!Serial)\n    {\n        yield();\n    }\n    Serial.println();\n    Serial.println(F(&quot;\u4ee3\u7801\uff0c\u7b26\u53f7 - \u9519\u8bef\u64cd\u4f5c&quot;));\n    for (uint8_t code = 0; code &lt;= SD_CARD_ERROR_UNKNOWN; code++)\n    {\n        Serial.print(code &lt; 16 ? &quot;0X0&quot; : &quot;0X&quot;);\n        Serial.print(code, HEX);\n        Serial.print(&quot;,&quot;);\n        printSdErrorSymbol(&amp;Serial, code);\n        Serial.print(&quot; - &quot;);\n        printSdErrorText(&amp;Serial, code);\n        Serial.println();\n    }\n}\nvoid loop()\n{\n\n}<\/code><\/pre>\n<p><img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705648552255.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 433px; --smush-placeholder-aspect-ratio: 433\/563;\" \/><br \/>\n<img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705648574558.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 495px; --smush-placeholder-aspect-ratio: 495\/290;\" \/><\/p>\n<h1><span class=\"ez-toc-section\" id=\"4_%E6%9F%A5%E7%9C%8B%E6%96%87%E4%BB%B6%E4%BF%A1%E6%81%AF\"><\/span>4 \u67e5\u770b\u6587\u4ef6\u4fe1\u606f<span class=\"ez-toc-section-end\"><\/span><\/h1>\n<pre><code class=\"language-cpp\">#include &quot;SdFat.h&quot;\n\n\/\/ 1 FAT16\/FAT32\n\/\/ 2 exFAT\n\/\/ 3 FAT16\/FAT32 and exFAT\n#define SD_FAT_TYPE 3\n\n#if SD_FAT_TYPE == 0\n    SdFat sd;\n    File dir;\n    File file;\n#elif SD_FAT_TYPE == 1\n    SdFat32 sd;\n    File32 dir;\n    File32 file;\n#elif SD_FAT_TYPE == 2\n    SdExFat sd;\n    ExFile dir;\n    ExFile file;\n#elif SD_FAT_TYPE == 3 \/\/ \u540c\u65f6\u652f\u6301 FAT16\/FAT32\/exFAT \u6587\u4ef6\u7cfb\u7edf\u7684\u7c7b\n    SdFs sd;\n    FsFile dir;\n    FsFile file;\n#else\n    #error invalid SD_FAT_TYPE\n#endif\n\nconst uint8_t SD_CS_PIN = 4; \/\/ CS \u5f15\u811a\n#define SD_CONFIG SdSpiConfig(SD_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(4)) \/\/ SPI \u4e13\u7528 4MHz\n\n#define error(s) sd.errorHalt(&amp;Serial, F(s))\n\nvoid setup()\n{\n    Serial.begin(9600);\n\n    while (!Serial)\n    {\n        yield();\n    }\n\n    Serial.println(&quot;\u8f93\u5165\u4efb\u610f\u5b57\u7b26\u5f00\u59cb&quot;);\n    while (!Serial.available())\n    {\n        yield();\n    }\n\n    \/\/ \u521d\u59cb\u5316\n    if (!sd.begin(SD_CONFIG))\n    {\n        sd.initErrorHalt(&amp;Serial);\n    }\n\n    \/\/ \u6253\u5f00\u6839\u76ee\u5f55\n    if (!dir.open(&quot;\/&quot;))\n    {\n        error(&quot;\u6839\u76ee\u5f55\u6253\u5f00\u5931\u8d25\uff01&quot;);\n    }\n    \/\/ \u6253\u5f00\u6839\u76ee\u5f55\u4e0b\u7684\u6587\u4ef6\uff08\u904d\u5386\uff09\n    while (file.openNext(&amp;dir, O_RDONLY))\n    {\n        file.printFileSize(&amp;Serial); \/\/ \u6587\u4ef6\u5927\u5c0f\n        Serial.write(&#039; &#039;);\n        file.printModifyDateTime(&amp;Serial); \/\/ \u6587\u4ef6\u4fee\u6539\u65f6\u95f4\n        Serial.write(&#039; &#039;);\n        file.printName(&amp;Serial); \/\/ \u6587\u4ef6\u540d\n        if (file.isDir()) \/\/ \u5982\u679c\u662f\u4e00\u4e2a\u76ee\u5f55\u6587\u4ef6(\u6587\u4ef6\u5939)\uff0c\u5219\u5728\u540e\u9762\u663e\u793a\u201c\/\u201d\n        {\n            Serial.write(&#039;\/&#039;);\n        }\n        Serial.println();\n        file.close(); \/\/ \u5173\u95ed\u6587\u4ef6\n    }\n    if (dir.getError())\n    {\n        Serial.println(&quot;openNext \u6253\u5f00\u5931\u8d25\uff01&quot;);\n    } else {\n    Serial.println(&quot;\u5b8c\u6210\uff01&quot;);\n    }\n}\n\nvoid loop()\n{\n\n}<\/code><\/pre>\n<p><img decoding=\"async\" data-src=\"https:\/\/blog.iyatt.com\/wp-content\/uploads\/2024\/01\/image-1705656393663.png\" alt=\"file\" src=\"data:image\/svg+xml;base64,PHN2ZyB3aWR0aD0iMSIgaGVpZ2h0PSIxIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjwvc3ZnPg==\" class=\"lazyload\" style=\"--smush-placeholder-width: 524px; --smush-placeholder-aspect-ratio: 524\/95;\" \/><\/p>\n<h1><span class=\"ez-toc-section\" id=\"5_%E6%96%87%E6%9C%AC%E6%96%87%E4%BB%B6%E8%AF%BB%E5%86%99\"><\/span>5 \u6587\u672c\u6587\u4ef6\u8bfb\u5199<span class=\"ez-toc-section-end\"><\/span><\/h1>\n","protected":false},"excerpt":{"rendered":"<p>1 \u73af\u5883 Arduino UNO SD \u5361\u6a21\u5757 Arduino IDE 2.2.1 SdFat 2.2.3\uff1ah [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"zakra_page_container_layout":"customizer","zakra_page_sidebar_layout":"customizer","zakra_remove_content_margin":false,"zakra_sidebar":"customizer","zakra_transparent_header":"customizer","zakra_logo":0,"zakra_main_header_style":"default","zakra_menu_item_color":"","zakra_menu_item_hover_color":"","zakra_menu_item_active_color":"","zakra_menu_active_style":"","zakra_page_header":true,"_lmt_disableupdate":"no","_lmt_disable":"no","footnotes":""},"categories":[1],"tags":[],"class_list":["post-12974","post","type-post","status-publish","format-standard","hentry","category-all"],"modified_by":"IYATT-yx","_links":{"self":[{"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=\/wp\/v2\/posts\/12974","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12974"}],"version-history":[{"count":0,"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=\/wp\/v2\/posts\/12974\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12974"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12974"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.iyatt.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12974"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}