> 文章列表 > ESP32的VSPI和HSPI

ESP32的VSPI和HSPI

ESP32的VSPI和HSPI

说明

SPI共有4根线,MOSI、MISO、CS、CLK,在ESP32中对应规则如下表:
ESP32的VSPI和HSPI
ESP32共有4个SPI,但是用户能够使用的只有2个SPI,分为VSPI和HSPI。
ESP32的VSPI和HSPI

引脚接口

在ESP32的数据手册中,说明了VSPI和HSPI对应的引脚:

  • VSPI:
    ESP32的VSPI和HSPI
  • HSPI:
    ESP32的VSPI和HSPI
    但是比较麻烦的是,ESP官方不知道犯了什么SB毛病,非弄出来个没有丝毫用途的Strapping 管脚,稍不注意,上电瞬间Strapping管脚电平不对,就没法正常启动,导致但凡是有Strapping管脚功能的引脚,大家都不敢使用
    在SPI中也是这样,VSPI和HSPI默认的引脚中,都有作为Strapping管脚的引脚。我们要格外格外的小心
    ESP32的VSPI和HSPI
    ESP32的VSPI和HSPI

结合Strapping管脚,将引脚对应整理如下表

  • VSPI
引脚 功能 备注
IO23 MOSI
IO19 MISO
IO18 CLK
IO5 CS Strapping管脚,上电瞬间必须保证上拉
  • HSPI
引脚 功能 备注
IO13 MOSI
IO12 MISO Strapping管脚,上电瞬间必须保证下拉
IO14 CLK
IO15 CS Strapping管脚,上电瞬间必须保证上拉

更改Auduino框架中SPI默认的引脚

在用arduino框架时,其默认的SPI引脚如下:
ESP32的VSPI和HSPI

除了使用默认的引脚之外,还可以使用其他方式更改默认引脚。官方给出的示例如下:

/* The ESP32 has four SPi buses, however as of right now only two of* them are available to use, HSPI and VSPI. Simply using the SPI API * as illustrated in Arduino examples will use VSPI, leaving HSPI unused.* * However if we simply intialise two instance of the SPI class for both* of these buses both can be used. However when just using these the Arduino* way only will actually be outputting at a time.* * Logic analyser capture is in the same folder as this example as* "multiple_bus_output.png"* * created 30/04/2018 by Alistair Symonds*/
#include <SPI.h>// Define ALTERNATE_PINS to use non-standard GPIO pins for SPI bus#ifdef ALTERNATE_PINS#define VSPI_MISO   2#define VSPI_MOSI   4#define VSPI_SCLK   0#define VSPI_SS     33#define HSPI_MISO   26#define HSPI_MOSI   27#define HSPI_SCLK   25#define HSPI_SS     32
#else#define VSPI_MISO   MISO#define VSPI_MOSI   MOSI#define VSPI_SCLK   SCK#define VSPI_SS     SS#define HSPI_MISO   12#define HSPI_MOSI   13#define HSPI_SCLK   14#define HSPI_SS     15
#endif#if CONFIG_IDF_TARGET_ESP32S2 || CONFIG_IDF_TARGET_ESP32S3
#define VSPI FSPI
#endifstatic const int spiClk = 1000000; // 1 MHz//uninitalised pointers to SPI objects
SPIClass * vspi = NULL;
SPIClass * hspi = NULL;void setup() {//initialise two instances of the SPIClass attached to VSPI and HSPI respectivelyvspi = new SPIClass(VSPI);hspi = new SPIClass(HSPI);//clock miso mosi ss#ifndef ALTERNATE_PINS//initialise vspi with default pins//SCLK = 18, MISO = 19, MOSI = 23, SS = 5vspi->begin();
#else//alternatively route through GPIO pins of your choicevspi->begin(VSPI_SCLK, VSPI_MISO, VSPI_MOSI, VSPI_SS); //SCLK, MISO, MOSI, SS
#endif#ifndef ALTERNATE_PINS//initialise hspi with default pins//SCLK = 14, MISO = 12, MOSI = 13, SS = 15hspi->begin();
#else//alternatively route through GPIO pinshspi->begin(HSPI_SCLK, HSPI_MISO, HSPI_MOSI, HSPI_SS); //SCLK, MISO, MOSI, SS
#endif//set up slave select pins as outputs as the Arduino API//doesn't handle automatically pulling SS lowpinMode(vspi->pinSS(), OUTPUT); //VSPI SSpinMode(hspi->pinSS(), OUTPUT); //HSPI SS}// the loop function runs over and over again until power down or reset
void loop() {//use the SPI busesspiCommand(vspi, 0b01010101); // junk data to illustrate usagespiCommand(hspi, 0b11001100);delay(100);
}void spiCommand(SPIClass *spi, byte data) {//use it as you would the regular arduino SPI APIspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));digitalWrite(spi->pinSS(), LOW); //pull SS slow to prep other end for transferspi->transfer(data);digitalWrite(spi->pinSS(), HIGH); //pull ss high to signify end of data transferspi->endTransaction();
}