Consider the following embedded C code snippet configuring a GPIO port. What will be the value of GPIOA->MODER after execution?
typedef struct {
volatile unsigned int MODER;
} GPIO_TypeDef;
GPIO_TypeDef GPIOA_instance = {0};
GPIO_TypeDef *GPIOA = &GPIOA_instance;
int main() {
GPIOA->MODER = 0;
GPIOA->MODER |= (1 << (2 * 3)); // Set pin 3 to output mode (01)
GPIOA->MODER |= (2 << (2 * 4)); // Set pin 4 to alternate function mode (10)
return GPIOA->MODER;
}Remember each pin uses 2 bits in MODER. Pin 3 bits are bits 6-7, pin 4 bits are bits 8-9.
Pin 3 set to output mode means bits 6-7 = 01 (1 << 6 = 0x40). Pin 4 set to alternate function mode means bits 8-9 = 10 (2 << 8 = 0x200). Total: 0x240.
In a typical microcontroller GPIO port configuration register, how many bits are used to set the mode (input, output, alternate function, analog) of one pin?
Think about how many modes are possible and how many bits are needed to represent them.
Each GPIO pin mode is selected by 2 bits because there are 4 possible modes: 00=input, 01=output, 10=alternate function, 11=analog.
Examine the code below. It attempts to set GPIO pin 3 as output mode but does not work as expected. What is the cause?
GPIOA->MODER &= ~(0x3 << 3); GPIOA->MODER |= (0x1 << 3);
Remember each pin uses 2 bits in MODER. Check the shift amount carefully.
Each pin uses 2 bits in MODER. Pin 3's bits are bits 6 and 7 (2*3=6). The code shifts by 3 which affects bits 3 and 4, not pin 3. Correct shift is 6.
Consider this code snippet. What error will it produce?
GPIOA->MODER = 0; GPIOA->MODER |= 1 << 2 * 5;
Operator precedence matters in bit shifts and multiplication.
Without parentheses, the expression is evaluated as (1 << 2) * 5 = 4 * 5 = 20, so 20 is ORed, not the intended 1 << 10. This causes wrong bits to be set.
Given the following code configuring GPIO pins, what is the final hexadecimal value of GPIOB->MODER?
typedef struct {
volatile unsigned int MODER;
} GPIO_TypeDef;
GPIO_TypeDef GPIOB_instance = {0};
GPIO_TypeDef *GPIOB = &GPIOB_instance;
int main() {
GPIOB->MODER = 0;
// Set pin 0 to analog mode (11)
GPIOB->MODER |= (3 << (2 * 0));
// Set pin 1 to output mode (01)
GPIOB->MODER |= (1 << (2 * 1));
// Set pin 2 to alternate function mode (10)
GPIOB->MODER |= (2 << (2 * 2));
// Set pin 3 to input mode (00)
GPIOB->MODER &= ~(3 << (2 * 3));
return GPIOB->MODER;
}Calculate each pin's bits carefully and apply the clearing operations in order.
Pin 0 analog (11): 3 << 0 = 0x3
Pin 1 output (01): 1 << 2 = 0x4 (total 0x7)
Pin 2 alt (10): 2 << 4 = 0x20 (total 0x27)
Pin 3 input (00): clears bits 6-7 (already 0), no change.
Final: 0x27