## Bit manipulation in Arrays In AVR Embedded C

13 posts / 0 new
Author
Message

```        uint8_t r = {11110001,11100011,00011101,10101010,00001111};
uint8_t q = {1,2,3,4,5};

while (1)
{

int8_t ptr;
for(ptr=7;ptr>=0;ptr--)
{
if ((***q*** & (1<<ptr))==0)
{
UART_TxChar0('0');
}
else
{
UART_TxChar0('1');
}
}
_delay_ms(1000);
}
void UART_TxChar0(uint8_t data)
{
while((UCSR0A & (1<<UDRE0))==0);
UDR0 = data;

}```

When I write q (one which is highlighted)..which corresponds to 4, in serial monitor its equivalent Binary Number is printed 00000100.
But when I write r instead of q ...which correspondence to 10101010, in the serial monitor 00010010... this binary is printed.

why is it happening when I store normal decimal values then it is behaving properly, but when I store Binary values it is Showing something else.

Kunal Gupta

github.com/gkunalupta

Last Edited: Thu. Aug 27, 2020 - 02:42 PM

Those are not binary values. Those are decimal values that have only zeroes and ones in them.

IOW you missed the 0b prefixes

11110001 = eleven million, one hundred and ten thousand, and one

0b11110001 = two hundred and forty one

Or,

0b11110001 = 241 (decimal), or 0xF1 (hex), or 0361 (octal).

https://gcc.gnu.org/onlinedocs/g...

Okay, so guys, Now
I want to assign an integer array index in terms of the binary values.
So say back to the first code which I Posted, Variable data
Now i each index of this array data data data ... Has 8bits.
So now **I want to assign values to array index by binary values,** not by a decimal.
So I use clear_bit and set_bit functions to do so by the bit manipulation technique.
But on printing its binary value it is showing 0.
Code is here:

```    uint8_t x;
TCCR0B|= (1<<CS01);

for (int l = 0; l < 5; ++l)
{

for(int j = 7; j >= 0; --j)
{
TCNT0 = 0;
if (TCNT0 <100)          //20us to 35 us
{ CLEAR_BIT(x[l],j); //decimel0(TCNT0);printString0("\n");
}

else if (TCNT0 >100)     // 60us to 80us
{ SET_BIT(x[l],j); //printString0("\n");decimel0(TCNT0); printString0("\n");
}
}
}
decimel0(x);
printString0("\n");
_delay_ms(2000);```

Then by the help of the above answer, I figure out to assign binary values one needs to do that by adding **prefix 0b** followed by binary value as shown in the **r variable.**

So how should I add prefix Ob to the x thing which is in the for  loop? So that compiler can Know I want to assign Binary value.

Kunal Gupta

github.com/gkunalupta

Last Edited: Thu. Aug 27, 2020 - 06:32 PM

While you may assign a binary value to a variable (does not matter if an array member or not), neither the MCU nor the language cares.

For example, if you assign 0b00001000 to an 8 bit unsigned integer (or a character), the MCU and the compiler handles it  in exactly the same way as if you had assigned 0x08 or decimal 8. That is because those are simply different ways of interpreting the same pattern of bits.

Maybe to add a bit of emphasis to this, 0b00001000 + 0x04 + 2 = 0b00001110 = 0x0E = 14. It maks no difference.

Now, if you are assigining the binary value to set or clear bits in a register, you are far better off creating a named constant for the different bits then do (1<<XYENABLE) | (1<<XYCOUNTA) or XYENABLE_bm | XYCOUNTA_bm (the latter,. for the Mega-0 style register accesses).

Jim

Until Black Lives Matter, we do not have "All Lives Matter"!

Last Edited: Thu. Aug 27, 2020 - 07:58 PM
```TCNT0 = 0;
if (TCNT0 <100)          //20us to 35 us```

This is always true. Was that your intention ? Or just a bit of debugging ?

Your #1 program is more correctly written as:

```uint8_t r = {0b11110001, 0b11100011, 0b00011101, 0b10101010, 0b00001111};

void Kunalgupta(void)
{
for (uint8_t idx = 0; idx < 5; idx++)
{
if (idx)
UART_TxChar0(',');

{
if ((r[idx] & mask) == 0) {
UART_TxChar0('0');
}
else {
UART_TxChar0('1');
}
}
_delay_ms(1000);
}
UART_TxChar0('\n');
}
```

It will produce this output:

11110001,11100011,00011101,10101010,00001111

Last Edited: Thu. Aug 27, 2020 - 09:11 PM

ka7ehk wrote:
For example, if you assign 0b00001000 to an 8 bit unsigned integer (or a character), the MCU and the compiler handles it  in exactly the same way as if you had assigned 0x08 or decimal 8. That is because those are simply different ways of interpreting the same pattern of bits.
More precisely, they all represent the same non-negative integer.  In this case, they also all represent the same type, int.

Since 8 fits into the target type, nothing interesting happens.

For an unsigned target type and a value that does not fit,

modular arithmetic happens.

For a signed target type and a value that does not fit,

what happens is implementation-defined.

Moderation in all things. -- ancient proverb

Values are not binary or non-binary. Values are just values.

Constants you put in your code could be binary, decimal, hexadecimal, or whatever. But values aren't.

So when you have uint8_t x, the members of x are not "binary" or "not-binary". They're values between 0 and 255, and just as much they are values between 0b0 and 0b11111111. No difference.

the_real_seebs wrote:
Those are not binary values. Those are decimal values that have only zeroes and ones in them.

Not true.  Examine the last value...

Kunalgupta wrote:

`,00001111};`

.

.

.

.

.

.

It is octal.

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.