esp32的spi驱动的编写遇到的问题

      最近在使用esp32驱动一个spi设备的时候,spi设备没有应答,奇怪的时候我之前用stm32成功驱动过这个spi设备,怎么移植到esp32就不行呢?

      在使用stm32的时候我是使用spi   mode3,即CPOL=1, CPHA=1,参考通用的spi模式定义:

spi四种模式SPI的相位(CPHA)和极性(CPOL)分别可以为0或1,对应的4种组合构成了SPI的4种模式(mode)
Mode 0 CPOL=0, CPHA=0 
Mode 1 CPOL=0, CPHA=1
Mode 2 CPOL=1, CPHA=0 
Mode 3 CPOL=1, CPHA=1
时钟极性CPOL: 即SPI空闲时,时钟信号SCLK的电平(1:空闲时高电平; 0:空闲时低电平)
时钟相位CPHA: 即SPI在SCLK第几个边沿开始采样(0:第一个边沿开始; 1:第二个边沿开始)

时序图如下:

esp32的spi驱动的编写遇到的问题_第1张图片

在esp32上面我也应该使用mode3的,最后我改esp32的spi模式=SPI_MODE2的时候协议分析仪获取到的数据才是正确的,都有点让我怀疑人生了。难道标准规范不对?

      SPI.begin(sck, miso, mosi, cs);
      SPI.beginTransaction(SPISettings(500000, MSBFIRST, SPI_MODE2));
或者esp32没有根据通用规范来标识,查看esp32的底层驱动文件发现真是这样:

源文件名称:esp32-hal-spi.c

void spiSetDataMode(spi_t * spi, uint8_t dataMode)
{
    if(!spi) {
        return;
    }
    SPI_MUTEX_LOCK();
    switch (dataMode) {
    case SPI_MODE1:
        spi->dev->pin.ck_idle_edge = 0;
        spi->dev->user.ck_out_edge = 1;
        break;
    case SPI_MODE2:
        spi->dev->pin.ck_idle_edge = 1;
        spi->dev->user.ck_out_edge = 1;
        break;
    case SPI_MODE3:
        spi->dev->pin.ck_idle_edge = 1;
        spi->dev->user.ck_out_edge = 0;
        break;
    case SPI_MODE0:
    default:
        spi->dev->pin.ck_idle_edge = 0;
        spi->dev->user.ck_out_edge = 0;
        break;
    }
    SPI_MUTEX_UNLOCK();
}

原来esp32是用“SPI_MODE2”来代表:
CPOL=1, CPHA=1

至此真相大白,看来有时候必须追根问底才能得到真理。



参考资料:

【1】SPI四种模式区别   

【2】 linux spi驱动开发学习(三)-----spi_bitbang.c详解 

【3】 github源文件:arduino-esp32/cores/esp32/esp32-hal-spi.c

你可能感兴趣的:(esp32)