Bird
Raised Fist0
Embedded Cprogramming~20 mins

SPI with external devices (sensors, displays) in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
SPI Mastery Badge
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
SPI Data Transmission Output
What will be the output on the SPI data register (SPDR) after executing this code snippet?
Embedded C
#define SPI_DATA_REG (*(volatile unsigned char*)0x2F)
#define SPI_STATUS_REG (*(volatile unsigned char*)0x2E)
#define SPI_ENABLE 0x40
#define SPI_INT_FLAG 0x80

void spi_init() {
    SPI_STATUS_REG = SPI_ENABLE;
}

void spi_send(unsigned char data) {
    SPI_DATA_REG = data;
    while (!(SPI_STATUS_REG & SPI_INT_FLAG));
}

int main() {
    spi_init();
    spi_send(0xA5);
    return SPI_DATA_REG;
}
A0xA5
B0x00
C0xFF
DProgram hangs in while loop
Attempts:
2 left
💡 Hint
Think about what value is written to the SPI data register and when the function returns.
🧠 Conceptual
intermediate
1:30remaining
SPI Clock Polarity and Phase
Which SPI mode configuration correctly sets clock polarity (CPOL) to 1 and clock phase (CPHA) to 0?
ACPOL=0, CPHA=1 means clock idles high, data sampled on leading edge
BCPOL=1, CPHA=0 means clock idles low, data sampled on trailing edge
CCPOL=1, CPHA=0 means clock idles high, data sampled on leading edge
DCPOL=0, CPHA=0 means clock idles high, data sampled on trailing edge
Attempts:
2 left
💡 Hint
Remember CPOL controls idle clock level, CPHA controls sampling edge.
🔧 Debug
advanced
2:30remaining
SPI Read from Sensor Fails
This code tries to read a byte from an SPI sensor but always returns 0x00. What is the most likely cause?
Embedded C
unsigned char spi_read() {
    SPI_DATA_REG = 0xFF; // send dummy byte
    while (!(SPI_STATUS_REG & SPI_INT_FLAG));
    return SPI_DATA_REG;
}

int main() {
    spi_init();
    unsigned char val = spi_read();
    return val;
}
ASPI_STATUS_REG is incorrectly masked, causing infinite loop
BSPI clock not enabled, so no data is clocked in
CSPI_INT_FLAG is never set because SPI is in slave mode
DSPI_DATA_REG should not be written before reading
Attempts:
2 left
💡 Hint
Check if SPI clock is active to shift data in and out.
📝 Syntax
advanced
1:30remaining
Correct SPI Interrupt Handler Syntax
Which option shows the correct syntax for an SPI interrupt service routine (ISR) in embedded C for AVR microcontrollers?
AISR(SPI_STC_vect) { /* handle SPI interrupt */ }
Bvoid ISR_SPI_STC_vect(void) { /* handle SPI interrupt */ }
Cinterrupt SPI_STC_vect() { /* handle SPI interrupt */ }
Dvoid SPI_STC_vect() { /* handle SPI interrupt */ }
Attempts:
2 left
💡 Hint
Look for the special ISR macro used in AVR GCC.
🚀 Application
expert
3:00remaining
SPI Display Initialization Sequence
Given these SPI commands to initialize a display, what is the correct order to send them to properly initialize the device?
A4,1,2,3
B2,1,4,3
C1,4,2,3
D1,2,4,3
Attempts:
2 left
💡 Hint
Reset first, then wake up, set pixel format, then turn display on.

Practice

(1/5)
1. What is the main purpose of the Chip Select (CS) line in SPI communication with external devices like sensors or displays?
easy
A. To increase the SPI clock speed
B. To provide power to the SPI device
C. To reset the SPI device
D. To select which device the microcontroller communicates with

Solution

  1. Step 1: Understand SPI device selection

    The Chip Select (CS) line is used to enable communication with one specific SPI device among multiple devices connected to the same SPI bus.
  2. Step 2: Identify the role of CS

    When CS is active (usually low), the selected device listens and responds to SPI signals; other devices ignore the communication.
  3. Final Answer:

    To select which device the microcontroller communicates with -> Option D
  4. Quick Check:

    CS line = device selector [OK]
Hint: CS line chooses the device to talk to in SPI [OK]
Common Mistakes:
  • Confusing CS with power supply line
  • Thinking CS resets the device
  • Assuming CS controls clock speed
2. Which of the following is the correct way to initialize SPI communication in embedded C for a sensor device?
easy
A. SPI_Init(); CS_Pin = LOW; SPI_Transmit(0xAA);
B. SPI_Init(); CS_Pin = HIGH; SPI_Transmit(0xFF);
C. SPI_Start(); CS_Pin = LOW; SPI_Receive();
D. SPI_Begin(); CS_Pin = HIGH; SPI_Receive(0x00);

Solution

  1. Step 1: Check SPI initialization and CS pin state

    SPI_Init() is the standard function to initialize SPI. CS must be LOW to select the device before transmitting data.
  2. Step 2: Verify data transmission call

    SPI_Transmit(0xAA) sends data to the device. This matches typical SPI usage.
  3. Final Answer:

    SPI_Init(); CS_Pin = LOW; SPI_Transmit(0xAA); -> Option A
  4. Quick Check:

    Init SPI + CS low + transmit data = correct setup [OK]
Hint: CS LOW means device selected before sending data [OK]
Common Mistakes:
  • Setting CS HIGH before transmit disables device
  • Using wrong SPI init function name
  • Calling receive without selecting device
3. Consider this embedded C code snippet communicating with an SPI sensor:
CS_PIN = 0;  // Select device
uint8_t data = SPI_TransmitReceive(0x55);
CS_PIN = 1;  // Deselect device

What value will data hold after execution?
medium
A. The sensor's response byte received during transmission
B. Always 0x55, the sent byte
C. Undefined, because CS_PIN is set to 1 after transmit
D. An error code due to missing SPI initialization

Solution

  1. Step 1: Understand SPI_TransmitReceive behavior

    This function sends a byte (0x55) and simultaneously receives a byte from the sensor during the SPI clock cycles.
  2. Step 2: Analyze CS pin usage

    CS_PIN is set LOW before transmission to select the device and set HIGH after to deselect. This is correct usage and does not affect the received data.
  3. Final Answer:

    The sensor's response byte received during transmission -> Option A
  4. Quick Check:

    SPI sends and receives simultaneously = sensor response [OK]
Hint: SPI sends and receives data at the same time [OK]
Common Mistakes:
  • Assuming received data equals sent data
  • Thinking CS high before transmit affects data
  • Ignoring simultaneous send/receive nature
4. This code snippet is intended to read data from an SPI display, but it does not work correctly:
CS_PIN = 1;
SPI_Transmit(0x0F);
CS_PIN = 0;
uint8_t response = SPI_Receive();
CS_PIN = 1;

What is the main error?
medium
A. CS_PIN should remain HIGH during receive
B. SPI_Transmit should be SPI_Receive
C. CS_PIN should be set LOW before transmitting
D. SPI_Receive requires a parameter

Solution

  1. Step 1: Check CS_PIN state before transmission

    CS_PIN must be LOW to select the SPI device before sending commands or data.
  2. Step 2: Identify the error in CS_PIN usage

    The code sets CS_PIN HIGH before transmit, which deselects the device, so the device ignores the command.
  3. Final Answer:

    CS_PIN should be set LOW before transmitting -> Option C
  4. Quick Check:

    CS LOW before transmit = device listens [OK]
Hint: Always set CS LOW before sending SPI data [OK]
Common Mistakes:
  • Setting CS HIGH before transmit disables device
  • Confusing transmit and receive functions
  • Assuming CS state doesn't affect communication
5. You want to read temperature data from an SPI sensor that requires sending a command byte 0x01, then reading two bytes of data. Which code snippet correctly implements this sequence?
hard
A. CS_PIN = 0; SPI_Transmit(0x01); uint8_t high = SPI_Receive(); uint8_t low = SPI_Receive(); CS_PIN = 1;
B. CS_PIN = 0; SPI_Transmit(0x01); high = SPI_Transmit(0x00); low = SPI_Transmit(0x00); CS_PIN = 1;
C. CS_PIN = 1; SPI_Transmit(0x01); high = SPI_Receive(); low = SPI_Receive(); CS_PIN = 0;
D. SPI_Transmit(0x01); CS_PIN = 0; high = SPI_Receive(); low = SPI_Receive(); CS_PIN = 1;

Solution

  1. Step 1: Select device before communication

    CS_PIN must be set LOW before sending commands or data to select the sensor.
  2. Step 2: Send command and read data correctly

    SPI_Transmit sends a byte and simultaneously receives a byte. To read data, send dummy bytes (0x00) to clock out sensor data.
  3. Step 3: Deselect device after communication

    CS_PIN is set HIGH after communication to end the session.
  4. Final Answer:

    CS_PIN = 0; SPI_Transmit(0x01); high = SPI_Transmit(0x00); low = SPI_Transmit(0x00); CS_PIN = 1; -> Option B
  5. Quick Check:

    Send command, then send dummy bytes to receive data [OK]
Hint: Send dummy bytes to receive SPI data after command [OK]
Common Mistakes:
  • Reading without sending dummy bytes
  • Setting CS high before command
  • Not deselecting device after communication
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard