Bird
Raised Fist0
Embedded Cprogramming~20 mins

UART interrupt-driven communication in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
UART Interrupt Master
Get all challenges correct to earn this badge!
Test your skills under time pressure!
❓ Predict Output
intermediate
2:00remaining
What is the output of this UART ISR code snippet?
Consider this UART interrupt service routine (ISR) snippet that reads a received byte and stores it in a buffer. What will be the value of rx_buffer[0] after the ISR runs once with UDR holding 0x41 (ASCII 'A')?
Embedded C
volatile char rx_buffer[10];
volatile int rx_index = 0;

ISR(USART_RX_vect) {
    rx_buffer[rx_index++] = UDR;
}
A0x00 (null character)
B'A' (0x41)
CUndefined value (buffer not updated)
DISR causes a compile error
Attempts:
2 left
💡 Hint
The ISR reads the UART data register and stores it in the buffer at the current index.
🧠 Conceptual
intermediate
1:30remaining
What happens if UART RX interrupt is not cleared properly?
In UART interrupt-driven communication, what is the most likely effect if the interrupt flag is not cleared inside the ISR?
AThe ISR will be called repeatedly, causing a system hang or high CPU usage.
BThe UART will stop receiving data permanently.
CThe UART will automatically clear the flag, so no effect occurs.
DThe microcontroller will reset immediately.
Attempts:
2 left
💡 Hint
Interrupt flags must be cleared to avoid repeated triggers.
🔧 Debug
advanced
2:30remaining
Why does this UART TX interrupt code fail to send all bytes?
This code tries to send a string via UART using TX interrupts. However, only the first character is sent. What is the bug?
Embedded C
volatile char tx_buffer[] = "HELLO";
volatile int tx_index = 0;

ISR(USART_UDRE_vect) {
    if (tx_index < sizeof(tx_buffer) - 1) {
        UDR = tx_buffer[tx_index];
        tx_index++;
    } else {
        UCSR0B &= ~(1 << UDRIE0); // Disable UDRE interrupt
    }
}
AThe interrupt enable bit UDRIE0 is not set before starting transmission.
BUsing sizeof(tx_buffer) includes the null terminator, causing an extra byte to send.
Ctx_index is not reset to zero after transmission completes.
DUDR register is read instead of written inside ISR.
Attempts:
2 left
💡 Hint
Check if the interrupt is enabled to trigger the ISR.
📝 Syntax
advanced
1:30remaining
Which option causes a syntax error in UART ISR declaration?
Which of these UART ISR declarations is syntactically incorrect in embedded C for AVR microcontrollers?
AISR(USART_RX_vect) { /* code */ }
BISR(USART_TX_vect) { /* code */ }
CISR(USART_UDRE_vect) { /* code */ }
Dvoid USART_RX_vect(void) { /* code */ }
Attempts:
2 left
💡 Hint
ISR functions use a special macro, not normal function syntax.
🚀 Application
expert
2:30remaining
How many bytes are stored after this UART RX interrupt-driven reception?
Given this UART RX ISR code that stores received bytes into a buffer of size 5, how many bytes will be stored if 7 bytes arrive without reading the buffer?
Embedded C
volatile char rx_buffer[5];
volatile int rx_index = 0;

ISR(USART_RX_vect) {
    if (rx_index < 5) {
        rx_buffer[rx_index++] = UDR;
    }
    // else bytes are discarded
}
A0 bytes stored; buffer not updated
B7 bytes stored; buffer auto-expands
C5 bytes stored; last 2 bytes discarded
DISR causes buffer overflow and crash
Attempts:
2 left
💡 Hint
Buffer size limits how many bytes can be stored.

Practice

(1/5)
1. What is the main advantage of using UART interrupt-driven communication in embedded systems?
easy
A. It allows the CPU to perform other tasks while waiting for UART data.
B. It requires the CPU to constantly check the UART status manually.
C. It disables all other interrupts during UART communication.
D. It slows down data transmission to avoid errors.

Solution

  1. Step 1: Understand UART polling vs interrupt

    Polling requires CPU to wait and check UART status repeatedly, wasting time.
  2. Step 2: Identify interrupt-driven benefit

    Interrupt-driven UART lets CPU do other work and only handles UART when data arrives.
  3. Final Answer:

    It allows the CPU to perform other tasks while waiting for UART data. -> Option A
  4. Quick Check:

    Interrupt-driven = CPU multitasks [OK]
Hint: Interrupts free CPU from waiting, improving multitasking [OK]
Common Mistakes:
  • Confusing polling with interrupt-driven method
  • Thinking interrupts disable other tasks
  • Assuming interrupt slows communication
2. Which of the following is the correct way to enable UART receive interrupt in embedded C?
easy
A. UART->CR1 &= ~UART_CR1_RXNEIE;
B. UART->CR1 = 0;
C. UART->CR1 |= UART_CR1_RXNEIE;
D. UART->CR1 |= UART_CR1_TXEIE;

Solution

  1. Step 1: Identify RX interrupt enable bit

    UART_CR1_RXNEIE enables receive-not-empty interrupt.
  2. Step 2: Enable RX interrupt without clearing other bits

    Use bitwise OR (|=) to set RXNEIE bit.
  3. Final Answer:

    UART->CR1 |= UART_CR1_RXNEIE; -> Option C
  4. Quick Check:

    Enable RX interrupt = |= UART_CR1_RXNEIE [OK]
Hint: Use |= to set interrupt enable bits without clearing others [OK]
Common Mistakes:
  • Using &= ~ to enable instead of disable bits
  • Setting TX interrupt instead of RX
  • Overwriting CR1 register instead of OR-ing
3. Given this UART interrupt handler code snippet, what will be the output if a byte 'A' (0x41) is received?
void USART1_IRQHandler(void) {
  if (USART1->SR & USART_SR_RXNE) {
    char data = USART1->DR;
    USART1->DR = data + 1;
  }
}
medium
A. The UART sends back 'A' unchanged.
B. The UART sends back 'B' (0x42) after receiving 'A'.
C. The UART sends back 'C' (0x43) after receiving 'A'.
D. No data is sent back.

Solution

  1. Step 1: Read received data

    Data 'A' (0x41) is read from USART1->DR.
  2. Step 2: Write back data + 1

    Data + 1 = 0x41 + 1 = 0x42, which is 'B'.
  3. Final Answer:

    The UART sends back 'B' (0x42) after receiving 'A'. -> Option B
  4. Quick Check:

    Received 'A' + 1 = 'B' [OK]
Hint: Adding 1 to 'A' (0x41) gives 'B' (0x42) [OK]
Common Mistakes:
  • Confusing ASCII values and characters
  • Assuming data is unchanged
  • Ignoring the addition operation
4. Identify the bug in this UART interrupt handler code:
void USART2_IRQHandler(void) {
  if (USART2->SR & USART_SR_TXE) {
    USART2->DR = tx_buffer[tx_index++];
  }
  USART2->SR &= ~USART_SR_TXE;
}
medium
A. The USART2->DR register should not be written inside the interrupt.
B. The interrupt handler should clear RXNE flag instead of TXE.
C. The tx_index variable is not incremented correctly.
D. Clearing the TXE flag manually is incorrect; it is cleared by hardware.

Solution

  1. Step 1: Understand TXE flag behavior

    TXE (transmit data register empty) flag is cleared automatically by hardware when data is written to DR.
  2. Step 2: Identify incorrect manual clearing

    Code tries to clear TXE by writing to SR register, which is read-only or managed by hardware.
  3. Final Answer:

    Clearing the TXE flag manually is incorrect; it is cleared by hardware. -> Option D
  4. Quick Check:

    TXE flag cleared by hardware, not software [OK]
Hint: TXE flag clears automatically; don't clear it manually [OK]
Common Mistakes:
  • Trying to clear hardware-managed flags manually
  • Confusing TXE and RXNE flags
  • Not incrementing buffer index properly
5. You want to implement a UART interrupt-driven echo program that receives data and immediately sends it back. Which sequence of actions should the interrupt handler perform to work correctly and efficiently?
hard
A. Check RXNE flag, read data from DR, write data back to DR, do not clear RXNE flag manually.
B. Clear RXNE flag manually, read data from DR, write data back to DR, check TXE flag.
C. Check TXE flag, write data to DR, clear TXE flag manually, then read data from DR.
D. Check RXNE flag, read data from DR, write data back to DR, clear RXNE flag manually.

Solution

  1. Step 1: Handle RXNE flag correctly

    Check RXNE flag to know data received; read data from DR clears RXNE automatically.
  2. Step 2: Write data back without manual flag clearing

    Write data to DR to send; TXE flag is managed by hardware, no manual clearing needed.
  3. Final Answer:

    Check RXNE flag, read data from DR, write data back to DR, do not clear RXNE flag manually. -> Option A
  4. Quick Check:

    Read clears RXNE; no manual flag clearing needed [OK]
Hint: Read clears RXNE; hardware manages flags automatically [OK]
Common Mistakes:
  • Manually clearing RXNE or TXE flags
  • Checking TXE before reading RXNE
  • Writing data before reading received byte
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