乐鑫技术交流
直播中

贺楠

7年用户 972经验值
私信 关注
[问答]

ESP-WROOM-02 SPI配置不能作为从机工作要怎么处理?

我尝试将具有 ESP8266 内核的 ESP-wroom-02 配置为 SPI 从设备。但是除了技术参考 ESP8266 之外,没有找到太多关于 SPI 配置的信息。该项目有一个 arduino nano iot 33 (samd21g18 arm-m0) 作为与 Slave ESP8266 通信的主机。
我用逻辑分析仪检查了主机发送数据和时钟,但从机没有响应。我还测试了使用 arduino uno 作为从站,并与 arduino iot SPI Master 一起工作。
引脚设置:
- 在 ESP 上:IO14->SCK、IO12->MISO、IO13->MOSI、IO15->CS
- 在 Arduino 上:D12->MISO、D13->SCK、D11->MOSI、D10->CS
从代码:
主例程
代码:全选#include "hspiESP8266.h"
#include
using namespace std;

#define MISO 12
#define MOSI 13

extern uint8_t bdata[LENGTH];
char c = 'c';
bdata[0] = (uint8_t)c;
void setup() {
  Serial.begin(115200);
  
  pinMode(MISO, OUTPUT);
  pinMode(MOSI, INPUT);

  HSPISlave SPIS;

  attachInterrupt(digitalPinToInterrupt(SYNC), sync_isr, FALLING);
  SPIS.begin();



  
}

void loop() {

  delay(100);
Serial.println((data[0] << 16));               
}


头文件
代码:全选#include "hspiESP8266.h"


         
volatile bool data_ready = false;   // set by HSPI interrupt handler when data is received
volatile bool new_readings = false; // set by sync pin interrupt when readings are extracted from raw data

CACHE_RAM_ATTR sync_isr();
void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *);



uint8_t bdata[LENGTH];

uint8_t* read_hspi(){

   return bdata;
}


void ICACHE_RAM_ATTR _hspi_slave_isr_handler(void *) {
    uint32_t istatus = SPIIR;
    if(istatus & (1 << SPII1)) {      //SPI1 ISR
        uint32_t status = SPI1S;
        SPI1S &= ~(0x3E0);            //disable interrupts
        SPI1S |= SPISSRES;            //reset
        SPI1S &= ~(0x1F);             //clear interrupts
        SPI1S |= (0x3E0);             //enable interrupts

        if(status & SPISWBIS) {
            uint8_t *p = bdata;
            for(int i = 0; i < LENGTH / 4; i++) {
                uint32_t dword = SPI1W(i);
                *p++ = dword;
                *p++ = dword >> 8;
                *p++ = dword >> 16;
                *p++ = dword >> 24;
            }
            data_ready = true;
        }
    } else if(istatus & (1 << SPII0)) { //SPI0 ISR
        SPI0S &= ~(0x3ff);//clear SPI ISR
    } else if(istatus & (1 << SPII2)) {} //I2S ISR
}



void ICACHE_RAM_ATTR sync_isr() {                           // Sync pin interrupt on falling edge
  SPI1S |= SPISSRES;                                        // Reset HSPI slave
  SPI1S &= ~SPISSRES;
  SPI1CMD = SPICMDUSR;                                      // Start HSPI slave
  static bool glitch = false;
  if(data_ready) {                                          // If a data has been received by the HSPI
    data_ready = false;
      
    if( glitch) {                 // reject samples that have been shifted right by noise on the clock line?
      glitch = false;                                       // sample accepted
      new_readings = true;                                  // new raw readings ready
    }
    else
      glitch = true;                                        // only reject one sample
  }
}





//contructor
HSPISlave::HSPISlave(){

}

void HSPISlave::begin(){
   pinMode(SCK, SPECIAL);                  // Both inputs in slave mode
    pinMode(MOSI, SPECIAL);
    SPI1C = 0;                              // SPI_CTRL_REG MSB first, single bit data mode.
    SPI1S = SPISE | SPISBE | SPISCD | 0x3E0;// SPI_SLAVE_REG, set slave mode, WR/RD BUF enable, CMD define, enable interrupts
    SPI1U = SPIUSSE;                        // SPI_USER_REG.  SPI_CK_I_EDGE
    SPI1CLK = 0;                            // SPI_CLOCK_REG
    SPI1U1 = 7 << SPILADDR;                 // SPI_USER1_REG, set address LENGTH to 8 bits
    SPI1U2 = 7 << SPILCOMMAND;              // SPI_USER2_REG, set command LENGTH to 8 bits
    SPI1S1 = (LENGTH * 8 - 1) << SPIS1LBUF; // SPI_SLAVE1_REG, SPI_SLV_BUF_BITLEN = 12 bytes
    SPI1S3 = 0xF1F200F3;                    // SPI_SLAVE3_REG,, Define command 0 to be write buffer, others something doesn't match
    SPI1P = 1 << 19;                        // SPI_PIN_REG, Clock idle high, seems to cause contension on the clock pin if set to idle low.
    ETS_SPI_INTR_ATTACH(_hspi_slave_isr_handler, 0);
    ETS_SPI_INTR_ENABLE();

}

void HSPISlave::end(){
       SPI1S |= SPISSRES;
    SPI1CMD = 0;
    pinMode(SCK, INPUT);                  // Return to inputs to avoid glicthing the PZEM-021 during reset
    pinMode(MOSI, INPUT);

}

void HSPISlave::INTreset(){

   SPI1S &= ~(0x3E0);            //disable interrupts
    SPI1S |= SPISSRES;            //reset
    SPI1S &= ~(0x1F);             //clear interrupts
    SPI1S |= (0x3E0);             //enable interrupts

}

void HSPISlave::reset(){

  SPI1S |= SPISSRES;                                        // Reset HSPI slave
  SPI1S &= ~SPISSRES;
  SPI1CMD = SPICMDUSR;                                      // Start HSPI slave
   
}

更多回帖

发帖
×
20
完善资料,
赚取积分