MicroPython – Protocolo SPI em ESP8266 e ESP32

MicroPython – Protocolo SPI em ESP8266 e ESP32

SPI e I2C são os protocolos de comunicação serial comuns usados ​​por sensores para comunicação com microcontroladores e microcomputadores. Ambos os protocolos são protocolos mestre-escravo. Os sensores muitas vezes fazem parte de um dispositivo escravo dentro de um ecossistema incorporado. Na maioria das vezes, um sensor requer apenas o envio de dados para o microcontrolador/microcomputador. Isto permanece verdadeiro mesmo se um determinado sensor estiver habilitado para interrupção.

Vários dispositivos embarcados incluem muitos sensores que requerem comunicação full-duplex com o controlador. Geralmente são sensores sofisticados e módulos embarcados com seu próprio conjunto de comandos explícitos e um escopo de configuração mais amplo ou aqueles capazes de transmitir uma ampla gama de dados variados. Esses sensores e módulos embarcados contam com o protocolo SPI full-duplex — que permite ao controlador trocar dados com vários dispositivos em um barramento comum — para comunicação de dados com o controlador. SPI também é um protocolo de comunicação síncrona que permite um link chip a chip de alta velocidade. A velocidade de dados no barramento SPI pode atingir no máximo 10 Mbps.

SPI vs. I2C
SPI significa Interface Periférica Serial. É um protocolo de comunicação serial full-duplex em contraste com o I2C, um protocolo serial half-duplex. Por full-duplex significa que o barramento SPI permite simultaneamente a transmissão e recepção de dados entre o controlador e o escravo. Existem linhas de dados separadas no barramento SPI para transferência de dados de controlador para controlador. Ao contrário disso, o I2C possui uma única linha de dados, portanto, de cada vez, qualquer um dos controladores pode enviar ou receber dados, mas não ambos. Enquanto o barramento I2C possui apenas duas linhas – uma linha de dados e uma linha de clock, um barramento SPI possui três ou quatro linhas. Existem duas linhas de dados, MISO (para transferência de dados do escravo para o controlador) e MOSI (para transferência de dados do controlador para o escravo), uma linha de clock SCK e uma linha de seleção de chip ou de seleção de escravo CS/SS. No protocolo I2C, vários escravos podem ser conectados a duas linhas onde os escravos são reconhecidos e selecionados para comunicação de dados usando um mecanismo de endereçamento. No SPI, se vários escravos estiverem conectados, a linha Chip Select será necessária. Cada escravo possui sua própria linha de seleção de chip. Isso aumenta o número de pinos de dados envolvidos no controlador à medida que mais dispositivos escravos são adicionados ao barramento SPI. Embora o protocolo I2C garanta a transmissão bem-sucedida de dados usando confirmações, o protocolo SPI não possui tal mecanismo. A transmissão de dados não é garantida no protocolo SPI.

Embora a exigência de linhas adicionais de seleção de chip e a falta de verificação de dados sejam as principais desvantagens do protocolo SPI. Tem muito a oferecer no cenário incorporado. Ele permite a comunicação de dados full-duplex em altas velocidades de até 10 Mbps. A velocidade de transmissão de dados no barramento I2C pode atingir no máximo 3,4 Mbps. O barramento SPI requer menos energia para comunicação de dados e é altamente eficiente para distâncias curtas. Se um bloco incorporado precisar ser integrado ao controlador, o SPI estará um pouco acima do I2C.

Módulo de máquina MicroPython
O módulo de máquina do MicroPython foi escrito para lidar com funções de hardware das portas suportadas. O módulo inclui classes para controlar entrada/saída digital, controlar sinais de saída de dispositivos externos, modulação por largura de pulso, conversão de analógico para digital, controlar periféricos ADC, UART, SPI, I2C, I2S, temporizador, RTC, temporizador Watchdog e gerenciamento de cartão SD . Possui a classe SPI para gerenciamento de hardware I2C e SoftSPI para implementação de software SPI nas portas suportadas.

Classe SPI
A classe SPI do módulo de máquina é responsável por implementar o protocolo SPI nas portas suportadas pelo MicroPython. O barramento SPI possui três linhas – MOSI, MISO e SCK. O protocolo síncrono requer uma linha CS adicional por escravo, desde que vários escravos estejam conectados ao barramento SPI. O sinal CS é gerenciado com a ajuda da classe PIN do módulo da máquina. SPI de hardware e software estão disponíveis no MicroPython. O SPI de hardware utiliza o periférico SPI subjacente das portas suportadas. Os pinos SPI na maioria das portas são fixos. Embora não seja tão eficiente, o software SPI pode ser aplicado a todos os pinos com capacidade de saída de uma porta. A classe SPI está incluída em um script MicroPython usando a instrução a seguir.
da importação da máquina SPI, Pin

Após importar a classe SPI e PIN, um objeto da classe SPI deve ser instanciado utilizando o método construtor. O método construtor da classe SPI possui o seguinte protótipo.
classe máquina.SPI(id,…)

Uma chamada ao método construtor requer essencialmente um argumento, o id. O id é a identificação do bloco SPI de hardware. Pode ser um número ou string dependendo da porta específica. Normalmente, os blocos SPI são identificados por números como 0, 1, 2, etc. Os outros argumentos que podem ser passados ​​em uma chamada ao método construtor são parâmetros de configuração. Os parâmetros de configuração definidos no método construtor incluem taxa de transmissão, polaridade, fase, bits, primeiro bit, sck, mosi, miso e pinos. A taxa de transmissão é a taxa de clock SCK. A taxa de transmissão máxima que pode ser definida depende da porta específica. A polaridade define o nível da linha de clock ociosa. Pode ser definido como 0 ou 1. A fase determina se os dados serão amostrados na primeira ou na segunda transição do clock. Se a fase for definida como 0, os dados serão amostrados na primeira transição do clock; se for definido como 1, os dados serão amostrados na segunda transição do clock. Firstbit determina se o primeiro bit nos dados é LSB ou MSB. Pode ser definido como SPI.LSB ou SPI.MSB. Algumas portas permitem pinos alternativos para MOSI, MISO e SCK. Os argumentos mosi, miso e sck definem os pinos MOSI, MISO e SCK, respectivamente, em tais portas. Se não for especificado, os pinos padrão MOSI, MISO e SCK serão definidos. O argumento pins só é permitido para a porta WiPy. Permite especificar uma tupla para definir os pinos MOSI, MISO e SCK. Alguns dos exemplos válidos de criação de objetos SPI são os seguintes.
spi = SPI(0)
spi = SPI(0, taxa de transmissão=400000)
hspi = SPI(1, 10000000)
hspi = SPI(1, 10000000, sck=Pino(14), mosi=Pino(13), miso=Pino(12))
vspi = SPI(2, taxa de transmissão=80000000, polaridade=0, fase=0, bits=8, primeiro bit=0, sck=Pino(18), mosi=Pino(23), miso=Pino(19))

Depois de criar um objeto SPI, ele pode ser inicializado usando o método SPI.init . Recebe os mesmos argumentos do método construtor, exceto o id. O método SPI.init possui o seguinte protótipo.
SPI.init(taxa de transmissão=1000000, *, polaridade=0, fase=0, bits=8, primeiro bit=SPI.MSB, sck=Nenhum, mosi=Nenhum, miso=Nenhum, pinos=(SCK, MOSI, MISO))

Os outros métodos disponíveis na classe SPI são os seguintes:

SPI.deinit : Este método desativa o barramento SPI.

SPI.read(nbytes, gravação=0x00): Este método lê o número de bytes nbytes ao escrever um único byte especificado pelo escrever argumento para a linha MOSI. Ele retorna um objeto byte contendo os bytes lidos da linha MISO.

SPI.readinto(buf, gravação=0x00): Este método lê bytes da linha MISO em um objeto buffer enquanto grava um único byte especificado pelo escrever argumento para a linha MOSI. Os bytes lidos são armazenados no objeto buffer. O número de bytes lidos depende do tamanho do objeto buffer. O método não retorna nada.

SPI.write(buf): Este método grava os bytes armazenados em um objeto buffer bufante para a linha MOSI. Não retorna nada.

SPI.write_readinto(write_buf, read_buf): Este método grava bytes de um objeto buffer escrever_buf para a linha MOSI e lê bytes em um objeto buffer read_buf. Ambos os objetos buffer podem ser iguais, mas devem ter o mesmo comprimento. O método não retorna nada. O número de bytes em escrever_buf são escritos no barramento e o número de bytes é igual ao comprimento do read_buf são lidos e armazenados no read_buf objeto.

Classe SoftSPI
O software SPI é implementado por bit-banging. A classe SoftSPI é importada em um script MicroPython usando a instrução a seguir.
do Pin de importação da máquina, SoftSPI

O SoftSPI possui todos os mesmos métodos da classe SPI de hardware. O método construtor do SoftSPI possui o seguinte protótipo.
class machine.SoftSPI(baudrate=500000, *, polarity=0, phase=0, bits=8, firstbit=MSB, sck=None, mosi=None, miso=None)

A seguir está um exemplo válido de instanciação de objeto SPI de software.
spi = SoftSPI(taxa de transmissão=100000, polaridade=1, fase=0, sck=Pino(0), mosi=Pino(2), miso=Pino(4))

SPI de hardware em ESP8266
Existem dois blocos SPI no ESP8266 – SPI0 e SPI1. O SPI0 permanece reservado para Flash ROM e não pode ser utilizado no programa do usuário. O SPI1 possui pinos MISO, MOSI e SCK fixados em GPIO12, GPIO13 e GPIO14 respectivamente.

Pinos SPI padrão no ESP8266

A frequência máxima do clock pode ser definida para 80 MHz. A seguir está um exemplo válido de criação de um objeto SPI de hardware no ESP8266.
da importação da máquina Pin, SPI
hspi = SPI(1, taxa de transmissão=80000000, polaridade=0, fase=0)

Software SPI em ESP8266
Software SPI é um dos dois drivers SPI disponíveis no ESP8266. O software SPI pode ser implementado em todos os pinos do ESP8266. A seguir está um exemplo válido de uso do software MicroPython SPI no ESP8266.
do Pin de importação da máquina, SoftSPI
spi = SoftSPI(taxa de transmissão=100000, polaridade=1, fase=0, sck=Pino(0), mosi=Pino(2), miso=Pino(4))
spi.init(taxa de transmissão=800000)
spi.read(3) # lê 3 bytes no MISO
spi.read(3, 0xff) # lê 3 bytes enquanto gera 0xff no MOSI
buf = bytearray(10) # objeto buffer
spi.readinto(buf) # lê 10 bytes no buffer fornecido
spi.readinto(buf, 0xff) # lê 10 bytes no buffer fornecido e gera 0xff no MOSI
spi.write(b'12345′) # grava o objeto buffer especificado no MOSI
buf = bytearray(5) # cria um buffer
spi.write_readinto(b'12345′, buf) # escreve no MOSI e lê do MISO no buffer

spi.write_readinto(buf, buf) # escreve buf no MOSI e lê o MISO de volta no buf

SPI de hardware no ESP32
Existem dois blocos SPI de hardware no ESP32 – HSPI (SPI1) e VSPI (SPI2). Os pinos padrão para MOSI, MISO e SCK do HSPI são GPIO13, GPIO12 e GPIO14, respectivamente. Os pinos padrão para MOSI, MISO e SCK do VSPI são GPIO23, GPIO19 e GPIO18, respectivamente. A frequência máxima do clock SPI pode ser de 80 MHz nos pinos padrão. ESP32 permite multiplexação GPIO dos blocos SPI de hardware, desde que os pinos sejam habilitados para entrada ou saída de acordo com os requisitos da linha SPI. No entanto, a frequência máxima do clock SPI em pinos multiplexados pode ser de apenas 40 MHz.

Pinos SPI padrão no ESP32

A seguir está um exemplo válido de criação de um objeto SPI de hardware no ESP32.
da importação da máquina Pin, SPI
hspi = SPI(1, 80000000)
hspi = SPI(1, 40000000, sck=Pino(14), mosi=Pino(13), miso=Pino(12))
vspi = SPI(2, taxa de transmissão=80000000, polaridade=0, fase=0, bits=8, primeiro bit=0, sck=Pino(18), mosi=Pino(23), miso=Pino(19))

SPI de software em ESP32
O software SPI está disponível em todos os pinos do ESP32. A frequência máxima de clock do software SPI pode ser de 40 MHz. A seguir está um exemplo válido de software SPI no ESP32.
do Pin de importação da máquina, SoftSPI
spi = SoftSPI(taxa de transmissão=100000, polaridade=1, fase=0, sck=Pino(0), mosi=Pino(2), miso=Pino(4))
spi.init(taxa de transmissão=800000)
spi.read(3) # lê 3 bytes no MISO
spi.read(3, 0xff) # lê 3 bytes enquanto gera 0xff no MOSI
buf = bytearray(10) # objeto buffer
spi.readinto(buf) # lê 10 bytes no buffer fornecido
spi.readinto(buf, 0xff) # lê 10 bytes no buffer fornecido e gera 0xff no MOSI
spi.write(b'12345′) # grava o objeto buffer especificado no MOSI
buf = bytearray(5) # cria um buffer
spi.write_readinto(b'12345′, buf) # escreve no MOSI e lê do MISO no buffer
spi.write_readinto(buf, buf) # escreve buf no MOSI e lê o MISO de volta no buf

Alguns exemplos de SPI
Alguns dos bons exemplos de uso da classe MicroPython SPI podem ser encontrados nos projetos a seguir.

  1. Projeto – MicroPython SSD1351 do autor rdagger
  2. Projeto – MicroPython nanoGUI do autor peterhinch
  3. Projeto – uPySensors do autor lemariva
  4. Projeto – uble do autor dmazzella

Confira os projetos incorporados acima e explore seu código-fonte para saber como a classe SPI do módulo de máquina MicroPython é usada.

Voltar para o blog

Deixe um comentário

Os comentários precisam ser aprovados antes da publicação.