SD 卡与其他 SPI 设备共享 SPI 总线
========================================================

:link_to_translation:`en:[English]`

SD 卡支持 SPI 模式，使其能够作为 SPI 设备通信，但使用时需注意其限制。

其他设备的管脚负载
----------------------------

向同一总线添加设备会增加管脚的整体负载，包括交流负载（管脚电容）和直流负载（上拉电阻）。

交流负载
^^^^^^^^^^

在通信速率不超过 50 MHz 的情况下，专为高速通信设计的 SD 卡采用小型管脚电容（交流负载小）。但在同一 SPI 总线上连接其他设备后，会增加管脚的交流负载。

管脚交流负载过高时，可能无法实现电平快速切换。通过使用示波器，你可以观察到管脚状态变化的边缘变得更加平滑，即边缘变化率更低。当 SD 卡连接到交流负载较高的总线时，可能无法满足 SD 卡建立时间 (setup) 的时序要求。高交流负载甚至可能导致 SD 卡和其他 SPI 设备无法正确解析主机发出的时钟信号，影响通信稳定性。

如果连接的其他设备的工作频率与 SD 卡工作频率不同，上述问题可能会更加明显。这是因为其他设备可能具有更大的管脚电容。管脚容量越大，响应时间越长，SD 总线可工作的最高频率越低。

你可以尝试以下测试，判断管脚交流负载是否过重：

术语

 - **启动边沿 (launch edge)**：数据开始切换的时钟边沿；
 - **锁存边沿 (latch edge)**：数据接收侧应进行数据采样的时钟边沿，对 SD 卡来说是上升沿。

1. 使用示波器观察时钟，并比较数据线与时钟。

   - 如果时钟不够快，例如上升/下降沿长于时钟周期的 1/4，表明时钟偏斜过大。
   - 如果在时钟锁存边沿之前数据线不稳定，表明数据线负载过大。

   借助逻辑分析仪，也可以观察到数据与时钟启动沿相比，延迟较大。但比起用示波器，用逻辑分析仪观察到的现象可能不太明显。

2. 尝试使用较低的时钟频率。

   如果设备可以在较低的通信频率下正常工作，而在较高的通信频率下出现问题，说明管脚交流负载过大。

如果管脚的交流负载过大，你可以选择使用其他管脚负载更低但通信速度更快的设备，或降低时钟速度。

直流负载
^^^^^^^^^^

SD 卡所需的上拉电阻通常在 10 kΩ 至 50 kΩ 之间，注意对某些 SPI 设备来说，这可能是过强的上拉电阻。

请查阅设备的规格说明书，了解其直流输出电流。此直流输出电流应大于 700 μA，否则可能无法正确读取设备输出。

初始化顺序
-----------------------

.. note::

  如果在执行以下步骤时遇到任何问题，请首先确保时序正确。如前文所述，你可以尝试降低时钟速度，例如将 SD 卡的 ``SDMMC_FREQ_PROBING`` 设置为 400 kHz，排除管脚交流负载的影响。

在同一 SPI 总线上与其他 SPI 设备一起使用 SD 卡时，由于 SD 卡启动流程的限制，应遵循以下初始化顺序。有关详情，请参阅 :example:`storage/sd_card`。

1. 通过 :cpp:func:`spi_bus_initialize` 正确初始化总线。

2. 将除 SD 卡外所有设备的 CS 线置为空闲状态（默认为高电平），避免在后续步骤中与 SD 卡发生冲突。

   这可以通过以下任一方式实现：

   1. 调用 :cpp:func:`spi_bus_add_device` 将设备连接到 SPI 总线，该函数将初始化用作 CS 的 GPIO 管脚到空闲电平：默认为高电平。

   2. 在添加新设备前，初始化需要拉高的 CS 管脚 GPIO。

   3. 在 ESP 的 GPIO 未初始化前，依靠内部/外部上拉电阻拉高所有 CS 管脚（**不推荐**）。请确保上拉电阻拥有足够强度，且没有其他下拉电阻影响拉高。例如，应启用内部下拉电阻。

3. 调用 :cpp:func:`esp_vfs_fat_sdspi_mount` 将卡挂载到文件系统。

   此步骤将使 SD 卡进入 SPI 模式，**应该** 在同一总线上的所有其他 SPI 通信前完成。否则，SD 卡会保持在 SD 模式，即使在未选中其 CS 线的情况下，SD 卡也可能随机响应总线上的任何 SPI 通信。

   如果你想测试这种行为，请注意，一旦 SD 卡置于 SPI 模式，在下次上电前，也就是断电后重新上电之前，SD 卡将不会返回 SD 模式

4. 此时，即可与其他 SPI 设备自由通信。
