请问esp32的VSPI和HSPI除了引脚不同之外有没有其它区别?-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 4279|回复: 7

[未解决] 请问esp32的VSPI和HSPI除了引脚不同之外有没有其它区别?

[复制链接]
发表于 2020-9-9 16:02 | 显示全部楼层 |阅读模式
连接ADXL355加速度计做测试,按照VSPI的接口连接,采集数据没有问题,但是一旦把接口全部换成HSPI,就无法采集到数据了(全都是0),请问还需要在代码中进行其它配置吗?

部分代码如下:

void writeRegister(byte thisRegister, byte thisValue) {
  byte dataToSend = (thisRegister << 1) | WRITE_BYTE;
  digitalWrite(CHIP_SELECT_PIN, LOW);
  SPI.transfer(dataToSend);
  SPI.transfer(thisValue);
  digitalWrite(CHIP_SELECT_PIN, HIGH);
}

unsigned int readRegistry(byte thisRegister) {
  unsigned int result = 0;
  byte dataToSend = (thisRegister << 1) | READ_BYTE;

  digitalWrite(CHIP_SELECT_PIN, LOW);
  SPI.transfer(dataToSend);
  result = SPI.transfer(0x00);
  digitalWrite(CHIP_SELECT_PIN, HIGH);
  return result;
}

void readMultipleData(int *addresses, int dataSize, int *readedData) {
  digitalWrite(CHIP_SELECT_PIN, LOW);
  for(int i = 0; i < dataSize; i = i + 1) {
    byte dataToSend = (addresses[i] << 1) | READ_BYTE;
    SPI.transfer(dataToSend);
    readedData[i] = SPI.transfer(0x00);
  }
  digitalWrite(CHIP_SELECT_PIN, HIGH);
}


发表于 2020-11-30 17:06 | 显示全部楼层
本帖最后由 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库文件中总结的。虽然论坛大家互帮互助,终究不如靠自己。

 楼主| 发表于 2020-9-9 19:14 | 显示全部楼层

const int CHIP_SELECT_PIN = 15;
pinMode(CHIP_SELECT_PIN,OUTPUT);

已经这样配置过了,之前使用VSPI的时候,引脚是5,可以正常采集数据,改成HSPI,引脚也改成了HSPI的CS引脚15,就采集不到数据了,还是说除此之外还要配置其他的吗?
发表于 2020-9-9 18:38 | 显示全部楼层
要配置SPI引脚
发表于 2020-9-9 22:07 | 显示全部楼层
Celeste914 发表于 2020-9-9 19:14
const int CHIP_SELECT_PIN = 15;
pinMode(CHIP_SELECT_PIN,OUTPUT);

Arduino 中 SPI就是VSSPI,改片选是没有用的
 楼主| 发表于 2020-9-10 01:00 | 显示全部楼层
XlinliY.Zhang 发表于 2020-9-9 22:07
Arduino 中 SPI就是VSSPI,改片选是没有用的

那请问您说的“配置SPI引脚”具体应该如何操作呢?
 楼主| 发表于 2020-9-11 18:44 | 显示全部楼层
XlinliY.Zhang 发表于 2020-9-9 22:07
Arduino 中 SPI就是VSSPI,改片选是没有用的

您的意思我理解了,是指在Arduino中,只能使用VSPI,无法使用HSPI吗?

如果是这样,因为SPI本身就是并行的,那么我是不是可以把开发板上的CS、SCK、MISO、MOSI、DRDY这些接口全都一分多个出来,然后连接不同的设备,通过不同的片选信号来控制呢?
发表于 2022-1-22 11:26 | 显示全部楼层
zapquiyou 发表于 2020-11-30 17:06
看着提问时间还不算长我就帮你回答一下,语言严苛一点也请见谅,毕竟忠言逆耳。楼上的回答并没有直接回答了 ...

虽然你说得很对,但我用你的办法还是不行,网上找了很久也都是SPIClass SPI2(HSPI);这种自定义一个spi为hspi的办法。底层文件也讲解得很对,但是还是不行,当然原因也很有可能在我。
后来我用另外的办法可以了
#define H_MISO     12
#define H_MOSI     13
#define H_SCLK     14
#define H_CS       3

SPI.begin(H_SCLK, H_MISO, H_MOSI);  //setup()里写

这种直接定义hspi的脚,再直接初始化这三个脚就可以了,我是运用到rc522门禁上的,CS是可以自定义的,所以begin里并没有他,运用到其他地方就不清楚了
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-11-28 16:04 , Processed in 0.073744 second(s), 17 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表