如何在ESP32 (pico-v3-02)上使用自定义引脚的SPI



我试图在pico-mini-02板上使用SPI的自定义引脚。该板具有esp32 (pico-v3-02)。我使用Arduino IDE(与Arduino -esp32)和windows 10。

当我尝试使用SPI示例(多个总线示例)时,我得到Guru Meditation Error: Core 1 panic'ed (LoadProhibited). Exception was unhandled.错误。我已经解码了异常backtrace

0x40080f31: __pinMode at C:UsersnewtoOneDriveDocumentsArduinoDatapackagesesp32hardwareesp321.0.5coresesp32esp32-hal-gpio.c line 115
0x400d0f3a: spiAttachSCK at C:UsersnewtoOneDriveDocumentsArduinoDatapackagesesp32hardwareesp321.0.5coresesp32esp32-hal-spi.c line 87
0x400d0db2: SPIClass::begin(signed char, signed char, signed char, signed char) at C:UsersnewtoOneDriveDocumentsArduinoDatapackagesesp32hardwareesp321.0.5librariesSPIsrcSPI.cpp line 57
0x400d0c2b: setup() at C:UsersnewtoOneDriveDocumentsArduinoDatapackagesesp32hardwareesp321.0.5librariesSPIexamplesSPI_Multiple_Buses/SPI_Multiple_Buses.ino line 67
0x400d190a: loopTask(void*) at C:UsersnewtoOneDriveDocumentsArduinoDatapackagesesp32hardwareesp321.0.5coresesp32main.cpp line 32
0x40085fa5: vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c line 143

完整的错误信息:

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 271414342, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:10124
load:0x40080400,len:5856
entry 0x400806a8
Guru Meditation Error: Core  1 panic'ed (LoadProhibited). Exception was unhandled.
Core 1 register dump:
PC      : 0x40080f31  PS      : 0x00060730  A0      : 0x800d0f3d  A1      : 0x3ffb1f30
A2      : 0x0000000e  A3      : 0x00000002  A4      : 0x3ffb8364  A5      : 0x00000001
A6      : 0x00000000  A7      : 0x00000004  A8      : 0x3f400674  A9      : 0xaaaaaaaa
A10     : 0xaaaaaaaa  A11     : 0x00000030  A12     : 0x3ffb82cc  A13     : 0x00000000
A14     : 0x00000000  A15     : 0x00000000  SAR     : 0x00000009  EXCCAUSE: 0x0000001c
EXCVADDR: 0xaaaaaaaa  LBEG    : 0x400d1258  LEND    : 0x400d1265  LCOUNT  : 0x00000000
ELF file SHA256: 0000000000000000
Backtrace: 0x40080f31:0x3ffb1f30 0x400d0f3a:0x3ffb1f50 0x400d0db2:0x3ffb1f70 0x400d0c2b:0x3ffb1f90 0x400d190a:0x3ffb1fb0 0x40085fa5:0x3ffb1fd0
Rebooting...
ets Jul 29 2019 12:21:46

如有任何帮助,不胜感激。


素描:


/* 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
static 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 respectively
vspi = 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 = 5
vspi->begin();
#else
//alternatively route through GPIO pins of your choice
vspi->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 = 15
hspi->begin();
#else
//alternatively route through GPIO pins
hspi->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 low
pinMode(VSPI_SS, OUTPUT); //VSPI SS
pinMode(HSPI_SS, OUTPUT); //HSPI SS
}
// the loop function runs over and over again until power down or reset
void loop() {
//use the SPI buses
vspiCommand();
hspiCommand();
delay(100);
}
void vspiCommand() {
byte data = 0b01010101; // junk data to illustrate usage
//use it as you would the regular arduino SPI API
vspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(VSPI_SS, LOW); //pull SS slow to prep other end for transfer
vspi->transfer(data);  
digitalWrite(VSPI_SS, HIGH); //pull ss high to signify end of data transfer
vspi->endTransaction();
}
void hspiCommand() {
byte stuff = 0b11001100;

hspi->beginTransaction(SPISettings(spiClk, MSBFIRST, SPI_MODE0));
digitalWrite(HSPI_SS, LOW);
hspi->transfer(stuff);
digitalWrite(HSPI_SS, HIGH);
hspi->endTransaction();
}

我试过这个代码,它可以工作。我选择了与我的板匹配的AI思考者ESP32,我选择了Flash模式QIO和DIO:两者都工作良好。如果您仍然有问题,我建议您选择DOUT或DIO。

基本上请检查您的板是否与Tools-> board上选择的板匹配,并检查'Flash mode'的选择。

不是所有的芯片都支持所有这些模式。数据表是了解什么支持什么的最佳来源。

DIO - SPI host uses the "Dual I/O Fast Read" command (BBh). Two SPI pins are used to write the flash address part of the command, and to read flash data out. Therefore these phases need half the clock cycles compared to standard SPI.
DOUT - SPI host uses the "Dual Output Fast Read" command (3Bh). Two SPI pins are used to read flash data out. Slightly slower than DIO, because the address is written via the single MOSI data pin.
QIO - SPI host uses the "Quad I/O Fast Read" command (EBh). Four SPI pins are used to write the flash address part of the command, and to read flash data out. Therefore these phases need a quarter the clock cycles compared to standard SPI.
QOUT - SPI host uses the "Quad Output Fast Read" command (6Bh). Four SPI pins are used to read the flash data out. Slightly slower than QIO, because the address is written via the single MOSI data pin.

ESP-IDF默认为DIO,因为一些闪存芯片使用模式位来启用io &QOUT支持,这可能因制造商而异。

如果使用DIO/DOUT模式,gpio 9 &10个可用于其他用途。但是请注意,如果它们连接到SPI闪存芯片(例如,它们在WROOM中),那么SPI闪存芯片可能会将它们用于其他引脚功能。参考SPI闪存芯片数据表来确定。

关于这个话题的讨论非常有趣:https://www.esp32.com/viewtopic.php?t=1250

希望这对你有帮助。祝你一切顺利。

最新更新