quarta-feira, 15 de junho de 2011

Comunicação SPI entre microcontroladores AVR:

Para este exemplo vou usar 2 microcontroladores ATmega8 comunicando entre si por meio do protocolo SPI. Usando o  AVRstudio(gratuito) . 
O circuito no simulador proteus :




Configurando os fuses:




O código fonte do slave:



 1:  //************************************************************************
   2:  //                             usando SPI
   3:  //  Version    : 1.0
   4:  //  microcontrolador : AVR ATMega8
   5:  //  Autor        : Aguivone
   6:  //  descrição  : modo slave - coloca dado recebido na saida do portd  
   7:  //  data : 14/06/2011.
   8:  //
   9:  ///////////////////////////////////////////////////////////////////////////////////////////////
  10:   
  11:  #define F_CPU 4000000UL           // clock do microcontrolador
  12:  #include <avr/io.h>
  13:  #include <avr/interrupt.h>
  14:  /////////////////////////////////configura registradores////////////////// 
  15:  #define MOSI     PINB3//entrada
  16:  #define MISO     PINB4//saida
  17:  #define SCK      PINB5//entrada
  18:  #define DDR_SPI  DDRB
  19:   
  20:  char enviar=0;
  21:   
  22:  ////////////////////////////////////////////////////////////// 
  23:  void SPI_Slave_inicializa(void)
  24:  {
  25:      DDR_SPI = (1<<MISO);
  26:      SPCR = (1<<SPE)/*|(1<<CPOL)*/|(1<<SPIE);      // habilita SPI / polaridade do clock / habilita interrupção de SPI 
  27:  }
  28:  ///////////////vetor de interrupção///////////////////////////////////
  29:  ISR (SPI_STC_vect)                         
  30:  {
  31:    SPDR = enviar;//envia dado anteriormente recebido
  32:    PORTD = SPDR;
  33:    enviar = SPDR;
  34:  }
  35:  /////////////////////////////////////função principal///////////////////////////////// 
  36:  int main(void) 
  37:  { 
  38:      SPI_Slave_inicializa();
  39:      DDRD = 0xFF;
  40:      sei();
  41:   
  42:          for (;;)
  43:          {
  44:           //faz nada 
  45:          }
  46:  }
  47:   

O código fonte do mestre:

   1:  //************************************************************************************************
   2:  //                             usando o protocolo SPI
   3:  //  Version    : 1.0
   4:  //  microcontrolador : AVR ATMega8
   5:  //  Autor        : Aguivone 
   6:  //  descrição  : envia dados e lê ao mesmo tempo
   7:  //  data : 14/06/11.
   8:  //
   9:  //para simular este exemplo basta ligar a saida serial com a entrada assim fica facil percerber que ele envia 
  10:  //e recebe ao mesmo tempo
  11:  //*************************************************************************************************
  12:   
  13:  #define F_CPU 4000000UL           // clock do microcontrolador
  14:  #include <avr\io.h>
  15:  #include <util/delay.h>
  16:  #include <avr/interrupt.h>
  17:   
  18:  /////////////////////////////configuração dos pinos utilizados //////////////////////////////////////
  19:   
  20:  #define MOSI         PB3
  21:  #define MISO         PB4
  22:  #define SCK          PB5
  23:  #define SS           PB2
  24:   
  25:  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  26:  void SPI_inicializa(void)
  27:  {
  28:      DDRD =0xFF;
  29:      DDRB |= ((1<<MOSI)|(1<<SCK)|(1<<SS));    //MOSI, SCK and SS são saidas(se for usar dois mestres então deve-se o SS como entrada) 
  30:      DDRB &= (~(1<<MISO));                    //MISO é entrada
  31:      PORTB |= (1<<SS);                        //inicia com SS em nivel alto
  32:      //SPE : habilita SPI
  33:      //MSTR: modo  Master 
  34:      //SPIE:  habilita interrupção de SPI
  35:      //SPCR = ((1<<SPE)|(1<<MSTR)|(1<SPR1)|(1<SPR0));    //(1<SPR1)|(1<SPR0) : FOSC/128
  36:      SPCR = ((1<<SPE)|(1<<MSTR)|(1<SPR0));    //(1<SPR0) : FOSC/16
  37:  }
  38:   
  39:  void SPI_envia_byte(char dados)
  40:  {
  41:      PORTB &= (~(1<<SS));    //coloca SS em nivel baixo (0), para transferir dados
  42:      SPDR = dados;        //inicializa transferencia
  43:      while(!(SPSR & (1<<SPIF)));    //espera fim de transmissão
  44:      PORTD = SPDR;//escreve no port D o dado recebido
  45:      PORTB |= (1<<SS);    //coloca SS em nivel alto (1), pois é o fim da transmissão.
  46:      _delay_ms(1);//tempo para slave colocar dados no registrador
  47:  }
  48:   
  49:  int main(void) 
  50:  {
  51:    
  52:    SPI_inicializa();//inicializa SPI
  53:    sei();//habilita interrupções
  54:   
  55:    while(1)
  56:     {
  57:      SPI_envia_byte(0X01);//envia primeiro dado
  58:      SPI_envia_byte(0X05);//envia segundo dado
  59:      SPI_envia_byte(0X09);//envia terceiro dado
  60:      SPI_envia_byte(0X30);//envia quarto dado
  61:      SPI_envia_byte(0X60);//envia quinto dado
  62:      }
  63:   
  64:    return 0;
  65:  }






Nenhum comentário :

Postar um comentário

olá,digite aqui seu comentário!