0
0
Power-electronicsHow-ToBeginner · 3 min read

How to Receive Data Using SPI in Embedded C: Simple Guide

To receive data using SPI in embedded C, you typically read from the SPI data register after initiating a transfer. Use the SPI receive function or check the SPI status register to know when data is ready, then read the received byte from the SPI data register.
📐

Syntax

The basic syntax to receive data over SPI involves checking the SPI status register and reading the SPI data register. Typically, you wait until the SPI transfer is complete, then read the received byte.

  • SPDR: SPI Data Register where received data is stored.
  • SPSR: SPI Status Register to check flags like SPIF (SPI Interrupt Flag).
  • SPIF: Flag set when transfer is complete.
c
while(!(SPSR & (1<<SPIF))) { /* wait for transfer complete */ }
uint8_t received_data = SPDR;
💻

Example

This example shows how to receive one byte of data using SPI on an AVR microcontroller. It waits for the SPI transfer to complete, then reads the received byte.

c
#include <avr/io.h>
#include <util/delay.h>

void SPI_SlaveInit(void) {
    DDRB &= ~(1<<PB3); // MISO as input
    DDRB |= (1<<PB4) | (1<<PB5) | (1<<PB2); // MOSI, SCK, SS as output
    SPCR = (1<<SPE); // Enable SPI
}

uint8_t SPI_SlaveReceive(void) {
    while(!(SPSR & (1<<SPIF))) { /* wait for reception complete */ }
    return SPDR; // Return received data
}

int main(void) {
    uint8_t data;
    SPI_SlaveInit();
    while(1) {
        data = SPI_SlaveReceive();
        // Use received data (e.g., store, process)
    }
}
⚠️

Common Pitfalls

Common mistakes when receiving SPI data include:

  • Not waiting for the transfer to complete before reading the data register.
  • Misconfiguring SPI pins (MISO, MOSI, SCK, SS).
  • Not enabling SPI before trying to receive data.
  • Ignoring the SPI interrupt flag (SPIF) which signals data is ready.

Always check the status flag before reading to avoid reading invalid data.

c
/* Wrong way: reading data without waiting */
uint8_t data = SPDR; // May read invalid data

/* Right way: wait for SPIF flag */
while(!(SPSR & (1<<SPIF))) {}
data = SPDR;
📊

Quick Reference

StepDescription
1Configure SPI pins and enable SPI peripheral
2Wait for SPI transfer complete flag (SPIF)
3Read received byte from SPI data register (SPDR)
4Process or store the received data

Key Takeaways

Always wait for the SPI transfer complete flag before reading data.
Read received data from the SPI data register after transfer completion.
Configure SPI pins and enable SPI before receiving data.
Avoid reading SPI data register too early to prevent invalid data.
Use status flags like SPIF to know when data is ready.