This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

How can map some bit in a array

Dear all,

I want to access some continus bit,let me can modify the value,such as,
for(i = 0 ; i < 10 ; i++)
{
bit[i] = ?;
}

but you know,the bit var cann't build as a array in keil c51,but build some boolean var with byte will speed down the MCU and more code,Who can give me a good advice and a way,Thanks in advance.

  • Hi,

    1) Keil does support Bit-addressable Objects. Read all about bdata memory, bit type, sbit keyword.
    2) you always are free to use ASM/ENDASM subroutines;
    3) something like:

    unsigned long bitfield, i;   //32-bits array
    
    for(i = 0 ; i < 10 ; i++)
    {
    // set:
    bitfield |= 1<<i;
    // reset:
    bitfield &= ~(1<<i);
    // read state:
    (bitfield & 1<<i)
    }
    ...but I have not checked how Keil Compiler process it...
    Good days!

  • The thing you're looking for doesn't exist, in that form, because the MCU can't do it either. So use masking and shifting on whole bytes. You may want to write your own little assembly functions or C macros to handle it.

  • Hi,

    I think you could do something like this:-

    #define noOfBits 10   /*required 'no of bits' in bit array */
    
    char bitNumber = 3;   /*  bit to access/test */
    char bArray[(noOfBits + 7)/8];  /* allocate enough space to store all bits */
    
    bArray[bitNumber/8] |= 1 << (bitNumber % 8); /* set bit */
    bArray[bitNumber/8] &= ~(1 << (bitNumber % 8)) /* reset bit */
    if (bArray[bitNumber/8] & (1 << (bitNumber % 8)) /* test bit none zero */
    
    

    The above does not allow you to (easily) declare your bits that you want to be stored in the bit array as 'bit bitName;'.
    It may be possible to write it more elegantly but hopefully this will give you some ideas on how to access bits, also you can 'enum' the bitNumbers to help clarify the bit positions in the array.

    Hope this helps,
    Mark.

  • you could try copying your byte into a bit-addressable temporary variable?

    you'd have to examine for yourself whether that's advantageous in your particular application.

  • Thanks every one in this message which give it a glance.
    But the way on above all is convert the bit array to a byte array,You compile the code will generate the asm code,all op code will be translated to byte operating mode,but you know,if we had build a array,and the member in the array is bit addressable var,some jump op will be translated as ,jb or jbc or jz and so on,this way will run more quickly and few code space,I had found no way to do this work,and I thinks embeding a piece asm code will be one way to resolve it.

    Waiting your good advice.

  • Paddy, your explanation is not at all clear, but it appears that you want the 8051 to do something which it just cannot. There is no "bit pointer" functionality in the 8051 design.
    If you want to access an array, then the assembler code has no choice but to use byte operations to access the required bit.

  • Paddy,

    your idea is fine, in principle, but unfortunately doesn't correspond to the reality of the 8051 processor family. You seem to be assuming that Keil wilfully withheld a useful feature of the CPU from being used by your C code. But they didn't --- it at all, it's IBM who did that, back when they designed the original 8051.

    There simply is no opcode in the 8051 machine language to indirectly access a bit, i.e. you can't compute the address of any bit and use the result of that computation to access it. This almost completely rules out array-of-bit as a C datatype. It still could be done, but only by use of methods that are practically guranteed to be even less efficient than the shift+mask technique which you so much would like to avoid.

    E.g. you could use self-modifying code, or a jump table to select one of a lot of hardwired "read bit #i" functions.

  • "IBM ... designed the original 8051"

    Eh??????????????????????????????????????????

  • OK, alright, so you caught me. 'Twas Intel, not IBM, of course.

  • What has been said about Keil C51 and the 8051 processor in other posts above is correct. Keil have, quite rightly, tried to stick as closely as possible to the C ANSI standard, but have provided just a few extra features to allow C programmers access to operations that the 8051 does particularly well – e.g. by adding the bit storage type.

    While weak in other areas, the one thing that the 8051 does do well is bit twiddling. So it is a pity that Keil did not take their extensions a little bit further and allow the implementation of an array of bits. While it is always possible to write your own code to access an array of bits with a fixed or variable index, the compiler will always be in a position to handle it better than hand-crafted code. The key difference is that with C source code accessing an individual bit the result is likely to be treated like a Boolean: occupying a whole byte and having either a zero or non-zero value. Consequently, the object code does not make as great a use of bit manipulation opcodes as one might hope.

    Something similar happens when declaring a structure that has fields defined as being one bit in size. It is very useful to define a word as a structure with some fields just one bit wide – do describe an I/O port for example. But, the compiler does not handle this situation efficiently.

    I assume nothing has changed since this thread (see end):

    http://www.keil.com/forum/docs/thread1291.asp

    Or this (see end):

    http://www.keil.com/forum/docs/thread1530.asp

  • Thansk all friend very much,Now I see,Though the bitaddress var is a good way to save the code area and speed up the MCU perfomance,but because the 8051's limit,The bitaddress var have no index register like the byteaddress var,So the pointer cann't assign to bit address var,and struct and union is also,the byte transfer is the only select,and I had test,Keil had trans the byte mode only 2 instruction (0) or 3instruction(1).

    Last word,Sorry my poor english.