Introdução
O Serial Peripheral Interface (SPI) é um protocolo de comunicação serial síncrona amplamente utilizado para conectar microcontroladores a sensores, displays e chips de memória. Neste tutorial, vamos construir um teste de loopback SPI usando o simulador Velxio. O teste de loopback envia bytes via SPI e lê a resposta de volta, confirmando que o protocolo funciona corretamente. Como não há um dispositivo escravo físico, o simulador retorna o byte enviado, tornando esta uma maneira perfeita de aprender SPI sem nenhum hardware.
Passo a Passo do Circuito
Vamos começar configurando o circuito. O único componente que precisamos é um Arduino Uno, que colocaremos na tela.

Para adicionar o Arduino Uno, abra o seletor de componentes clicando no ícone ”+” na barra de ferramentas da tela.

Pesquise por “Arduino Uno” e coloque-o na tela. O Arduino Uno possui pinos SPI dedicados:
- MOSI (Master Out Slave In) – pino 11
- MISO (Master In Slave Out) – pino 12
- SCK (Serial Clock) – pino 13
- SS (Slave Select) – pino 10 (usaremos este como chip select)
Neste teste de loopback, não precisamos de nenhuma fiação externa, pois os sinais SPI são internos ao Arduino. No entanto, devemos garantir que o pino SS (pino 10) seja configurado como saída e acionado em nível alto inicialmente, depois em nível baixo durante a comunicação. O código cuida disso.
Passo a Passo do Código
Agora vamos examinar o código. Abra o editor de código clicando na aba “Code” na barra de ferramentas do editor.

O código é escrito em Arduino C++ e usa a biblioteca interna SPI.h. Nenhuma biblioteca externa é necessária.
// SPI Loopback Test
// Sends bytes via SPI and logs the exchange.
// Without a physical slave, the emulator returns the sent byte.
#include <SPI.h>
#define SS_PIN 10
void setup() {
Serial.begin(9600);
Serial.println("========================");
Serial.println(" SPI Protocol Test");
Serial.println("========================");
Serial.println();
pinMode(SS_PIN, OUTPUT);
digitalWrite(SS_PIN, HIGH);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV16);
Serial.println("SPI initialized.");
Serial.print("Clock divider: 16 (");
Serial.print(F_CPU / 16);
Serial.println(" Hz)");
Serial.println();
// Send test pattern
Serial.println("Sending test pattern via SPI:");
byte testData[] = {0xAA, 0x55, 0xFF, 0x00, 0x42, 0xDE, 0xAD, 0xBE};
digitalWrite(SS_PIN, LOW); // Select slave
for (int i = 0; i < sizeof(testData); i++) {
byte sent = testData[i];
byte received = SPI.transfer(sent);
Serial.print(" TX: 0x");
if (sent < 16) Serial.print("0");
Serial.print(sent, HEX);
Serial.print(" RX: 0x");
if (received < 16) Serial.print("0");
Serial.print(received, HEX);
if (sent == received) {
Serial.println(" (loopback OK)");
} else {
Serial.println();
}
}
digitalWrite(SS_PIN, HIGH); // Deselect slave
Serial.println();
Serial.println("SPI test complete.");
}
void loop() {
delay(1000);
}
Vamos detalhar as partes principais:
#include <SPI.h>: Inclui a biblioteca SPI do Arduino.#define SS_PIN 10: Define o pino de seleção do escravo como pino 10.setup(): Inicializa a comunicação serial a 9600 baud, define o pino SS como saída e o aciona em nível alto, depois chamaSPI.begin()para inicializar o periférico SPI. O divisor de clock é definido como 16, resultando em uma frequência de clock deF_CPU / 16(1 MHz para um Arduino de 16 MHz).- Padrão de teste: Um array de 8 bytes (
0xAA, 0x55, 0xFF, 0x00, 0x42, 0xDE, 0xAD, 0xBE) é enviado um por um. digitalWrite(SS_PIN, LOW): Seleciona o escravo (em loopback, isso é apenas um passo lógico).SPI.transfer(sent): Envia um byte e simultaneamente recebe um byte. Em loopback, o byte recebido é igual ao byte enviado.- Saída serial: Cada transmissão é impressa em formato hexadecimal e, se os bytes enviado e recebido coincidirem, “(loopback OK)” é anexado.
digitalWrite(SS_PIN, HIGH): Desseleciona o escravo após a transferência.loop(): Vazia, exceto por um atraso, pois o teste é executado apenas uma vez emsetup().
Conceitos Principais
- Protocolo SPI: SPI é um protocolo síncrono full-duplex com quatro fios: MOSI, MISO, SCK e SS. O mestre gera o clock e controla a seleção do escravo.
- Loopback: Conectar MOSI a MISO (ou usar um simulador que ecoa) permite testar o hardware SPI sem um escravo externo.
- Divisor de Clock: A função
SPI.setClockDivider()define a frequência do SCK em relação ao clock do sistema. Divisores mais baixos significam comunicação mais rápida. SPI.transfer(): Esta função envia e recebe um byte simultaneamente. É o núcleo da comunicação SPI.
Armadilhas Comuns e Dicas de Depuração
- Configuração do Pino SS: O pino SS deve ser configurado como saída; caso contrário, o hardware SPI pode mudar automaticamente para o modo escravo. Sempre defina
pinMode(SS_PIN, OUTPUT)e acione-o em nível alto quando ocioso. - Incompatibilidade de Baud Rate: Certifique-se de que o baud rate do Monitor Serial corresponda a
Serial.begin(9600). Na Velxio, o monitor serial abre automaticamente. - Polaridade e Fase do Clock: O modo SPI padrão (modo 0) usa SCK ocioso em nível baixo e dados amostrados na borda de subida. Se o seu escravo esperar um modo diferente, use
SPI.setDataMode(). - Sem Fiação Externa: Neste teste de loopback, nenhum fio é necessário. Se você estivesse conectando um escravo real, verifique as conexões: MOSI a MOSI, MISO a MISO, SCK a SCK e SS a SS.
Extensões Sugeridas
- Adicione um Escravo Externo: Simule um sensor ou display adicionando um segundo Arduino como escravo e escrevendo um sketch para escravo.
- Altere a Velocidade do Clock: Experimente com diferentes divisores de clock (por exemplo,
SPI_CLOCK_DIV2,SPI_CLOCK_DIV128) e observe o efeito na velocidade de transmissão. - Envie Dados Maiores: Modifique o padrão de teste para enviar uma string ou uma leitura de sensor.
- Use Interrupções: Implemente comunicação SPI com interrupções para transferências não bloqueantes.
Experimente Você Mesmo
Pronto para mergulhar? Abra o exemplo ao vivo na Velxio e execute a simulação. Você verá a saída serial mostrando cada byte transmitido e recebido, confirmando o loopback.
Abra o Teste de Loopback SPI na Velxio
Feliz simulação!