Skip to content

set_bits

Mallikarjunarao Kosuri edited this page Jul 14, 2024 · 1 revision

Explanation of set_bits

The set_bits function sets n bits of x starting from position p with the n least significant bits of y. This function is particularly useful in embedded systems for manipulating specific bits within a byte or register.

Function Code

uint8_t set_bits(uint8_t x, uint8_t p, uint8_t n, uint8_t y) 
{
    uint8_t mask = (1 << n) - 1;
    y = (y & mask) << (p - n + 1);
    mask = ~(mask << (p - n + 1));
    return (x & mask) | y;
}

How It Works

  1. Create a Mask for n Bits:

    • mask = (1 << n) - 1 creates a mask with the least significant n bits set to 1 and all other bits set to 0.
  2. Align the n Bits of y with Position p in x:

    • y = (y & mask) << (p - n + 1) extracts the n least significant bits of y and shifts them to align with the target position p in x.
  3. Create a Mask to Clear n Bits at Position p in x:

    • mask = ~(mask << (p - n + 1)) creates a mask to clear the n bits at position p in x.
  4. Set the Bits:

    • return (x & mask) | y clears the n bits at position p in x and sets them to the n bits of y.

Example

Let's consider an example where x = 0b11001100, p = 5, n = 3, and y = 0b101.

Binary Representation

x = 11001100 (binary)
p = 5
n = 3
y = 101 (binary)

Step-by-Step Execution

  1. Create the Mask for n Bits:

    mask = (1 << 3) - 1 = 0b111
    
  2. Align the n Bits of y with Position p in x:

    y = (y & mask) << (5 - 3 + 1) = (0b101 & 0b111) << 3 = 0b101 << 3 = 0b101000
    
  3. Create a Mask to Clear n Bits at Position p in x:

    mask = ~(mask << (5 - 3 + 1)) = ~(0b111 << 3) = ~0b111000 = 0b000111
    
  4. Set the Bits:

    (x & mask) | y = (0b11001100 & 0b000111) | 0b101000 = 0b00001100 | 0b101000 = 0b10101100
    

Result

Result = 10101100 (binary) = 172 (decimal)

Markdown Diagram

 x = 11001100 (original binary value)
 p = 5 (bit position to start setting)
 n = 3 (number of bits to set)
 y = 101 (binary value to set)

1. Create a mask for n bits:
   mask = (1 << 3) - 1 = 00000111 (binary)

2. Align the n bits of y with position p in x:
   y (aligned) = (0b101 & 0b111) << 3 = 0b101 << 3 = 101000 (binary)

3. Create a mask to clear n bits at position p in x:
   mask (clear) = ~(0b111 << 3) = ~0b111000 = 0000111 (binary)

4. Clear n bits at position p in x and set the n bits from y:
   result = (0b11001100 & 0b0000111) | 0b101000 = 0b00001100 | 0b101000 = 10101100 (binary)

Use Cases in Embedded Systems

When to Use

  • Manipulating Specific Bits in a Register: Setting specific bits in control or configuration registers of peripherals.
  • Bit-field Manipulation: Efficiently managing bit-fields in communication protocols or hardware interfaces.
  • Custom Configuration: Setting specific configuration bits in microcontroller or sensor settings.

Real-World Example

Consider a microcontroller interfacing with a sensor. The sensor's configuration register is 8 bits wide, and we need to set specific bits to configure the sensor's mode of operation.

Let's assume the sensor's configuration register is initially 0b11001100, and we need to set bits 5 to 3 to 0b101 to configure the sensor.

Example in Embedded Systems

#include <stdint.h>
#include "bitops.h"

int main() 
{
    uint8_t config_register = 0b11001100; // Initial configuration register value
    uint8_t bit_position = 5; // Starting position to set bits
    uint8_t num_bits = 3; // Number of bits to set
    uint8_t value_to_set = 0b101; // Value to set

    uint8_t new_config = set_bits(config_register, bit_position, num_bits, value_to_set);

    printf("New configuration register: 0b%08b\n", new_config);

    return 0;
}

Output

New configuration register: 0b10101100

Use Cases

  • Microcontroller Configuration:

    • Setting specific bits in microcontroller configuration registers for enabling or disabling features.
    • Configuring communication protocols (e.g., setting SPI mode bits).
  • Peripheral Settings:

    • Setting specific mode or control bits in peripheral devices such as sensors, actuators, or communication modules.
    • Configuring ADC channels, UART settings, or PWM outputs.
  • Protocol Implementation:

    • Efficiently setting specific bits in custom communication protocols or data packets.
    • Managing bit-fields in proprietary communication standards or interfacing with custom hardware.

The set_bits function is essential for efficient bit manipulation in embedded systems, enabling precise control and configuration of hardware components through bit-level operations.