Bit manipulation in Arrays In AVR Embedded C

Go To Last Post
13 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

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

        while (1)
        {

    int8_t ptr;
    	for(ptr=7;ptr>=0;ptr--)
    	{
    		if ((***q[3]*** & (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[3] (one which is highlighted)..which corresponds to 4, in serial monitor its equivalent Binary Number is printed 00000100.
But when I write r[3] instead of q[3] ...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
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IOW you missed the 0b prefixes

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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[5]
Now i each index of this array data[1] data[2] data[3] ... 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[5];
         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[1]);
        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[5] variable.**

So how should I add prefix Ob to the x[5] 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
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

To be clear about it.

 

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
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0
TCNT0 = 0;
if (TCNT0 <100)          //20us to 35 us

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Your #1 program is more correctly written as:

uint8_t r[5] = {0b11110001, 0b11100011, 0b00011101, 0b10101010, 0b00001111};

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

        for (uint8_t mask = 0b10000000; mask != 0; mask >>= 1)
        {
            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

 

 

BTW: I didn't understand what your #5 was about at all.

Last Edited: Thu. Aug 27, 2020 - 09:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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[5], 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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

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.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

There are only 10 types of people in the world, those who understand binary notation and those who don't.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

And yes, good point, the last value is indeed octal.