title: How to correctly send more than one string using SPI
body: <p>I am trying to communicate between two <em>ATmega</em> using <a href="https://en.wikipedia.org/wiki/Serial_Peripheral_Interface" rel="nofollow noreferrer">SPI</a>. First, I initialized SPI for both ATmega. Here ATmega8 is <strong>master</strong> and ATmega32 is <strong>slave</strong>.  </p>
  
  <hr>
  
  <p><strong>MASTER</strong></p>
  
  <p>Master initialization - ATMEGA8:</p>
  
  <pre><code>#define SPI_ddr             DDRB
  #define SPI_port            PORTB
  #define PIN_sck             5
  #define PIN_mosi            3
  #define PIN_ss              2
  #define PIN_miso            4
  
  #define SPI_PORT_enable()   (SPI_ddr |= (1 &lt;&lt; PIN_sck) | (1 &lt;&lt; PIN_mosi) | (1 &lt;&lt; PIN_ss))
  #define CS_High             SPI_port |= (1 &lt;&lt; PIN_ss);
  #define CS_Low              SPI_port &amp;= ~(1 &lt;&lt; PIN_ss);
  
  void SPI_Init()
  {
      SPI_PORT_enable();
      SPI_ddr &amp;= ~(1 &lt;&lt; PIN_miso);
      SPCR |= (1 &lt;&lt; MSTR) | (1 &lt;&lt; SPR0) | (1 &lt;&lt; SPR1) | (1 &lt;&lt;SPE);
  }
  </code></pre>
  
  <hr>
  
  <p>Functions to send data from master - ATMEGA8:</p>
  
  <pre><code>void send_char_SPI(char c)
  {
      SPDR = c;
      /* Wait for transmission complete */
      while(!(SPSR &amp; (1 &lt;&lt; SPIF)));
  }
  
  void send_string_SPI(char s[])
  {
      int i = 0;
      while (s[i] != 0x00)
      {
          send_char_SPI(s[i]);
          i++;
      }
  }
  </code></pre>
  
  <p>so now I have two strings which I want to send to <strong>slave</strong> one by one.</p>
  
  <pre><code>char freq_array[] = {0x01, '5', '0', '.', '0', '0', '\r'};
  char volt_array[] = {0x02, '2', '9', '1', '.', '4', '\r'};  
  </code></pre>
  
  <p>Main of master- ATMEGA8:</p>
  
  <pre><code>int main(void)
  {
      SPI_Init();
      while (1) 
      {
          CS_Low;
          _delay_ms(10);
          send_string_SPI(volt_array);
          CS_High;
          _delay_ms(1000);
  
          CS_Low;
          _delay_ms(10);
          send_string_SPI(freq_array);
          CS_High;
          _delay_ms(1000);
      }
  }
  </code></pre>
  
  <p>Here is the main problem while I send only one array through SPI to slave I can get the data perfectly on <strong>slave</strong> side and further transmit it to the terminal via <a href="https://en.wikipedia.org/wiki/Universal_asynchronous_receiver-transmitter" rel="nofollow noreferrer">UART</a>. But while I send both of the arrays, I don't receive both arrays perfectly. I rather receive one array most of the time and the other array sometimes. I want that the <strong>salve</strong> receives the array one by one. First, it will receive the first array and then again it should receive the next array. and should transmit it to UART simultaneously.</p>
  
  <hr>
  
  <p><strong>SLAVE</strong></p>
  
  <p>Slave initialization - ATMEGA32:</p>
  
  <p>Here ATmega32 is receiving data using Interrupt</p>
  
  <pre><code>#define SPI_ddr             DDRB
  #define SPI_port            PORTB
  #define PIN_sck             7
  #define PIN_mosi            5
  #define PIN_ss              4
  #define PIN_miso            6
  #define SPI_PORT_enable()   (SPI_ddr &amp;= ~((1 &lt;&lt; PIN_sck) | (1 &lt;&lt; PIN_mosi) | (1 &lt;&lt; PIN_ss)) )
  
  void SPI_Init()
  {
      SPI_PORT_enable();
      SPI_ddr |= (1 &lt;&lt; PIN_miso);
      SPCR &amp;= ~(1 &lt;&lt; MSTR);
      SPCR |= (1&lt;&lt;SPR0)|(1&lt;&lt;SPR1);       // divide clock by 128
      SPCR |= (1&lt;&lt;SPE);                  // Enable SPI
      SPCR |= (1&lt;&lt;SPIE);
  
  }
  </code></pre>
  
  <p>ISR of slave- ATMEGA32:</p>
  
  <p>Here I am checking for <code>\r</code> as every string i am sending from <strong>master</strong> ends with <code>\r</code>. So if I get <code>\r</code> I will set <code>spi_data_recieved</code> variable so that I can process it in <code>main</code> (i.e can send the received data to the terminal via UART).</p>
  
  <pre><code>ISR(SPI_STC_vect)
  {
      data_array[data_index] = SPDR;
      if(data_array[data_index] == '\r')
          spi_data_recieved = 1;
      if (data_index &gt; 10)
      {
          data_index = 0;
          Clear_Buffer(data_array, 10);
      }
      else
      {
          data_index++;
      }
  }
  </code></pre>
  
  <hr>
  
  <p>UART functions on slave - ATMEGA32:</p>
  
  <pre><code>void Serial_Init(unsigned int baud)
  {
      UBRRH = (unsigned char)(baud &gt;&gt; 8);
      UBRRL = (unsigned char)baud;
  
      UCSRB = (1 &lt;&lt; RXEN)  | (1 &lt;&lt; TXEN) ;
      UCSRC = (1 &lt;&lt; URSEL) | (3 &lt;&lt; UCSZ0);
  
  }
  
  void Serial_Transmit(unsigned char data)
  {
      UDR = data;
      while ( !( UCSRA &amp; (1 &lt;&lt; UDRE) ) );
  }
  
  void Serial_Transmit_String(unsigned char *string)
  {
      while (*string != 0)
      Serial_Transmit(*string++);
  }
  </code></pre>
  
  <hr>
  
  <p>Main of slave - ATMEGA32:</p>
  
  <pre><code>int main(void)
  {
      SPI_Init();
      Serial_Init(103);
      data_index = 0;
      spi_data_recieved = 0;
      sei();
      Serial_Transmit_String((unsigned char*)"TESTING SPI\r\n");
      unsigned char copyBuff[10];
      while (1) 
      {
          if (spi_data_recieved == 1)
          {
              spi_data_recieved = 0;
              strcpy((char*)copyBuff, (char*)data_array);
              Clear_Buffer(data_array, 10);
              data_index = 0;
              switch(copyBuff[0])
              {
                  case 0x01: Serial_Transmit_String((unsigned char*)"Frequency: "); break;
                  case 0x02: Serial_Transmit_String((unsigned char*)"Bus Voltage: "); break;
                  default: Serial_Transmit_String((unsigned char*)"SPI Data: "); break;
              }
  
              Serial_Transmit_String(copyBuff);
          }
  
          _delay_ms(10);
      }
  }
  </code></pre>
  
  <p><strong>Expected output for this setup is:</strong></p>
  
  <pre>
  Bus Voltage: 291.4
  
  Frequency: 50.00
  
  Bus Voltage: 291.4
  
  Frequency: 50.00
  </pre>
  
  <p>and continuous in this manner</p>
  
  <p><strong>Getting the output as:</strong></p>
  
  <pre>
  SPI Data: 0
  
  Frequency: 50.00
  
  SPI Data: 0
  
  Frequency: 50.00
  
  SPI Data: 0
  
  Frequency: 50.00
  </pre>
  
  <p>And in very rare case I could see the bus voltage.</p>
  
  <p>I figured out there is some synchronization issue between the ATmega's but I don't know how to solve this problem.</p>