Bird
Raised Fist0
Embedded Cprogramming~20 mins

Transmitting a byte over UART in Embedded C - Practice Problems & Coding Challenges

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
UART Transmission 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 transmit function?
Consider the following embedded C code snippet that transmits a byte over UART. What will be the value of the UART data register (UDR) after calling uart_transmit(0x55);?
Embedded C
volatile unsigned char UDR = 0;
volatile unsigned char UCSRA = 0x20; // UDRE bit set (ready)

void uart_transmit(unsigned char data) {
    while (!(UCSRA & 0x20)) {
        // wait until UDRE bit is set
    }
    UDR = data;
}

int main() {
    uart_transmit(0x55);
    return 0;
}
AUDR will be 0xFF
BUDR will be 0x00
CUDR will be 0x55
DUDR will be 0x20
Attempts:
2 left
💡 Hint
Check what the function assigns to UDR after the ready bit is confirmed.
🧠 Conceptual
intermediate
1:30remaining
Which statement correctly describes the UDRE bit in UART communication?
In UART communication, what does the UDRE (UART Data Register Empty) bit indicate?
AThe UART data register is full and cannot accept new data
BThe UART data register is empty and ready to accept new data
CThe UART has received a byte successfully
DThe UART transmitter is disabled
Attempts:
2 left
💡 Hint
Think about when you can safely write a new byte to the UART data register.
🔧 Debug
advanced
2:30remaining
Why does this UART transmit code cause a hang?
This code is intended to transmit a byte over UART, but it causes the program to hang (infinite loop). What is the reason?
Embedded C
volatile unsigned char UCSRA = 0x00; // UDRE bit is 0 (not ready)
volatile unsigned char UDR = 0;

void uart_transmit(unsigned char data) {
    while (!(UCSRA & 0x20)) {
        // wait until UDRE bit is set
    }
    UDR = data;
}

int main() {
    uart_transmit(0xAA);
    return 0;
}
AThe function does not clear the UDRE bit after transmission
BUDR register is not volatile, causing optimization issues
CData is assigned before checking UDRE bit
DUDRE bit is never set, so the while loop never ends
Attempts:
2 left
💡 Hint
Look at the initial value of UCSRA and the condition in the while loop.
📝 Syntax
advanced
2:00remaining
Which option correctly transmits a byte over UART?
Select the code snippet that correctly waits for the UART data register to be ready and then transmits the byte data.
A
while (!(UCSRA & (1 << 5))) {}
UDR = data;
B
while (UCSRA & (1 << 5)) {}
UDR = data;
C
if (UCSRA & (1 << 5)) {
  UDR = data;
}
D
while (!(UCSRA & 0x10)) {}
UDR = data;
Attempts:
2 left
💡 Hint
UDRE bit is bit 5 (value 0x20). You want to wait until it is set.
🚀 Application
expert
3:00remaining
How many bytes are transmitted by this UART send function call?
Given the following code, how many bytes will be transmitted when uart_send_string("Hi"); is called?
Embedded C
volatile unsigned char UCSRA = 0x20; // UDRE bit set
volatile unsigned char UDR = 0;

void uart_transmit(unsigned char data) {
    while (!(UCSRA & 0x20)) {}
    UDR = data;
}

void uart_send_string(const char *str) {
    while (*str) {
        uart_transmit(*str++);
    }
}

int main() {
    uart_send_string("Hi");
    return 0;
}
A2 bytes
B3 bytes
C1 byte
D0 bytes
Attempts:
2 left
💡 Hint
Count the characters in the string and how the loop processes them.

Practice

(1/5)
1. What is the main purpose of waiting for the UART transmit buffer to be empty before sending a byte?
easy
A. To change the baud rate
B. To reset the UART hardware
C. To clear the receive buffer
D. To ensure the previous byte has been sent and avoid data loss

Solution

  1. Step 1: Understand UART transmit buffer role

    The UART transmit buffer holds the byte to be sent. It must be empty before loading a new byte.
  2. Step 2: Reason why waiting is necessary

    If you send a byte before the buffer is empty, the previous byte might be overwritten, causing data loss.
  3. Final Answer:

    To ensure the previous byte has been sent and avoid data loss -> Option D
  4. Quick Check:

    Wait for buffer empty = prevent data loss [OK]
Hint: Always wait for transmit buffer empty before sending [OK]
Common Mistakes:
  • Ignoring the transmit buffer status
  • Confusing transmit and receive buffers
  • Trying to send bytes too fast
2. Which of the following code snippets correctly waits for the UART transmit buffer to be ready before sending a byte data using a register UART_STATUS with bit 5 as TX_READY flag?
easy
A. while (!(UART_STATUS & (1 << 5))); UART_DATA = data;
B. if (UART_STATUS & (1 << 5)) UART_DATA = data;
C. UART_DATA = data; while (!(UART_STATUS & (1 << 5)));
D. while (UART_STATUS & (1 << 5)) UART_DATA = data;

Solution

  1. Step 1: Understand the TX_READY flag meaning

    Bit 5 set means transmit buffer is ready (empty), so wait until it is set.
  2. Step 2: Analyze each code snippet

    while (!(UART_STATUS & (1 << 5))); UART_DATA = data; waits in a loop until bit 5 is set, then sends data. This is correct. if (UART_STATUS & (1 << 5)) UART_DATA = data; sends data only if ready once, no wait. UART_DATA = data; while (!(UART_STATUS & (1 << 5))); sends data before waiting, risking overwrite. while (UART_STATUS & (1 << 5)) UART_DATA = data; loops while bit 5 is set, which is opposite logic.
  3. Final Answer:

    while (!(UART_STATUS & (1 << 5))); UART_DATA = data; -> Option A
  4. Quick Check:

    Wait until TX_READY set, then send [OK]
Hint: Use while loop to wait for TX_READY bit set [OK]
Common Mistakes:
  • Using if instead of while to wait
  • Sending data before waiting
  • Checking wrong bit or wrong condition
3. Given the following code snippet, what will be the output if UART_STATUS initially has bit 5 cleared and then set after some time?
while (!(UART_STATUS & (1 << 5))) {
  // wait
}
UART_DATA = 0xAB;
medium
A. The byte 0xAB is sent immediately without waiting
B. The byte 0xAB is sent after waiting for TX_READY
C. The code causes an infinite loop
D. The UART_DATA register is never written

Solution

  1. Step 1: Analyze the while loop condition

    The loop waits while bit 5 of UART_STATUS is 0 (not ready). Initially bit 5 is cleared, so it waits.
  2. Step 2: Consider bit 5 changing to set

    When bit 5 becomes set, the condition becomes false, loop exits, and UART_DATA is assigned 0xAB.
  3. Final Answer:

    The byte 0xAB is sent after waiting for TX_READY -> Option B
  4. Quick Check:

    Wait loop exits when ready, then send byte [OK]
Hint: Wait loop exits only when TX_READY bit is set [OK]
Common Mistakes:
  • Assuming immediate send without waiting
  • Thinking loop never ends
  • Confusing bit set/clear logic
4. Identify the error in this UART transmit code snippet:
UART_DATA = data;
while (!(UART_STATUS & (1 << 5))) {
  // wait
}
medium
A. UART_DATA register is not assigned any value
B. The while loop condition is incorrect, should check bit 4 instead
C. The data is sent before checking if UART is ready, risking overwrite
D. The code correctly waits before sending data

Solution

  1. Step 1: Check order of operations

    The code writes data to UART_DATA before waiting for TX_READY flag.
  2. Step 2: Understand risk of overwriting

    If UART is not ready, writing data first can overwrite previous byte, causing data loss.
  3. Final Answer:

    The data is sent before checking if UART is ready, risking overwrite -> Option C
  4. Quick Check:

    Send only after waiting for TX_READY [OK]
Hint: Always wait before writing UART_DATA [OK]
Common Mistakes:
  • Writing data before waiting
  • Checking wrong status bit
  • Missing wait loop entirely
5. You want to send an array of bytes data[5] = {0x10, 0x20, 0x30, 0x40, 0x50} over UART. Which code snippet correctly transmits all bytes ensuring no data loss?
hard
A. for (int i = 0; i < 5; i++) { while (!(UART_STATUS & (1 << 5))); UART_DATA = data[i]; }
B. for (int i = 0; i < 5; i++) { UART_DATA = data[i]; while (!(UART_STATUS & (1 << 5))); }
C. int i = 0; while (i < 5) { UART_DATA = data[i]; i++; }
D. for (int i = 0; i < 5; i++) { UART_DATA = data[i]; }

Solution

  1. Step 1: Understand the need to wait before sending each byte

    Each byte must be sent only after UART transmit buffer is ready to avoid overwriting.
  2. Step 2: Analyze each option

    for (int i = 0; i < 5; i++) { while (!(UART_STATUS & (1 << 5))); UART_DATA = data[i]; } waits before sending each byte, ensuring safe transmission. for (int i = 0; i < 5; i++) { UART_DATA = data[i]; while (!(UART_STATUS & (1 << 5))); } sends byte first then waits, risking overwrite. int i = 0; while (i < 5) { UART_DATA = data[i]; i++; } sends bytes without waiting. for (int i = 0; i < 5; i++) { UART_DATA = data[i]; } sends all bytes without any wait, causing data loss.
  3. Final Answer:

    for (int i = 0; i < 5; i++) { while (!(UART_STATUS & (1 << 5))); UART_DATA = data[i]; } -> Option A
  4. Quick Check:

    Wait before each send to avoid data loss [OK]
Hint: Wait before sending each byte in loop [OK]
Common Mistakes:
  • Sending bytes without waiting
  • Waiting after sending bytes
  • Ignoring transmit buffer status
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