Bird
Raised Fist0
Embedded Cprogramming~20 mins

Direction register vs data register in Embedded C - Practice Questions

Choose your learning style10 modes available
Challenge - 5 Problems
🎖️
Direction and Data Register 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 embedded C code snippet?

Consider a microcontroller port with a direction register (DDR) and a data register (PORT). The DDR controls pin direction (1 for output, 0 for input). The PORT register controls output value if the pin is output, or enables pull-up resistor if input.

What will be the output on the port pins after running this code?

Embedded C
#include <stdint.h>
#include <stdio.h>

uint8_t DDR = 0x00;  // Direction register
uint8_t PORT = 0x00; // Data register

int main() {
    DDR = 0b00001111;  // Lower 4 pins output, upper 4 pins input
    PORT = 0b10101010; // Set alternating bits

    // Simulate reading port pins
    uint8_t pin_values = PORT & DDR; // Output pins show PORT value
    printf("Pin values: 0x%02X\n", pin_values);
    return 0;
}
APin values: 0x0F
BPin values: 0x0A
CPin values: 0xAA
DPin values: 0x00
Attempts:
2 left
💡 Hint

Remember that only pins set as output in DDR show the PORT value on pins.

🧠 Conceptual
intermediate
1:30remaining
Which statement correctly describes the difference between DDR and PORT registers?

Choose the correct description of the roles of the Direction Register (DDR) and Data Register (PORT) in microcontroller I/O ports.

ADDR and PORT both set output values but for different pins.
BDDR sets output value; PORT sets pin direction.
CDDR sets pin direction; PORT sets output value or pull-up resistor depending on DDR.
DDDR enables interrupts; PORT controls analog input levels.
Attempts:
2 left
💡 Hint

Think about what controls if a pin is input or output, and what controls the voltage level.

🔧 Debug
advanced
2:30remaining
Why does this code not set the output pins correctly?

The code below tries to set pins 0-3 as outputs and set them high, but the output pins remain low. What is the cause?

Embedded C
#include <stdint.h>
#include <stdio.h>

uint8_t DDR = 0x00;
uint8_t PORT = 0x00;

int main() {
    DDR = 0b00001111; // Set pins 0-3 as output
    PORT = 0b00001111; // Set pins 0-3 high

    // Simulate reading pins
    uint8_t pins = PORT & DDR;
    printf("Pins: 0x%02X\n", pins);
    return 0;
}
AThe PORT register must be set before DDR to take effect.
BThe pins variable should be DDR & ~PORT to read output pins.
CThe code should use |= instead of = to set bits in DDR and PORT.
DThe DDR and PORT variables are not linked to actual hardware registers, so setting them has no effect.
Attempts:
2 left
💡 Hint

Think about what DDR and PORT represent in real embedded systems versus this simulation.

📝 Syntax
advanced
1:30remaining
What error does this code produce?

Analyze the following embedded C code snippet. What error will it produce when compiled?

Embedded C
#include <stdint.h>

uint8_t DDR = 0x00;
uint8_t PORT = 0x00;

int main() {
    DDR = 0b00001111;
    PORT = 0b10101010;
    return 0;
}
ASyntaxError: missing semicolon after DDR assignment
BTypeError: invalid binary literal
CNo error, code compiles successfully
DRuntime error: uninitialized variable usage
Attempts:
2 left
💡 Hint

Check each line carefully for missing punctuation.

🚀 Application
expert
3:00remaining
How many pins are configured as output and set high after this code?

Given the following code, how many pins are configured as output and set to high voltage?

Embedded C
#include <stdint.h>

uint8_t DDR = 0b11001100;
uint8_t PORT = 0b10101010;

int main() {
    uint8_t output_pins = DDR & PORT;
    int count = 0;
    for (int i = 0; i < 8; i++) {
        if ((output_pins >> i) & 1) {
            count++;
        }
    }
    return count;
}
A2
B3
C4
D5
Attempts:
2 left
💡 Hint

Count bits set to 1 in DDR and PORT at the same positions.

Practice

(1/5)
1. What is the primary role of a direction register in embedded C programming?
easy
A. It resets the microcontroller.
B. It stores the data value to be sent through the pin.
C. It sets whether a pin is an input or an output.
D. It controls the clock speed of the microcontroller.

Solution

  1. Step 1: Understand the function of direction register

    The direction register configures each pin as either input or output.
  2. Step 2: Differentiate from data register

    The data register holds the actual value sent or received, not the pin mode.
  3. Final Answer:

    It sets whether a pin is an input or an output. -> Option C
  4. Quick Check:

    Direction register = Pin mode control [OK]
Hint: Direction register controls pin mode, not data value [OK]
Common Mistakes:
  • Confusing direction register with data register
  • Thinking direction register stores data values
  • Mixing up pin configuration with clock control
2. Which of the following is the correct way to set pin 3 as output using a direction register named DIR_REG in embedded C?
easy
A. DIR_REG = 1 << 3;
B. DIR_REG |= (1 << 3);
C. DIR_REG &= ~(1 << 3);
D. DIR_REG ^= (1 << 3);

Solution

  1. Step 1: Understand setting a bit without affecting others

    Using |= with (1 << 3) sets bit 3 to 1, keeping other bits unchanged.
  2. Step 2: Analyze other options

    DIR_REG = 1 << 3; overwrites all bits, DIR_REG &= ~(1 << 3); clears bit 3, DIR_REG ^= (1 << 3); toggles bit 3.
  3. Final Answer:

    DIR_REG |= (1 << 3); -> Option B
  4. Quick Check:

    Use |= to set bits safely [OK]
Hint: Use |= to set a bit without changing others [OK]
Common Mistakes:
  • Using = instead of |= which overwrites all bits
  • Using &=~ which clears the bit instead of setting
  • Using ^= which toggles the bit unpredictably
3. Given the following code snippet, what is the final value of DATA_REG if initially it was 0x00?
DIR_REG |= (1 << 2);  // Set pin 2 as output
DATA_REG |= (1 << 2); // Set pin 2 high
DATA_REG &= ~(1 << 1); // Clear pin 1
DATA_REG ^= (1 << 2);  // Toggle pin 2
medium
A. 0x04
B. 0x06
C. 0x02
D. 0x00

Solution

  1. Step 1: Trace DATA_REG changes step-by-step

    Initially DATA_REG = 0x00.
    After DATA_REG |= (1 << 2); DATA_REG = 0x04.
    After DATA_REG &= ~(1 << 1); bit 1 cleared, no change, DATA_REG = 0x04.
    After DATA_REG ^= (1 << 2); toggles bit 2, DATA_REG = 0x00.
  2. Step 2: Confirm final value

    Final DATA_REG value is 0x00 after toggling bit 2 off.
  3. Final Answer:

    0x00 -> Option D
  4. Quick Check:

    Toggle bit 2 twice returns to 0 [OK]
Hint: Toggle a bit twice returns it to original state [OK]
Common Mistakes:
  • Ignoring toggle effect and assuming bit stays set
  • Confusing bit positions (bit 1 vs bit 2)
  • Not tracking bit clearing correctly
4. Identify the error in the following code that tries to set pin 0 as output and set it high:
DIR_REG = DIR_REG & (1 << 0);
DATA_REG = DATA_REG | (1 << 0);
medium
A. Using & instead of | to set direction bit clears other bits.
B. DATA_REG should use &= instead of | to set pin high.
C. DIR_REG should be assigned 0, not bitwise operation.
D. No error, code works correctly.

Solution

  1. Step 1: Analyze DIR_REG operation

    DIR_REG & (1 << 0) clears all bits except bit 0, overwriting other pin settings.
  2. Step 2: Correct way to set bit without clearing others

    Use DIR_REG |= (1 << 0) to set bit 0 without affecting others.
  3. Final Answer:

    Using & instead of | to set direction bit clears other bits. -> Option A
  4. Quick Check:

    Use |= to set bits, not & [OK]
Hint: Use |= to set bits, & clears bits [OK]
Common Mistakes:
  • Using & instead of |= to set bits
  • Thinking |= clears bits
  • Assuming DATA_REG needs &= to set bits
5. You want to configure pins 0, 2, and 4 as outputs and set pins 0 and 4 high without changing other pins. Which sequence of operations correctly achieves this?
// Initial values: DIR_REG = 0x08, DATA_REG = 0x02
hard
A. DIR_REG |= (1 << 0) | (1 << 2) | (1 << 4); DATA_REG |= (1 << 0) | (1 << 4);
B. DIR_REG = (1 << 0) | (1 << 2) | (1 << 4); DATA_REG = (1 << 0) | (1 << 4);
C. DIR_REG &= ~((1 << 1) | (1 << 3)); DATA_REG |= (1 << 0) | (1 << 4);
D. DIR_REG |= (1 << 1) | (1 << 3); DATA_REG |= (1 << 2);

Solution

  1. Step 1: Set pins 0, 2, 4 as outputs without clearing others

    Use DIR_REG |= (1 << 0) | (1 << 2) | (1 << 4); to set these bits safely.
  2. Step 2: Set pins 0 and 4 high without affecting others

    Use DATA_REG |= (1 << 0) | (1 << 4); to set those pins high.
  3. Step 3: Analyze other options

    DIR_REG = (1 << 0) | (1 << 2) | (1 << 4); DATA_REG = (1 << 0) | (1 << 4); overwrites all bits, clearing others.
    DIR_REG &= ~((1 << 1) | (1 << 3)); DATA_REG |= (1 << 0) | (1 << 4); clears pins 1 and 3 but does not set required pins.
    DIR_REG |= (1 << 1) | (1 << 3); DATA_REG |= (1 << 2); sets wrong pins.
  4. Final Answer:

    DIR_REG |= (1 << 0) | (1 << 2) | (1 << 4); DATA_REG |= (1 << 0) | (1 << 4); -> Option A
  5. Quick Check:

    Use |= to set multiple bits safely [OK]
Hint: Use |= with combined bits to set multiple pins safely [OK]
Common Mistakes:
  • Using = which overwrites other pins
  • Setting wrong pins by mistake
  • Clearing pins unintentionally
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