PORTA SPI
PORTA SPI
Tem como conectar dois módulo que usa por SPI usando a mesma porta do esp32 ou tem que usar o C.I de expansor de porta??
-
- Experiente
- Mensagens: 41
- Registrado em: 05/Jun/2018, 15:52
Re: PORTA SPI
Nunca usei expansor de porta pra isso..
Se seu projeto não for muito exigente quanto a desempenho, você pode usar hora um componente SPI e hora outro.
Você pode utilizar as mesmas portas SCK, MISO, MOSI e CS. Não use as mesmas portas RST, SDA.
Se não me engano, o ESP32 possui portas suficientes para que 2 componentes SPI sejam conectados, porém estou te enviando um pseudo-código que desconsidera essa possibilidade, considerando apenas uma comunicação SPI disponível e que será usada por mais de um componente SPI. Nada impede que você altere as portas dos defines abaixo.
Segue exemplo de um código com 2 sensores RFID RC522, lembrando que poderiam ser componentes diferentes:
// ################################## INÍCIO DO CÓDIGO ##################################
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
// Pinos spi correspondentes ao componente A
#define SDA_A 0
#define RST_A 0
// Pinos spi correspondentes ao spi do componente A
#define SCK_A 0
#define MISO_A 0
#define MOSI_A 0
#define CS_A 0
// Pinos spi correspondentes ao componente B
#define SDA_B 0
#define RST_B 0
// Pinos spi correspondentes ao spi do componente B
#define SCK_B 0
#define MISO_B 0
#define MOSI_B 0
#define CS_B 0
MFRC522 componente_A(SDA_A, RST_A);
MFRC522 componente_B(SDA_B, RST_B);
// Esse trecho de código foi retirado de um projeto cujo código possui mais de uma task que acessa a função "spi_select"
// Por isso declaramos a flag abaixo para controlar os possíveis múltiplos acessos e evitar erros
bool flagSPIBusy = false;
int current_spi = -1;
// current_spi = 1 para componente A
// current_spi = 2 para componente B
// Função que alterna a comunicação SPI para o componente A ou B
// spiToBegin = 1 para componente A
// spiToBegin = 2 para componente B
bool spi_select(int spiToBegin)
{
// Verificamos se o SPI está ocupado
if(!flagSPIBusy)
{
// Se o SPI atual já é o desejado não precisamos reiniciá-lo, então abortamos a função
if (spiToBegin == current_spi)
return true;
// Setamos a flag como true para evitar erros de multiplos acessos à essa função
flagSPIBusy = true;
// Comparamos qual é o SPI que será utilizado
// E iniciamos o SPI correspondente
switch(spiToBegin)
{
case 0:
SPI.end();
SPI.begin(SCK_A, MISO_A, MOSI_A, CS_A);
// chame aqui a inicialização do componente A, por exemplo:
// componenteA.init();
break;
case 1:
SPI.end();
SPI.begin(SCK_B, MISO_B, MOSI_B, CS_B);
// chame aqui a inicialização do componente B, por exemplo:
// componente_B.init();
break;
}
// Atribuímos o SPI atual para nossa variável global
current_spi = spiToBegin;
// Voltamos a flag como false para podermos chamar esta função novamente
flagSPIBusy = false;
return true;
}
// Se essa função que configura o SPI está ocupada, retornamos false
return false;
}
void setup()
{
// Você pode chamar a função diretamente
// spi_select(0);
spi_select(1);
// Ou dentro de um loop, que aguarda até que o SPI desejado seja realmente setado (mais recomendado)
while(!spi_select(1))
{
delay(100);
}
}
void loop() { }
// ################################## FIM DO CÓDIGO ##################################
Pode haver formas diferentes de conectar os módulos, mas essa é uma possibilidade.
Se seu projeto não for muito exigente quanto a desempenho, você pode usar hora um componente SPI e hora outro.
Você pode utilizar as mesmas portas SCK, MISO, MOSI e CS. Não use as mesmas portas RST, SDA.
Se não me engano, o ESP32 possui portas suficientes para que 2 componentes SPI sejam conectados, porém estou te enviando um pseudo-código que desconsidera essa possibilidade, considerando apenas uma comunicação SPI disponível e que será usada por mais de um componente SPI. Nada impede que você altere as portas dos defines abaixo.
Segue exemplo de um código com 2 sensores RFID RC522, lembrando que poderiam ser componentes diferentes:
// ################################## INÍCIO DO CÓDIGO ##################################
#include <Arduino.h>
#include <SPI.h>
#include <MFRC522.h>
// Pinos spi correspondentes ao componente A
#define SDA_A 0
#define RST_A 0
// Pinos spi correspondentes ao spi do componente A
#define SCK_A 0
#define MISO_A 0
#define MOSI_A 0
#define CS_A 0
// Pinos spi correspondentes ao componente B
#define SDA_B 0
#define RST_B 0
// Pinos spi correspondentes ao spi do componente B
#define SCK_B 0
#define MISO_B 0
#define MOSI_B 0
#define CS_B 0
MFRC522 componente_A(SDA_A, RST_A);
MFRC522 componente_B(SDA_B, RST_B);
// Esse trecho de código foi retirado de um projeto cujo código possui mais de uma task que acessa a função "spi_select"
// Por isso declaramos a flag abaixo para controlar os possíveis múltiplos acessos e evitar erros
bool flagSPIBusy = false;
int current_spi = -1;
// current_spi = 1 para componente A
// current_spi = 2 para componente B
// Função que alterna a comunicação SPI para o componente A ou B
// spiToBegin = 1 para componente A
// spiToBegin = 2 para componente B
bool spi_select(int spiToBegin)
{
// Verificamos se o SPI está ocupado
if(!flagSPIBusy)
{
// Se o SPI atual já é o desejado não precisamos reiniciá-lo, então abortamos a função
if (spiToBegin == current_spi)
return true;
// Setamos a flag como true para evitar erros de multiplos acessos à essa função
flagSPIBusy = true;
// Comparamos qual é o SPI que será utilizado
// E iniciamos o SPI correspondente
switch(spiToBegin)
{
case 0:
SPI.end();
SPI.begin(SCK_A, MISO_A, MOSI_A, CS_A);
// chame aqui a inicialização do componente A, por exemplo:
// componenteA.init();
break;
case 1:
SPI.end();
SPI.begin(SCK_B, MISO_B, MOSI_B, CS_B);
// chame aqui a inicialização do componente B, por exemplo:
// componente_B.init();
break;
}
// Atribuímos o SPI atual para nossa variável global
current_spi = spiToBegin;
// Voltamos a flag como false para podermos chamar esta função novamente
flagSPIBusy = false;
return true;
}
// Se essa função que configura o SPI está ocupada, retornamos false
return false;
}
void setup()
{
// Você pode chamar a função diretamente
// spi_select(0);
spi_select(1);
// Ou dentro de um loop, que aguarda até que o SPI desejado seja realmente setado (mais recomendado)
while(!spi_select(1))
{
delay(100);
}
}
void loop() { }
// ################################## FIM DO CÓDIGO ##################################
Pode haver formas diferentes de conectar os módulos, mas essa é uma possibilidade.