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

accessing bitwise data in a data buffer

hi all,
iam a new to embedded programming and keil software.
i am struck with a problem how to access a bit in a data buffer.

the algo i need to implement is

data_buf of 32 bits is stored in the micro controller. i need to send those bits bit by bit. ie. starting from bit 0 to bit 31.

can anybody pls suggest me how to write a program in keil.

thanks in advance
uday

  • "iam a new to embedded programming and keil software."

    Do you know 'C' at all?
    If so, look at the shift and bitwise operators.

  • hi,
    i did not ask to teach me bitwise operators mr. andrew.
    if u had not read the mail sent by me properly, i repeat it again.

    i have declared a buffer holding a 32 bit value. i need to send that value on 3rd pin of port 0. my problem was how to access each bit of the buffer and send it. if i use a piece of code below..is it correct ?

    /**********
    unsigned int data_buf[40];
    unsigned int i;
    for (i=0;i<=39;i++)
    {
    P0^3 = data_buf[i];
    }
    *********/

    hope iam now clear in explaining the problem.
    thx
    uday

  • "i did not ask to teach me bitwise operators mr. andrew."

    True; I'm just suggesting that you can achieve your aim by using the standard ANSI 'C' bitwise logical operators (let's call them "mask" operators if it helps) and the standard ANSI 'C' shift operators.

    You didn't answer whether you're already familiar with 'C', so Look them up in your 'C' textbook, if necessary. Then think about what you're trying to achieve, what the operators do, and thus how to proceed.

    "i have declared a buffer holding a 32 bit value."

    No you haven't:

    unsigned int data_buf[40];
    You have declared a buffer containing 40 unsigned int values - in Keil C51, that's forty 16-bit values.
    See the Manual
    P0^3 = data_buf[i];
    Here, you're trying to send a whole unsigned int (16 bits) to a single port pin.

    Note that the sytax is wrong: the P0^3 is a Keil-specific extension to the language - it can only be used on the right-hand side of a bit definition.
    Elsewhere, the '^' operator performs its standard ANSI 'C' exclusive-OR function.
    See the Manual

    "my problem was how to access each bit of the buffer and send it."

    Exactly - and you can achieve this using the standard ANSI 'C' shift and "mask" operators!

    BTW: Note that you have commented-out the entire code:
    /********** comment starts here
    unsigned int data_buf[40];
    unsigned int i;
    for (i=0;i<=39;i++)
    {
    P0^3 = data_buf[i];
    }
    *********/ comment ends here!

    As you said you're new to embedded programming, note also that the 8051 is an 8-bit processor; therefore working with 16-bit and larger values is relatively inefficient.
    Since your array has only 40 members, you can use an unsigned char as the index instead of an int.

  • i have declared a buffer holding a 32 bit value. i need to send that value on 3rd pin of port 0. my problem was how to access each bit of the buffer and send it. if i use a piece of code below..is it correct ?

    /**********
    unsigned int data_buf[40];
    unsigned int i;
    for (i=0;i<=39;i++)
    {
    P0^3 = data_buf[i];
    }
    *********/


    No. This code will not work and does not match the description you provided. Ignoring the fact that the code is commented-out, even still it will not work.

    i have declared a buffer holding a 32 bit value.

    No, you have declared an array of 80 bytes (40 ints). Since bytes have 8-bits, your buffer holds 640 bits (not 32).

    i need to send that value on 3rd pin of port 0.

    OK, then why do you send 40 bits when your first sentence says you have 32 bits.

    my problem was how to access each bit of the buffer and send it.

    This is what Mr. Neil suggested with his comment to "look at the shift and bitwise operators."

    Have you looked at any of the example programs provided or looked into the 8051 download files ( http://www.keil.com/download/c51.asp)? There are several examples there that do similar things to what you want.

    Jon

  • Hehe, here's something really ugly, but it does just what you asked for, right? Unless, of course, you would like to further refine your specifications ;-)

    unsigned long bdata data_buf;
    sbit data_buf_0  = data_buf ^ 0;
    sbit data_buf_1  = data_buf ^ 1;
    sbit data_buf_2  = data_buf ^ 2;
    sbit data_buf_3  = data_buf ^ 3;
    sbit data_buf_4  = data_buf ^ 4;
    sbit data_buf_5  = data_buf ^ 5;
    sbit data_buf_6  = data_buf ^ 6;
    sbit data_buf_7  = data_buf ^ 7;
    sbit data_buf_8  = data_buf ^ 8;
    sbit data_buf_9  = data_buf ^ 9;
    sbit data_buf_10 = data_buf ^ 10;
    sbit data_buf_11 = data_buf ^ 11;
    sbit data_buf_12 = data_buf ^ 12;
    sbit data_buf_13 = data_buf ^ 13;
    sbit data_buf_14 = data_buf ^ 14;
    sbit data_buf_15 = data_buf ^ 15;
    sbit data_buf_16 = data_buf ^ 16;
    sbit data_buf_17 = data_buf ^ 17;
    sbit data_buf_18 = data_buf ^ 18;
    sbit data_buf_19 = data_buf ^ 19;
    sbit data_buf_20 = data_buf ^ 20;
    sbit data_buf_21 = data_buf ^ 21;
    sbit data_buf_22 = data_buf ^ 22;
    sbit data_buf_23 = data_buf ^ 23;
    sbit data_buf_24 = data_buf ^ 24;
    sbit data_buf_25 = data_buf ^ 25;
    sbit data_buf_26 = data_buf ^ 26;
    sbit data_buf_27 = data_buf ^ 27;
    sbit data_buf_28 = data_buf ^ 28;
    sbit data_buf_29 = data_buf ^ 29;
    sbit data_buf_30 = data_buf ^ 30;
    sbit data_buf_31 = data_buf ^ 31;
    
    sbit P0_3 = P0 ^ 3;
    
    void main (void)
    {
        P0_3 = data_buf_0;
        P0_3 = data_buf_1;
        P0_3 = data_buf_2;
        P0_3 = data_buf_3;
        P0_3 = data_buf_4;
        P0_3 = data_buf_5;
        P0_3 = data_buf_6;
        P0_3 = data_buf_7;
        P0_3 = data_buf_8;
        P0_3 = data_buf_9;
        P0_3 = data_buf_10;
        P0_3 = data_buf_11;
        P0_3 = data_buf_12;
        P0_3 = data_buf_13;
        P0_3 = data_buf_14;
        P0_3 = data_buf_15;
        P0_3 = data_buf_16;
        P0_3 = data_buf_17;
        P0_3 = data_buf_18;
        P0_3 = data_buf_19;
        P0_3 = data_buf_20;
        P0_3 = data_buf_21;
        P0_3 = data_buf_22;
        P0_3 = data_buf_23;
        P0_3 = data_buf_24;
        P0_3 = data_buf_25;
        P0_3 = data_buf_26;
        P0_3 = data_buf_27;
        P0_3 = data_buf_28;
        P0_3 = data_buf_29;
        P0_3 = data_buf_30;
        P0_3 = data_buf_31;
    }

  • "Unless, of course, you would like to further refine your specifications"

    Undoubtedly, some timing requirements must be added...

  • "Undoubtedly, some timing requirements must be added..."

    Indeed, and/or some clock signalling requirements.

  • Hi ALL,

    You can make use of mask to send bitwise onto a port.
    Take a look at this:
    sending LSB to MSB

    temp = 0x01;
    for(i=0;i<8;i++)
    {
    if(temp == (temp & byteTObeSent))
    {
    DATAPIN = 1;
    }
    else
    DATAPIN = 0;
    temp <<=1;
    }

    Think logically and code logically.

    Ravi

  • The earlier post has function code to send 1 byte.
    Now include a for loop for number of bytes and send each byte to this function.

    Cheers,
    Ravi

  • Yes, indeed it requires timing.

  • hi all,

    thanks for the overwhelming response that i received for my question. i have written the code for sending bit by bit data on a single pin of port 0 with reference to a clock.
    i thank one and all for the response
    cheers,
    Uday

  • Seems over-complicated to me:
    Why not just shift the 32-bit number, mask the LSB, and send it direct?

    for( i=0; i<32; i++ )
    {
       DATAPIN = wordToSend & 1;
       wordToSend >>= 1;
    }

  • HI,
    ofcourse that works for 32 bits and will occupy less instructions.
    I was considering a generic function which can send a byte. Depending on his size he may call this function accordingly.

    Cheers,
    Ravi

  • "I was considering a generic function which can send a byte."

    Even more reason to keep it simple:

    for( i=0; i<8; i++ )
    {
       DATAPIN = byteToSend & 1;
       byteToSend >>= 1;
    }
    If you were actually writing a generic fucntion, I think a pointer & size would be easiest.

    Or a hardware shift-register... ;-)