#include <stdio.h>
#include <stdint.h>
#define SET_ENABLE(val) ((val & 0x01) << 0)
#define SET_MODE(val) ((val & 0x03) << 1)
#define SET_SPEED(val) ((val & 0x07) << 3)
uint16_t build_register(uint8_t enable, uint8_t mode, uint8_t speed) {
uint16_t reg = 0;
reg |= SET_ENABLE(enable);
reg |= SET_MODE(mode);
reg |= SET_SPEED(speed);
// RESERVED bits (6–7) are left as 0
return reg;
}
int main() {
uint8_t enable, mode, speed;
scanf("%hhu %hhu %hhu", &enable, &mode, &speed);
printf("%u\n", build_register(enable, mode, speed));
return 0;
}
MODE
is 2 bits starting at bit 1 → mask = 0x03
, shift = << 1
.Use masking and shifting to isolate and position each field:
#define SET_MODE(val) ((val & 0x03) << 1)
Use bitwise OR (|
) to combine all fields into a single register:
reg |= SET_ENABLE(enable) | SET_MODE(mode) | SET_SPEED(speed);
Ensure reserved bits are untouched or explicitly cleared:
reg &= ~(0x03 << 6); // Clear bits 6–7
&
masks to avoid overflow or invalid values.const
or macros for field widths and positions to improve maintainability.This approach works whether you're configuring TCCR0A
, ADCSRA
, or a custom peripheral register. Want to see how this maps to real datasheet specs or auto-generate macros from a register map? I can help with that too!
Input
1 2 4
Expected Output
37