HOME      PROJETOS      PROGRAMAÇÃO     

Comunicação usando a interface SPI do módulo MSSP


Alguns microcontroladores PIC, como 16F73, 16F877A, 18F4520, 18F4550, 18F4620 e outros, possuem o módulo MSSP ou SSP, sigla que significa "Master Synchronous Serial Port", uma interface serial sincrona de 8 bits que serve para a comunicação com outros periféricos ou outros microcontroladores. Conforme o data sheet dos microcontroladores que possuem esse módulo, alguns dispositivos externos que usam essa interface de comunicação podem ser memórias EEPROM, shift registers, displays e conversores analógico/digitais.

O módulo MSSP pode se comunicar nos modos I2C (Inter-Integrated Circuit) ou SPI (Serial Peripheral Interface). Veremos aqui somente o modo SPI que é a mais simples de todas.

Basicamente, o modo SPI usa tres fios ou sinais para fazer a comunicação entre dois dispositivo que são:

  • SDI - entrada de dados
  • SDO - a saída de dados
  • SCK - clock da interface


FIGURA 1 - Conexões entre dispositivos SPI



Como se pode observar na figura 1, retirada do data sheet o microcontrolador PIC18F4520, os tres sinais são usados tanto no MASTER como no SLAVE, sendo que o sinal SDI do MASTER deve ser conectado ao SDO do SLAVE, o SDI do SLAVE ao SDO do MASTER e os sinais SCK, tanto do MASTER como do SLAVE, devem ser conectados entre si.

Além dos sinais descritos acima, o dispositivo SLAVE poderá usar um quarto sinal conhecido como SS ou Slave Select que permite ao MASTER selecionar qual dispositivo SLAVE esta sendo endereçado para a comunicação. Esse sinal é útil quando o MASTER necessita se comunicar com vários SLAVES. Normalmente, quando só existe um SLAVE no circuito, não é necessário usar esse sinal. O sinal SS, quando usado, deverá ter nível baixo para o dispositivo SLAVE selecionado e nível alto para dispositivos SLAVEs não selecionados.

A primeira regra para operar no modo SPI é que, apenas um dos dispositivos funcionará como MASTER enquanto o outro funcionará como SLAVE. É necessário citar que mais de um escravo pode participar do circuito mas, para selecionar qual deles deve se comunicar com o MASTER, o software deve manter controle sobre os sinais de seleção SS já citado acima.

Outra regra fundamental, que se aplica ao modo SPI, é que uma comunicação é sempre iniciada e mantida pelo MASTER. Um dispositivo SLAVE nunca inicia uma comunicação.




REGISTRADORES ENVOLVIDOS NO MODO SPI

Tres registradores são usados para configurar e operar o modo SPI:

  1. O registrador SSPSTAT que pode ser visto na figura 2.

  2. O registrador SSPCON1 na figura 3.

  3. O registrador SSPBUF onde o dado é colocado para ser transmitido ou onde o dado é recebido.



O registrador SSPSTAT

No registrador SSPSTAT temos apenas tres bits de interesse:

  1. O bit SMP que, em modo SLAVE não é usado mas que em modo MASTER configura em que ponto do sinal de clock SCK o dado deve ser obtido; no meio do sinal (SMP=0) ou no fim do sinal (SMP=1).

  2. O bit CKE indica, nos dois modos (MASTER e SLAVE), quando a transmissão/recepção deve ocorrer, isto é, na transição de clock Idle-->Act ou Act-->Idle (ver bit CKP do registrador SSPCON1).

  3. O bit BF que indica que o buffer esta completo após uma transmissão/recepção.



FIGURA 2 - Registrador SSPSTAT





O registrador SSPCON1

O registrador SSPCON1 configura outras características no modo SPI e os bits de interesse são:

  1. O bit SSPEN que liga e desliga o módulo SSP.

  2. O bit CKP que define a polaridade do clock. Se CKP=0 o Idle state será nível baixo e se CKP=1 o Idle state será nível alto.

  3. Os bits SSPM3 a SSPM0 configuram o dispositivo em modo MASTER em suas diversas modalidades de clock e o modo SLAVE com ou sem o sinal de seleção SS (ver figura 3).



  4. FIGURA 3 - Registrador SSPCON1





    Tabela Resumo com Opções de Configuração para os Registradores SSPSTAT e SSPCON1

    A tabela abaixo mostra como devem ser escolhidos os valores de configuração desses registradores dependendo do tipo de dispositivo que esta sendo programado (Master ou Slave).

     REGISTRADOR   BIT   M A S T E R   S L A V E   D E S C R I Ç Ã O 
     SSPSTAT   SMP   0,1   sempre 0   Amostragem no meio ou no fim do tempo 
     CKE   0,1   0,1   Amostragem de Idle-->Act ou Act-->/Idle 
     SSPCON1   WCOL   0   0   Sem colisão 
     SSPOV   0   0   Sem overflow 
     SSPEN   0,1   0,1   Habilita/Desabilita módulo SPI 
     CKP   0,1   0,1   Clock Idle Low/High 
     SSPM3   0000 - Fosc/4    0100 - com SS   Esses bits definem o modo 
     Master ou Slave 
     SSPM2   0001 - Fosc/16   0101 - sem SS  
     SSPM1   0010 - Fosc/64    -  
     SSPM0   0011 - TMR2    -  

    Observar que os bits SSPSTAT<CKE> e SSPCON1<CKP> sempres devem ser configurados com as mesmas características tanto no MASTER como no SLAVE.







    C O M O    F U N C I O N A

    O mecanismo de comunicação é bem simples conforme mostra a figura 1. Toda vez que o MASTER coloca um byte no registrador SSPBUF, esse byte será automaticamente enviado pela porta SDO, através do shift register SSPSR, começando pelo MSB e recebido no SLAVE pela porta SDI. O sinal de clock SCK é controlado pelo MASTER.

    Antes de iniciar uma transferência o MASTER deve, em primeiro lugar, deixar o sinal SCK no seu estado IDLE, isto é, se o bit SSPCON1<CKP> foi configurado com o valor 0, o sinal SCK deverá ser baixo, caso contrário deverá ser alto. O dispositivo MASTER inicia a transmissão colocando um byte no registrador SSPBUF e, em seguida verifica se o bit PIR1<SSPIF> foi ligado indicando uma resposta do SLAVE. Verifica, também, se o bit SSPSTAT<BF> foi ligado indicando que o registrador SSPBUF contem um dado completo. Se essas condições forem verificadas, então a operação terminou com sucesso.

    Uma vez configurado e habilitado no modo SPI, o dispositivo SLAVE deve permanecer verificando o bit SSPSTAT<BF> para saber se um byte chegou. O SLAVE pode, também, usar a interrupção do módulo SSP para executar a mesma função. Cada bit recebido pelo SLAVE na porta SDI entrará no registrador SSPSR pelo LSB. O SLAVE, então, "empurrará" de volta ao MASTER, o bit MSB contido no seu próprio registrador SSPSR antes da comunicação ser iniciada. Quando os 8 bits forem recebidos, o conteúdo do registrador SSPSR será copiado para o registrador SSPBUF e os bits PIR1<SSPIF> e SSPSTAT<BF> serão ligados e o dispositivo poderá retirar o dado do registrador SSPBUF.

    Em ambos os dispositivos, o bit SSPSTAT<BF> é desligado assim que o registrador SSPBUF é lido por uma instrução como movf    SSPBUF,w    mas o bit PIR1<SSPIF> deve ser desligado pelo software.





    EXEMPLOS PRÁTICOS

    Abaixo vemos dois exemplos escritos em linguagem assembler para configurar e usar os dispositivos MASTER e SLAVE em dois microcontroladores PIC18F4620. Os microcontroladores podem ser substituidos à vontade por qualquer outro da família 18F em que os pinos de I/O do módulo SSP estejam no PORTC. Digo isso porque no chip PIC18F4550 esses pino estão em portas diferentes. Para compilar os programas para outros microcontroladores basta substituir seus nomes nas diretivas abaixo:

    LIST P=18F4620 #include <P18F4620.INC>

    Para fazê-los funcionar, monte o circuito de teste do arquivo "schematic.png" e baixe os arquivos necessários seguindo as instruções fornecidas em cada exemplo. Apesar dos microcontroladores mostrados no esquema serem PIC18F4520 não há diferença de pinagem para o PIC18F4620 sendo que o circuito pode ser montado tranquilamente para esse microcontrolador. Os microcontroladores podem usar cristais de até 20MHz.



    EXEMPLO 1 - PROGRAMA NO DISPOSITIVO MASTER

    Baixe o código fonte que se encontra no arquivo "spi_master.asm" para poder alterá-lo se assim desejar. Se preferir, grave o arquivo "spimstrsimp.hex" diretamente no dispositivo MASTER.

    ; --------------------------------------------------------------------------------------------- ; COMUNICACAO SIMPLES ENTRE DOIS PIC18F4620 USANDO A INTERFACE SPI ; ; PROGRAMA PARA O DISPOSITIVO MASTER ; ; Este programa envia bytes ao dispositivo SLAVE que mostrara os dados nos LEDs do PORTB. ; ; O hardware para o circuito teste pode ser visto no arquivo "schematic.png" no diretorio ; deste projeto. ; ; --------------------------------------------------------------------------------------------- LIST P=18F4620 #include <P18F4620.INC> ; --------------------------------------------------------------------------------------------- ; CONFIGURATION BITS ou FUSES ; --------------------------------------------------------------------------------------------- CONFIG WDT = OFF CONFIG MCLRE = ON CONFIG debug = OFF CONFIG LVP = OFF CONFIG OSC = HS ; oscilador a cristal externo 20MHZ ; --------------------------------------------------------------------------------------------- ; REGISTRADORES E SIMBOLOS NA MEMORIA DE DADOS ; --------------------------------------------------------------------------------------------- UDATA 0x80 ; RAM do sistema delay_temp RES 1 ; registrador da subrotina de delay contador RES 1 ; contador R1 RES 1 ; registrador auxiliar ; #define SPI_TRIS TRISC ; I/O do PORTC #define SPI_PORT PORTC ; PORTC contem os bits SCK, SDI e SDO #define SPI_SCK 3 ; bit SCK -- CLock no Master sera saida #define SPI_SDI 4 ; bit SDI -- Entrada serial #define SPI_SDO 5 ; bit SDO -- Saida serial ; --------------------------------------------------------------------------------------------- ; Vetores de interrupcao ; --------------------------------------------------------------------------------------------- rstvec CODE 0x0000 goto inicio inth CODE 0x0008 retfie ; --------------------------------------------------------------------------------------------- ; Inicio ; --------------------------------------------------------------------------------------------- MAIN CODE inicio movlw 0x00 ; W=0 movwf SPI_PORT ; SPI_PORT=0 movlw b'11010111' ; mascara de I/O SCK=saida, SDI=entrada e SDO=saida movwf SPI_TRIS ; configura I/O bsf SPI_PORT,SPI_SCK ; mantem o clock em Idle state (high) clrf SSPSTAT ; amostragem no meio do tempo (SMP) e Idle--->Act (CKE) movlw 0x31 ; habilita SSPI, IDLE state high e Fosc/16 movwf SSPCON1 ; configura SPI como master clrf contador ; zera o contador sendcnt movf contador,w ; byte a enviar movwf SSPBUF ; envia o contador loop1 btfss PIR1,SSPIF ; o SLAVE respondeu? goto loop1 ; NAO... espera responder loop2 btfss SSPSTAT,BF ; o buffer esta completo? goto loop2 ; NAO... espera completar movf SSPBUF,w ; le a resposta do SLAVE zerando o bit SSPSTAT<BF> bcf PIR1,SSPIF ; limpa o flag incfsz contador,f ; decrementa o contador movlw .250 ; milisegundos call tempo ; tempo... goto sendcnt ; vai enviar ; --------------------------------------------------------------------------------------------- ; Subrotina de retardo ; --------------------------------------------------------------------------------------------- tempo movlw .250 movwf delay_temp t1 call wastetme decfsz delay_temp,f goto t1 return ; wastetme movlw .50 ; 200ns movwf R1 ; 200ns waste01 goto $+2 ; 400ns goto $+2 ; 400ns goto $+2 ; 400ns goto $+2 ; 400ns goto $+2 ; 400ns goto $+2 ; 400ns goto $+2 ; 400ns decfsz R1,f ; 200ns goto waste01 ; 400ns return ; 400ns END





    EXEMPLO 2 - PROGRAMA NO DISPOSITIVO SLAVE

    Baixe o código fonte que se encontra no arquivo "spi_slave.asm" para poder alterá-lo se assim desejar. Se preferir, grave o arquivo "spislvsimp.hex" diretamente no dispositivo SLAVE.

    ; --------------------------------------------------------------------------------------------- ; COMUNICACAO SIMPLES ENTRE DOIS PIC18F4620 USANDO A INTERFACE SPI ; ; PROGRAMA PARA O DISPOSITIVO SLAVE ; ; Este programa recebe bytes ao dispositivo Master e os mostra nos LEDs conectados ao PORTB. ; ; O hardware para o circuito teste pode ser visto no arquivo "schematic.png" no diretorio ; deste projeto. ; ; --------------------------------------------------------------------------------------------- LIST P=18F4620 #include <P18F4620.INC> ; --------------------------------------------------------------------------------------------- ; CONFIGURATION BITS ; --------------------------------------------------------------------------------------------- CONFIG WDT = OFF CONFIG MCLRE = ON CONFIG debug = OFF CONFIG LVP = OFF CONFIG OSC = HS ; oscilador a cristal externo 20MHZ ; --------------------------------------------------------------------------------------------- ; REGISTRADORES E SIMBOLOS ; --------------------------------------------------------------------------------------------- UDATA 0x80 ; RAM do sistema #define SPI_TRIS TRISC ; I/O do PORTC #define SPI_PORT PORTC ; PORTC contem os bits SCK, SDI e SDO #define SPI_SCK 3 ; bit SCK -- CLock no Slave sera entrada #define SPI_SDI 4 ; bit SDI -- Entrada serial #define SPI_SDO 5 ; bit SDO -- Saida serial ; --------------------------------------------------------------------------------------------- ; Vetores de interrupcao ; --------------------------------------------------------------------------------------------- rstvec CODE 0x0000 goto inicio inth CODE 0x0008 retfie ; --------------------------------------------------------------------------------------------- ; Inicio ; --------------------------------------------------------------------------------------------- MAIN CODE inicio clrf PORTB ; PORTB=0 clrf TRISB ; I/O do PORTB --> tudo saida movlw 0x00 ; W=0 movwf SPI_PORT ; SPI_PORT=0 movlw b'11011111' ; mascara de I/O SCK=entrada, SDI=entrada e SDO=saida movwf SPI_TRIS ; configura I/O clrf SSPSTAT ; SMP sempre zero e amostragem Idle-->Act (CKE) movlw 0x35 ; habilita SPI, IDLE state high e modo slave sem SS movwf SSPCON1 ; configura SPI como slave bcf PIR1,SSPIF ; limpa o flag loop1 btfss PIR1,SSPIF ; chegou um byte do MASTER? goto loop1 ; NAO --> espera chegar um byte loop2 btfss SSPSTAT,BF ; o buffer esta completo? goto loop2 ; NAO --> espera completar movf SSPBUF,w ; SIM --> le o byte recem chegado zerando o bit SSPSTAT<BF> movwf PORTB ; mostra nos LEDs bcf PIR1,SSPIF ; limpa o flag goto loop1 ; vai receber o proximo... END





    C O N C L U S Ã O

    A interface SPI com certeza é muito simples de usar porém, para permitir segurança na troca de dados entre os dispositivos, o programador deve desenvolver um tipo de protocolo para saber se os dados realmente chegaram onde deviam. Quando se trabalha com dispositivos como, por exemplo, cartões de memória SD Card que possuem um protocolo próprio, deve-se ler o data sheet do dispositivo para saber como este responde aos comandos enviados pelo MASTER. Assim, cada dispositivo externo tem seu próprio protocolo que deve ser estudado antes de começar a programar. Além disso, aqui não foi estudado o assunto sobre interrupções do módulo MSSP. Isso deixaremos para uma próxima ocasião ou você pode tentar por si mesmo.

    Bons estudos...

    H P S P I N

    Desde 04 de Março de 2010

    Atualização: 19 de Apr de 2024