|
本帖最后由 zapquiyou 于 2020-12-2 16:01 编辑
看着提问时间还不算长我就帮你回答一下,语言严苛一点也请见谅,毕竟忠言逆耳。楼上的回答并没有直接回答了你的问题,你也并没有理解楼上回答的问题。
esp32共有4个硬件spi接口:SPI0(用于cache访问外部储存单元),SPI1,SPI2(HSPI),SPI3(VSPI)。目前在Arduino中只能使用SPI2和SPI3,我给你把示例里的原文贴出来:
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.
SPI2和SPI3既可以作为主机也可以作为从机,作为主机时可以通过多个引脚连接从机实现SPI总线通讯。
回到问题,首先,使用的是VSPI还是HSPI,不是由你连接引脚决定的。因果关系搞混了,应该是你使用哪个SPI接口,需要去按其要求连接。而使用哪个SPI接口是需要你自己编写程序决定的。库文件提供了一个SPI的对象供使用,那么为什么是VSPI呢,这里我把库文件里SPI的声明代码贴出来:
SPIClass SPI(VSPI);
看到了没,这个SPI对象在初始化的时候使用的就是VSPI,因此你按照VSPI连线是可以使用的。但这也是默认连线,修改连线的函数为SPI的初始化函数,这里我也把代码贴出来
void SPIClass::begin(int8_t sck, int8_t miso, int8_t mosi, int8_t ss)
{
if(_spi) {
return;
}
if(!_div) {
_div = spiFrequencyToClockDiv(_freq);
}
_spi = spiStartBus(_spi_num, _div, SPI_MODE0, SPI_MSBFIRST);
if(!_spi) {
return;
}
if(sck == -1 && miso == -1 && mosi == -1 && ss == -1) {
_sck = (_spi_num == VSPI) ? SCK : 14;
_miso = (_spi_num == VSPI) ? MISO : 12;
_mosi = (_spi_num == VSPI) ? MOSI : 13;
_ss = (_spi_num == VSPI) ? SS : 15;
} else {
_sck = sck;
_miso = miso;
_mosi = mosi;
_ss = ss;
}
spiAttachSCK(_spi, _sck);
spiAttachMISO(_spi, _miso);
spiAttachMOSI(_spi, _mosi);
}
那么为什么会有默认引脚?这是因为在声明SPIClass这个类时引脚就有缺省值:
SPIClass::SPIClass(uint8_t spi_bus)
:_spi_num(spi_bus)
,_spi(NULL)
,_use_hw_ss(false)
,_sck(-1)
,_miso(-1)
,_mosi(-1)
,_ss(-1)
,_div(0)
,_freq(1000000)
,_inTransaction(false)
{}
默认引脚在程序里应定义好了,具体我就不细说了,在另一个偏底层的库文件进行了宏定义,也描述了引脚的信息:
#define HSPI 2 //SPI bus normally mapped to pins 12 - 15, but can be matrixed to any pins
#define VSPI 3 //SPI bus normally attached to pins 5, 18, 19 and 23, but can be matrixed to any pins
继续回到问题,如果我想使用另一个SPI接口,或者同时使用两个怎么办?需要声明两个不同接口的SPI对象,其中HSPI的声明有两种模式:
SPIClass SPI2; //这里SPI2你可以自定义对象名字
SPIClass SPI2(HSPI);
我更建议用第二种,比较清晰,代码易懂。第一种的原理是因为SPIClass的构造函数中有默认值:
SPIClass(uint8_t spi_bus=HSPI);
至于你说的总线结构(分出不同的线),我没有实际使用过,也不准备花时间去研究库文件了,这里给你一些应用时的代码进行参考,你可以尝试:
digitalWrite(SS_PIN, LOW);
while(digitalRead(MISO_PIN));
SPI.transfer(addr);
SPI.transfer(value);
digitalWrite(SS_PIN, HIGH);
这里可以把SS_PIN换成不同的引脚看是否可以控制多个从机。
写在最后,Arduino易于上手所以被认为低级。实际而言,想吃透Arduino的底层文件,以及第三方库进行程序上的优化和功能的实现并不是很容易。通过Arduino同样可以学习大量知识,同样可以进行相对标准的开发。如果仅仅是调库应用做一些酷炫的东西而不去学习相关的理论如数模电、单片机原理、微机原理等等我认为并没有什么用。以上内容是我通过基础的理论知识在ESP32的文档,ESP32示例,SPI库文件,esp32-hal-spi库文件中总结的。虽然论坛大家互帮互助,终究不如靠自己。
|
|