<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>帆登小站</title><link>https://blog.simgor.cn/</link><description>Recent content on 帆登小站</description><generator>Hugo</generator><language>zh-cn</language><lastBuildDate>Mon, 01 Sep 2025 08:24:02 +0800</lastBuildDate><atom:link href="https://blog.simgor.cn/index.xml" rel="self" type="application/rss+xml"/><item><title>1.中断简介</title><link>https://blog.simgor.cn/blog/1.%E4%B8%AD%E6%96%AD%E7%AE%80%E4%BB%8B/</link><pubDate>Fri, 04 Jul 2025 16:23:36 +0800</pubDate><guid>https://blog.simgor.cn/blog/1.%E4%B8%AD%E6%96%AD%E7%AE%80%E4%BB%8B/</guid><description>&lt;p>51单片机里面有5个中断源：&lt;/p>
&lt;ul>
&lt;li>两个外部中断&lt;/li>
&lt;li>两个定时器中断&lt;/li>
&lt;li>一个串口中断&lt;/li>
&lt;/ul>
&lt;h2 id="中断类型">中断类型 &lt;a href="#%e4%b8%ad%e6%96%ad%e7%b1%bb%e5%9e%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>中断源名称&lt;/th>
 &lt;th>类型号&lt;/th>
 &lt;th>默认优先级&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>外部中断0&lt;/td>
 &lt;td>0&lt;/td>
 &lt;td>最高&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>定时/计数器T0&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>第2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>外部中断1&lt;/td>
 &lt;td>2&lt;/td>
 &lt;td>第3&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>定时/计数器T1&lt;/td>
 &lt;td>3&lt;/td>
 &lt;td>第4&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>串口中断&lt;/td>
 &lt;td>4&lt;/td>
 &lt;td>第5&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h2 id="ie寄存器">IE寄存器 &lt;a href="#ie%e5%af%84%e5%ad%98%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>中断控制寄存器&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>位序&lt;/th>
 &lt;th>D7&lt;/th>
 &lt;th>D6&lt;/th>
 &lt;th>D5&lt;/th>
 &lt;th>D4&lt;/th>
 &lt;th>D3&lt;/th>
 &lt;th>D2&lt;/th>
 &lt;th>D1&lt;/th>
 &lt;th>D0&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>位名&lt;/td>
 &lt;td>EA&lt;/td>
 &lt;td>&amp;ndash;&lt;/td>
 &lt;td>&amp;ndash;&lt;/td>
 &lt;td>ES&lt;/td>
 &lt;td>ET1&lt;/td>
 &lt;td>EX1&lt;/td>
 &lt;td>ET0&lt;/td>
 &lt;td>EX0&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;ul>
&lt;li>EA位：全局中断允许控制位，EA = 0时，禁止所有中断&lt;/li>
&lt;li>ES位：串口接收中断使能&lt;/li>
&lt;li>EX位：外部中断允许位，EX = 0时，禁止外部中断&lt;/li>
&lt;li>ET位：定时/计数允许位，ET = 0时，禁止定时/计数器中断&lt;/li>
&lt;/ul>
&lt;h2 id="ip寄存器">IP寄存器 &lt;a href="#ip%e5%af%84%e5%ad%98%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>中断优先级寄存器&lt;/p>
&lt;h2 id="tcon寄存器">TCON寄存器 &lt;a href="#tcon%e5%af%84%e5%ad%98%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>主要用于控制定时/计数器、中断的启动与停止、标示定时器的溢出和中断的情况。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>位序&lt;/th>
 &lt;th>D7&lt;/th>
 &lt;th>D6&lt;/th>
 &lt;th>D5&lt;/th>
 &lt;th>D4&lt;/th>
 &lt;th>D3&lt;/th>
 &lt;th>D2&lt;/th>
 &lt;th>D1&lt;/th>
 &lt;th>D0&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>位名&lt;/td>
 &lt;td>TF1&lt;/td>
 &lt;td>TR1&lt;/td>
 &lt;td>TF0&lt;/td>
 &lt;td>TR0&lt;/td>
 &lt;td>IE1&lt;/td>
 &lt;td>IT1&lt;/td>
 &lt;td>IE0&lt;/td>
 &lt;td>IT0&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="tf位">TF位 &lt;a href="#tf%e4%bd%8d" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;p>定时/计数器溢出中断位，这个位一般不需要人为操作。当定时/计数器溢出时，硬件自动将这个位置1，并向CPU发出中断指令，CPU进入中断服务程序的时候，自动清除该位。&lt;/p></description></item><item><title>1.初始化SD卡</title><link>https://blog.simgor.cn/blog/1.%E5%88%9D%E5%A7%8B%E5%8C%96sd%E5%8D%A1/</link><pubDate>Thu, 03 Jul 2025 22:39:49 +0800</pubDate><guid>https://blog.simgor.cn/blog/1.%E5%88%9D%E5%A7%8B%E5%8C%96sd%E5%8D%A1/</guid><description>&lt;p>作者是初学者，水平有限，本文仅作为个人学习笔记使用，不能保证内容的正确性。部分资料来源于网络，参考了SD卡协议2.0手册等资料，如果有歧义，可以与作者联系。&lt;/p>
&lt;h1 id="省流直接看图文章下面有比较详细的初始化流程">省流直接看图，文章下面有比较详细的初始化流程 &lt;a href="#%e7%9c%81%e6%b5%81%e7%9b%b4%e6%8e%a5%e7%9c%8b%e5%9b%be%e6%96%87%e7%ab%a0%e4%b8%8b%e9%9d%a2%e6%9c%89%e6%af%94%e8%be%83%e8%af%a6%e7%bb%86%e7%9a%84%e5%88%9d%e5%a7%8b%e5%8c%96%e6%b5%81%e7%a8%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>







 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/01/1052810562.png" alt="Pasted image 20230128214632.png" loading="lazy">
 

&lt;/p>
&lt;h1 id="常见问题">常见问题 &lt;a href="#%e5%b8%b8%e8%a7%81%e9%97%ae%e9%a2%98" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;h2 id="q1-为什么发送初始化命令之后sd卡一直返回0xff">Q1、 为什么发送初始化命令之后，SD卡一直返回0xFF？ &lt;a href="#q1-%e4%b8%ba%e4%bb%80%e4%b9%88%e5%8f%91%e9%80%81%e5%88%9d%e5%a7%8b%e5%8c%96%e5%91%bd%e4%bb%a4%e4%b9%8b%e5%90%8esd%e5%8d%a1%e4%b8%80%e7%9b%b4%e8%bf%94%e5%9b%9e0xff" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>作者亲自遇到过这个问题，我的工具是某宝上十几块钱的逻辑分析仪，芯片是CH32V203C8T6，开发板长这样子的








 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/02/4080687956.png" alt="Pasted image 20230203214636.png" loading="lazy">
 

&lt;/p>
&lt;p>首先检查线路的连接，MCU的MISO连接SD卡的DO，MOSI连接SD卡的DI，如果MCU有多个SPI外设，一定要看清楚SD卡连接的是哪个SPI。
最有效的方法，就是用逻辑分析仪连接到SD卡所连接的线路上，看有没有信号输出。
确定线路连接正常之后，再检查上电需要的时钟信号是否正确，必须在100k~400kHz的频率之间，如果你的MCU主频设置过高，如144MHz，就算SPI用256级的分频，依然是非常大的。144MHz分频256次：&lt;/p>
&lt;p>$$
\frac{MCU主频}{SPI分频数}=\frac{144MHz}{256}=562.5Kbit/s
$$&lt;/p>
&lt;p>所以在合适的主频下，选择合适的SPI分频数。初始化完成之后，再调高SPI的主频，用于数据通信。
最后一个办法，可以检查初始化步骤是否在上电时操作。
有些开发板上的SD卡槽的电源，是直接连接开发板电源，所以要求SD卡初始化的操作必须在开发板刚上电时完成。但是调试时，一般只会让MCU复位而不会让开发板断电，从而SD卡无法进入初始化模式。
在这种情况下，我建议每次下载完程序之后，让开发板重新上电，或者先购买一个SD卡模块，让GPIO控制SD卡的上电，直到写完初始化部分的功能，代码能正常初始化SD卡之后，再换回开发板的卡槽。&lt;/p>
&lt;h2 id="q2关于tf卡">Q2、关于TF卡 &lt;a href="#q2%e5%85%b3%e4%ba%8etf%e5%8d%a1" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>有些TF卡不支持SPI模式操作，这个需要注意，可以多准备几张卡。目前我的8G金士顿TF卡，这个没问题，但是我的32G闪迪没法进入SPI模式。&lt;/p>
&lt;h2 id="q3-mcu应该在什么时候发送命令">Q3、 MCU应该在什么时候发送命令？ &lt;a href="#q3-mcu%e5%ba%94%e8%af%a5%e5%9c%a8%e4%bb%80%e4%b9%88%e6%97%b6%e5%80%99%e5%8f%91%e9%80%81%e5%91%bd%e4%bb%a4" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>SD卡的DO线，空闲的情况下应该是高电平，当SD卡忙的时候，DO线会被SD卡拉低，所以应该在DO线为高电平的时候，发送命令。&lt;/p>
&lt;h1 id="简介">简介 &lt;a href="#%e7%ae%80%e4%bb%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>SPI模式是MCU在没有SDIO的情况下控制MMC和SD卡的备用操作模式。比起SDIO模式，SPI模式的传输协议稍微简单一些，代价是传输速度也会变慢。&lt;/p>
&lt;h1 id="引脚说明">引脚说明 &lt;a href="#%e5%bc%95%e8%84%9a%e8%af%b4%e6%98%8e" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>







 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/01/1515819948.png" alt="Pasted image 20230118202918.png" loading="lazy">
 










 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/01/3533747864.png" alt="Pasted image 20230118202939.png" loading="lazy">
 


（图片来源于网络）&lt;/p>
&lt;h1 id="引脚设置">引脚设置 &lt;a href="#%e5%bc%95%e8%84%9a%e8%ae%be%e7%bd%ae" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>在SPI模式下使用SD卡，按照SD卡的要求正确接线之后，需要将MCU的引脚进行如下设置：&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>SD引脚&lt;/th>
 &lt;th>MCU引脚&lt;/th>
 &lt;th>MCU引脚模式&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>CS&lt;/td>
 &lt;td>NSS&lt;/td>
 &lt;td>复用推挽输出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>SCLK&lt;/td>
 &lt;td>SCK&lt;/td>
 &lt;td>复用推挽输出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DI&lt;/td>
 &lt;td>MOSI&lt;/td>
 &lt;td>复用推挽输出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>DO&lt;/td>
 &lt;td>MISO&lt;/td>
 &lt;td>浮空输入&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>VDD&lt;/td>
 &lt;td>(任意引脚)&lt;/td>
 &lt;td>复用推挽输出&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>VSS&lt;/td>
 &lt;td>GND&lt;/td>
 &lt;td>&amp;ndash;&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>其中，SD卡的VDD可以使用一个引脚去控制SD卡的电源，从而使用MCU控制SD卡上电。
注意，有些SD卡的DO引脚需要一个上拉电阻，否则会在初始化的过程中失败。&lt;/p>
&lt;h1 id="spi模式设置">SPI模式设置 &lt;a href="#spi%e6%a8%a1%e5%bc%8f%e8%ae%be%e7%bd%ae" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>SD卡使用的是SPI模式0（CPHA=0，CPOL=0）和SPI模式3（CPHA=1，CPOL=1），一般情况下选择SPI模式3。命令发送模式为高位优先（MSB-first）。&lt;/p></description></item><item><title>2.串口介绍</title><link>https://blog.simgor.cn/blog/2.%E4%B8%B2%E5%8F%A3%E4%BB%8B%E7%BB%8D/</link><pubDate>Fri, 04 Jul 2025 16:23:39 +0800</pubDate><guid>https://blog.simgor.cn/blog/2.%E4%B8%B2%E5%8F%A3%E4%BB%8B%E7%BB%8D/</guid><description>&lt;h1 id="串口操作流程">串口操作流程 &lt;a href="#%e4%b8%b2%e5%8f%a3%e6%93%8d%e4%bd%9c%e6%b5%81%e7%a8%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;ol>
&lt;li>配置串口工作方式&lt;/li>
&lt;li>配置用于串口的定时器T1为工作方式2&lt;/li>
&lt;li>设置波特率&lt;/li>
&lt;li>使能总中断、串口中断&lt;/li>
&lt;li>设置接收中断函数&lt;/li>
&lt;li>设置stdio库&lt;/li>
&lt;/ol>
&lt;h1 id="串口寄存器">串口寄存器 &lt;a href="#%e4%b8%b2%e5%8f%a3%e5%af%84%e5%ad%98%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>与串口有关的寄存器有以下几个：&lt;/p>
&lt;ul>
&lt;li>SUBF：数据缓冲器&lt;/li>
&lt;li>SCON：串行口控制寄存器&lt;/li>
&lt;li>PCON寄存器&lt;/li>
&lt;/ul>
&lt;h2 id="subf数据缓冲器">SUBF：数据缓冲器 &lt;a href="#subf%e6%95%b0%e6%8d%ae%e7%bc%93%e5%86%b2%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>有两个，用于接收/发送数据。
需要注意的是，该两个缓冲器地址一致，可以当作普通寄存器看待。&lt;/p>
&lt;h2 id="scon寄存器">SCON寄存器 &lt;a href="#scon%e5%af%84%e5%ad%98%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;p>串行口控制寄存器
用于设置串行口的工作方式、监视串行口的工作状态、控制发送与接收的状态等。&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>位序&lt;/th>
 &lt;th>D7&lt;/th>
 &lt;th>D6&lt;/th>
 &lt;th>D5&lt;/th>
 &lt;th>D4&lt;/th>
 &lt;th>D3&lt;/th>
 &lt;th>D2&lt;/th>
 &lt;th>D1&lt;/th>
 &lt;th>D0&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>位名&lt;/td>
 &lt;td>SM0&lt;/td>
 &lt;td>SM1&lt;/td>
 &lt;td>SM2&lt;/td>
 &lt;td>REN&lt;/td>
 &lt;td>TB8&lt;/td>
 &lt;td>RB8&lt;/td>
 &lt;td>TI&lt;/td>
 &lt;td>RI&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="sm0和sm1位">SM0和SM1位 &lt;a href="#sm0%e5%92%8csm1%e4%bd%8d" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;p>用于选择串行工作方式&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>SM0 SM1&lt;/th>
 &lt;th>工作方式&lt;/th>
 &lt;th>功能&lt;/th>
 &lt;th>波特率&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>00&lt;/td>
 &lt;td>0&lt;/td>
 &lt;td>8位同步移位寄存器（输出）&lt;/td>
 &lt;td>波特率固定为fosc/12&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>01&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>10位异步收发方式（8位数据）&lt;/td>
 &lt;td>波特率可变&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>10&lt;/td>
 &lt;td>2&lt;/td>
 &lt;td>11位异步收发（9位数据）&lt;/td>
 &lt;td>波特率固定为fosc/64或fosc/32&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>11&lt;/td>
 &lt;td>3&lt;/td>
 &lt;td>11位异步收发方式（9位数据）&lt;/td>
 &lt;td>波特率可变&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h3 id="sm2位">SM2位 &lt;a href="#sm2%e4%bd%8d" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;p>多机通信控制位，主要用于方式2和方式3。&lt;/p>
&lt;ul>
&lt;li>在工作方式0中，SM2必须设成0。&lt;/li>
&lt;li>在工作方式1中，当处于接收状态时，若SM2=1，则只有接收到的停止位“1”时，RI才能被激活成“1”（产生中断请求）。&lt;/li>
&lt;li>在工作方式2和3中，当SM2=0时，串口以单机发送或接收方式工作，TI和RI以正常方式被激活并产生中断请求；&lt;/li>
&lt;li>在工作方式2和3中，当SM2=1时，若RB8=1，则RI被激活并产生中断请求；若RB8=0，不激活RI，也不引起接收中断请求。&lt;/li>
&lt;/ul>
&lt;h3 id="ren位">REN位 &lt;a href="#ren%e4%bd%8d" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h3>&lt;p>使能串行接收位。&lt;/p></description></item><item><title>2.读操作</title><link>https://blog.simgor.cn/blog/2.%E8%AF%BB%E6%93%8D%E4%BD%9C/</link><pubDate>Thu, 03 Jul 2025 22:40:43 +0800</pubDate><guid>https://blog.simgor.cn/blog/2.%E8%AF%BB%E6%93%8D%E4%BD%9C/</guid><description>&lt;p>作者是初学者，水平有限，本文仅作为个人学习笔记使用，不能保证内容的正确性。部分资料来源于网络，参考了SD卡协议2.0手册等资料，如果有歧义，可以与作者联系。&lt;/p>
&lt;h1 id="简介">简介 &lt;a href="#%e7%ae%80%e4%bb%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>SD卡在SPI模式下，初始化完成之后就可以进行块操作，如读操作。SD卡有两种读取数据块的方式：&lt;/p>
&lt;ul>
&lt;li>单次读数据块&lt;/li>
&lt;li>连续读数据块&lt;/li>
&lt;/ul>
&lt;p>其中，每次读取的数据块大小，数据块的长度由CMD16（ SET_BLOCKLEN）命令设置。高容量SD卡的块大小固定为512字节，因此起始地址应与块边界对齐。&lt;/p>
&lt;h1 id="单次读数据块">单次读数据块 &lt;a href="#%e5%8d%95%e6%ac%a1%e8%af%bb%e6%95%b0%e6%8d%ae%e5%9d%97" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>命令号&lt;/th>
 &lt;th>参数&lt;/th>
 &lt;th>响应&lt;/th>
 &lt;th>名称&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>CMD17&lt;/td>
 &lt;td>[31:0]：数据地址，单位：字节（SDSC），单位:512字节（SDHC）&lt;/td>
 &lt;td>R1&lt;/td>
 &lt;td>READ_SINGLE_BLOCK&lt;/td>
 &lt;td>读取一个块的数据，参数为块的首地址。块的长度由CMD16设置，对于高容量卡，块大小固定为512字节&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>通过发送CMD17（READ_SINGLE_BLOCK）命令，让SD卡按照参数的地址返回一个块的数据。当发生错误的时候，SD卡会响应一个数据错误令牌。








 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/02/3935951914.png" alt="SD卡-SPI模式单次读操作.png" loading="lazy">
 

&lt;/p>
&lt;h1 id="连续数据块">连续数据块 &lt;a href="#%e8%bf%9e%e7%bb%ad%e6%95%b0%e6%8d%ae%e5%9d%97" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>命令号&lt;/th>
 &lt;th>参数&lt;/th>
 &lt;th>响应&lt;/th>
 &lt;th>名称&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>CMD18&lt;/td>
 &lt;td>[31:0]：数据地址，单位：字节（SDSC），单位:512字节（SDHC）&lt;/td>
 &lt;td>R1&lt;/td>
 &lt;td>READ_MULTIPLE_BLOCK&lt;/td>
 &lt;td>连续读取多块数据，直到主机发送CMD12命令，参数为块的首地址。块的长度由CMD16设置，对于高容量卡，块大小固定为512字节&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>与单次读扇区相似，通过发送CMD18（READ_MULTIPLE_BLOCK）命令，让SD卡按照参数指定的地址开始连续返回数据块，需要停止读取时，MCU发送CMD12（STOP_TRANSMISSION）命令停止读取。当发生错误的时候，SD卡会响应一个数据错误令牌。








 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/02/2657434650.png" alt="SD卡-SPI模式连续读数据块.png" loading="lazy">
 

&lt;/p>
&lt;h1 id="数据错误令牌格式">数据错误令牌格式 &lt;a href="#%e6%95%b0%e6%8d%ae%e9%94%99%e8%af%af%e4%bb%a4%e7%89%8c%e6%a0%bc%e5%bc%8f" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>与R2令牌的内容相似，长度为1字节，其中高4位固定为0。在发送命令CMD17、CMD18之后，如果响应的R1令牌指示发生错误，SD卡将继续响应该令牌。








 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/02/3992104664.png" alt="数据错误令牌格式.png" loading="lazy">
 

&lt;/p>
&lt;h1 id="如果需要评论">如果需要评论 &lt;a href="#%e5%a6%82%e6%9e%9c%e9%9c%80%e8%a6%81%e8%af%84%e8%ae%ba" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>因为是个人博客，因备案要求不能使用交互服务，如果需要评论，可以前往本文的CSDN页：
&lt;a href="https://blog.csdn.net/Simgo/article/details/128825969" rel="external" target="_blank">CSDN-SD卡 SPI模式操作（2）读操作&lt;svg width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">&lt;path fill="currentColor" d="M14 5c-.552 0-1-.448-1-1s.448-1 1-1h6c.552 0 1 .448 1 1v6c0 .552-.448 1-1 1s-1-.448-1-1v-3.586l-7.293 7.293c-.391.39-1.024.39-1.414 0-.391-.391-.391-1.024 0-1.414l7.293-7.293h-3.586zm-9 2c-.552 0-1 .448-1 1v11c0 .552.448 1 1 1h11c.552 0 1-.448 1-1v-4.563c0-.552.448-1 1-1s1 .448 1 1v4.563c0 1.657-1.343 3-3 3h-11c-1.657 0-3-1.343-3-3v-11c0-1.657 1.343-3 3-3h4.563c.552 0 1 .448 1 1s-.448 1-1 1h-4.563z"/>&lt;/svg>&lt;/a>&lt;/p></description></item><item><title>3.写操作</title><link>https://blog.simgor.cn/blog/3.%E5%86%99%E6%93%8D%E4%BD%9C/</link><pubDate>Thu, 03 Jul 2025 22:41:27 +0800</pubDate><guid>https://blog.simgor.cn/blog/3.%E5%86%99%E6%93%8D%E4%BD%9C/</guid><description>&lt;p>作者是初学者，水平有限，本文仅作为个人学习笔记使用，不能保证内容的正确性。部分资料来源于网络，参考了SD卡协议2.0手册等资料，如果有歧义，可以与作者联系。&lt;/p>
&lt;h1 id="简介">简介 &lt;a href="#%e7%ae%80%e4%bb%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>写入操作有两种类型：&lt;/p>
&lt;ul>
&lt;li>单次写操作&lt;/li>
&lt;li>连续写操作
其中，每次写入的数据块长度由CMD16（ SET_BLOCKLEN）命令设置。高容量SD卡的块大小固定为512字节，因此起始地址应与块边界对齐。&lt;/li>
&lt;/ul>
&lt;h1 id="单次写操作">单次写操作 &lt;a href="#%e5%8d%95%e6%ac%a1%e5%86%99%e6%93%8d%e4%bd%9c" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>命令号&lt;/th>
 &lt;th>参数&lt;/th>
 &lt;th>响应&lt;/th>
 &lt;th>名称&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>CMD24&lt;/td>
 &lt;td>[31:0]：数据地址，单位：字节（SDSC），单位:512字节（SDHC）&lt;/td>
 &lt;td>R1&lt;/td>
 &lt;td>WRITE_BLOCK&lt;/td>
 &lt;td>写入一个块的数据，参数为块的首地址。块的长度由CMD16设置，对于高容量卡，块大小固定为512字节&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>通过发送CMD24（WRITE_BLOCK）命令，往参数指定的地址写入一个块的数据。因为高容量卡（SDHC）的块长度固定为512字节，所以发送地址的时候，需要将起始地址对齐到512字节，也就是说，起始地址需要为512的倍数。
在写入一个块的数据之前，需要发送数据起始令牌，该令牌为1个字节，格式为0xFE，表示开始传输数据块。
接下来需要发送一个数据块，该数据块的长度由CMD16（SET_BLOCKLEN）命令设置，一般在初始化时设置完毕。高容量卡（SDHC）的块长度固定为512字节。
发送完数据块之后，需要发送一个CRC，长度为2字节，在SPI模式下，要求不高的情况下可以省略掉，固定为0xFF。
当SD卡收到以上数据的时候，会对这些数据进行计算，并且返回一个数据应答令牌，指示当前数操作是否发生错误。如果接收到的数据块没有错误，将对其进行编程。只要SD卡忙着编程，就会向主机发送连续的忙令牌流，即将DO（对应MCU的MISO）拉低，直到SD卡完成操作，才会将DO拉高，表示空闲。








 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/02/1507326852.png" alt="SD卡-SPI模式单次写操作.png" loading="lazy">
 

&lt;/p>
&lt;h1 id="连续写操作">连续写操作 &lt;a href="#%e8%bf%9e%e7%bb%ad%e5%86%99%e6%93%8d%e4%bd%9c" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>命令号&lt;/th>
 &lt;th>参数&lt;/th>
 &lt;th>响应&lt;/th>
 &lt;th>名称&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>CMD25&lt;/td>
 &lt;td>[31:0]：数据地址，单位：字节（SDSC），单位:512字节（SDHC）&lt;/td>
 &lt;td>R1&lt;/td>
 &lt;td>WRITE_MULTIPLE_BLOCK&lt;/td>
 &lt;td>连续写入多块数据，直到主机发送CMD12命令，参数为块的首地址。块的长度由CMD16设置，对于高容量卡，块大小固定为512字节&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>通过发送CMD25（WRITE_MULTIPLE_BLOCK）命令，从参数指定的地址开始，连续写入数据块。因为高容量卡（SDHC）的块长度固定为512字节，所以发送地址的时候，需要将起始地址对齐到512字节，也就是说，起始地址需要为512的倍数。
在写入一个块的数据之前，需要发送数据起始令牌，该令牌为1个字节，格式为&lt;strong>0xFC&lt;/strong>，表示开始传输数据块。&lt;/p>
&lt;blockquote>
&lt;p>注意：0xFC是连续写入的起始令牌，0xFE是单次读取、连续读取、单次写入的起始令牌。&lt;/p>&lt;/blockquote>
&lt;p>接下来需要发送一个数据块，该数据块的长度由CMD16（SET_BLOCKLEN）命令设置，一般在初始化时设置完毕。高容量卡（SDHC）的块长度固定为512字节。
发送完数据块之后，需要发送一个CRC，长度为2字节，在SPI模式下，要求不高的情况下可以省略掉，固定为0xFF。
当SD卡收到以上数据的时候，会对这些数据进行计算，并且返回一个数据应答令牌，指示当前数操作是否发生错误。如果接收到的数据块没有错误，将对其进行编程。只要SD卡忙着编程，就会向主机发送连续的忙令牌流，即将DO（对应MCU的MISO）拉低，直到SD卡完成操作，才会将DO拉高，表示空闲。
这时候，可以继续重复以上的步骤，进行连续传输。当需要结束写入数据的时候，可以发送结束数据令牌，该令牌位1个字节，格式为0xFD。&lt;/p>
&lt;blockquote>
&lt;p>注意：连续写入的结束条件是发送结束令牌，而不是发送CMD12命令，CMD12命令只适用于连续读操作。&lt;/p>&lt;/blockquote>
&lt;p>







 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/02/654117237.png" alt="SD卡-SPI模式连续写操作.png" loading="lazy">
 

&lt;/p>
&lt;p>当写入时发生数据错误，SD卡会停止写入，这时候可以发送ACMD12命令获取正确写入的块数。该命令的响应格式为4个字节的块数，以及2字节的CRC。&lt;/p>
&lt;h1 id="数据应答令牌格式">数据应答令牌格式 &lt;a href="#%e6%95%b0%e6%8d%ae%e5%ba%94%e7%ad%94%e4%bb%a4%e7%89%8c%e6%a0%bc%e5%bc%8f" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>在发送完数据块内容和CRC之后，SD卡会返回一个数据应答令牌，指示当前数操作是否发生错误。该令牌为1个字节，低5位有效，第4位固定为0，第0位固定为1：








 



 
 
 &lt;img src="https://mirror.simgor.cn/typecho_img/2023/02/390449443.png" alt="Pasted image 20230203183242.png" loading="lazy">
 

&lt;/p>
&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>[1：3]位&lt;/th>
 &lt;th>描述&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>010&lt;/td>
 &lt;td>数据已接受&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>101&lt;/td>
 &lt;td>CRC错误，数据被拒绝&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>110&lt;/td>
 &lt;td>写入错误，数据被拒绝&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h1 id="关于写入完成之后的操作可选">关于写入完成之后的操作（可选） &lt;a href="#%e5%85%b3%e4%ba%8e%e5%86%99%e5%85%a5%e5%ae%8c%e6%88%90%e4%b9%8b%e5%90%8e%e7%9a%84%e6%93%8d%e4%bd%9c%e5%8f%af%e9%80%89" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>可以继续发送CMD13（SEND_STATUS）命令。要求SD卡发送状态寄存器的内容，以获取SD卡的当前状态。&lt;/p>
&lt;h1 id="如果需要评论">如果需要评论 &lt;a href="#%e5%a6%82%e6%9e%9c%e9%9c%80%e8%a6%81%e8%af%84%e8%ae%ba" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>因为是个人博客，因备案要求不能使用交互服务，如果需要评论，可以前往本文的CSDN页：
&lt;a href="https://blog.csdn.net/Simgo/article/details/128876798" rel="external" target="_blank">CSDN-SD卡 SPI模式操作（3）写操作&lt;svg width="16" height="16" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">&lt;path fill="currentColor" d="M14 5c-.552 0-1-.448-1-1s.448-1 1-1h6c.552 0 1 .448 1 1v6c0 .552-.448 1-1 1s-1-.448-1-1v-3.586l-7.293 7.293c-.391.39-1.024.39-1.414 0-.391-.391-.391-1.024 0-1.414l7.293-7.293h-3.586zm-9 2c-.552 0-1 .448-1 1v11c0 .552.448 1 1 1h11c.552 0 1-.448 1-1v-4.563c0-.552.448-1 1-1s1 .448 1 1v4.563c0 1.657-1.343 3-3 3h-11c-1.657 0-3-1.343-3-3v-11c0-1.657 1.343-3 3-3h4.563c.552 0 1 .448 1 1s-.448 1-1 1h-4.563z"/>&lt;/svg>&lt;/a>&lt;/p></description></item><item><title>比特计算器工具</title><link>https://blog.simgor.cn/tools/%E6%AF%94%E7%89%B9%E8%AE%A1%E7%AE%97%E5%99%A8%E5%B7%A5%E5%85%B7/</link><pubDate>Mon, 01 Sep 2025 08:24:02 +0800</pubDate><guid>https://blog.simgor.cn/tools/%E6%AF%94%E7%89%B9%E8%AE%A1%E7%AE%97%E5%99%A8%E5%B7%A5%E5%85%B7/</guid><description>&lt;h1 id="计算器">计算器 &lt;a href="#%e8%ae%a1%e7%ae%97%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>在嵌入式开发中，经常需要进行各种位运算和进制转换。这个比特计算器提供了便捷的进制转换和位操作功能。&lt;/p>
&lt;div style="width: 100%; height: 750px; border: 1px solid #e1e5e9; border-radius: 8px; overflow: hidden; box-shadow: 0 2px 8px rgba(0,0,0,0.1); margin: 20px 0;">
 &lt;iframe src="https://assets.simgor.cn/public/tool/BitCalculator" 
 style="width: 100%; height: 100%; border: none;" 
 >
 &lt;/iframe>
&lt;/div>
&lt;h1 id="十六进制与二进制">十六进制与二进制 &lt;a href="#%e5%8d%81%e5%85%ad%e8%bf%9b%e5%88%b6%e4%b8%8e%e4%ba%8c%e8%bf%9b%e5%88%b6" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>二进制&lt;/th>
 &lt;th>十六进制&lt;/th>
 &lt;th>十进制&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>0000&lt;/td>
 &lt;td>0&lt;/td>
 &lt;td>0&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0001&lt;/td>
 &lt;td>1&lt;/td>
 &lt;td>1&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0010&lt;/td>
 &lt;td>2&lt;/td>
 &lt;td>2&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0011&lt;/td>
 &lt;td>3&lt;/td>
 &lt;td>3&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0100&lt;/td>
 &lt;td>4&lt;/td>
 &lt;td>4&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0101&lt;/td>
 &lt;td>5&lt;/td>
 &lt;td>5&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0110&lt;/td>
 &lt;td>6&lt;/td>
 &lt;td>6&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>0111&lt;/td>
 &lt;td>7&lt;/td>
 &lt;td>7&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1000&lt;/td>
 &lt;td>8&lt;/td>
 &lt;td>8&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1001&lt;/td>
 &lt;td>9&lt;/td>
 &lt;td>9&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1010&lt;/td>
 &lt;td>A&lt;/td>
 &lt;td>10&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1011&lt;/td>
 &lt;td>B&lt;/td>
 &lt;td>11&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1100&lt;/td>
 &lt;td>C&lt;/td>
 &lt;td>12&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1101&lt;/td>
 &lt;td>D&lt;/td>
 &lt;td>13&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1110&lt;/td>
 &lt;td>E&lt;/td>
 &lt;td>14&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>1111&lt;/td>
 &lt;td>F&lt;/td>
 &lt;td>15&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;h1 id="常用应用场景">常用应用场景 &lt;a href="#%e5%b8%b8%e7%94%a8%e5%ba%94%e7%94%a8%e5%9c%ba%e6%99%af" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;h2 id="位掩码操作">位掩码操作 &lt;a href="#%e4%bd%8d%e6%8e%a9%e7%a0%81%e6%93%8d%e4%bd%9c" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h2>&lt;ul>
&lt;li>&lt;strong>设置位&lt;/strong>: &lt;code>value |= (1 &amp;lt;&amp;lt; bit_position)&lt;/code>&lt;/li>
&lt;li>&lt;strong>清除位&lt;/strong>: &lt;code>value &amp;amp;= ~(1 &amp;lt;&amp;lt; bit_position)&lt;/code>&lt;/li>
&lt;li>&lt;strong>切换位&lt;/strong>: &lt;code>value ^= (1 &amp;lt;&amp;lt; bit_position)&lt;/code>&lt;/li>
&lt;li>&lt;strong>检查位&lt;/strong>: &lt;code>(value &amp;amp; (1 &amp;lt;&amp;lt; bit_position)) != 0&lt;/code>&lt;/li>
&lt;/ul></description></item><item><title>稳压器分压电阻计算工具</title><link>https://blog.simgor.cn/tools/%E7%A8%B3%E5%8E%8B%E5%99%A8%E5%88%86%E5%8E%8B%E7%94%B5%E9%98%BB%E8%AE%A1%E7%AE%97%E5%B7%A5%E5%85%B7/</link><pubDate>Thu, 03 Jul 2025 22:24:02 +0800</pubDate><guid>https://blog.simgor.cn/tools/%E7%A8%B3%E5%8E%8B%E5%99%A8%E5%88%86%E5%8E%8B%E7%94%B5%E9%98%BB%E8%AE%A1%E7%AE%97%E5%B7%A5%E5%85%B7/</guid><description>&lt;h1 id="计算器">计算器 &lt;a href="#%e8%ae%a1%e7%ae%97%e5%99%a8" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;p>随着用过的DC-DC越来越多，每家的FB参考电压还各不相同，所以我决定弄一个方便选择电阻的计算器。&lt;/p>
&lt;p>这个计算器得到的值不一定是最优值，仅供参考。&lt;/p>
&lt;div style="width: 100%; height: 600px; overflow: hidden;">
 &lt;iframe src="https://mirror.simgor.cn/tool/VoltageDividerCalculator.html" style="width: 100%; height: 100%; border: none;" scrolling="no">&lt;/iframe>
&lt;/div>
&lt;h1 id="06v参考电压">0.6V参考电压 &lt;a href="#06v%e5%8f%82%e8%80%83%e7%94%b5%e5%8e%8b" class="anchor" aria-hidden="true">&lt;i class="material-icons align-middle">link&lt;/i>&lt;/a>&lt;/h1>&lt;table>
 &lt;thead>
 &lt;tr>
 &lt;th>输出电压&lt;/th>
 &lt;th>R1&lt;/th>
 &lt;th>R2&lt;/th>
 &lt;/tr>
 &lt;/thead>
 &lt;tbody>
 &lt;tr>
 &lt;td>5V&lt;/td>
 &lt;td>110k&lt;/td>
 &lt;td>15k&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3.31998V&lt;/td>
 &lt;td>68k&lt;/td>
 &lt;td>15k&lt;/td>
 &lt;/tr>
 &lt;tr>
 &lt;td>3.3273V&lt;/td>
 &lt;td>100k&lt;/td>
 &lt;td>22k&lt;/td>
 &lt;/tr>
 &lt;/tbody>
&lt;/table>
&lt;p>$$ V_{out} = V_{ref} \left( 1 + \frac{R1}{R2} \right) $$&lt;/p></description></item></channel></rss>