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

using jb of a unsigned char in c

hello,
I would like to do a bit test of a unsigned char variable. It's like a jb in assembler.

here is my code in c.


unsigned char displ;
unsigned char display3 = 0xA8;
unsigned char i;
sbit display_data = P1^0;

displ = display3;
for (i=0; i<7; i++) {
        if (displ^0 == 1){
        display_data = 0;
        }
        else {
        display_data = 1;
        }
        displ>>=1;
}


I don't have any warning or error, but the result of test is wrong.
is it possible to do in c?

tkx.

  • Note that the '^' only has its Keil-specifc meaning in an sbit definition - elsewhere, it continues to be the standard 'C' exclusive-or operator.

    Have you looked at the C51 facility for bit-addressable objects?
    http://www.keil.com/support/man/docs/c51/c51_le_bitaddrobj.htm

    Without using C51's proprietary bit-addressable object extensions, you will have to use the standard 'C' bitwise mask operations...

    You might also want to look at http://www.keil.com/support/man/docs/c51/c51__testbit_.htm

  • This slightly modified example does what you want:

    C51 COMPILER V8.08a, COMPILATION OF MODULE DISPL
    OBJECT MODULE PLACED IN displ.OBJ
    COMPILER INVOKED BY: c51.exe displ.c CODE
    
    line level    source
       1          unsigned char    displ;
       2          unsigned char display3 = 0xA8;
       3          unsigned char       i;
       4          sfr            P1 = 0x90;
       5          sbit display_data = P1^0;
       6
       7          void test (void)  {
       8   1        displ = display3;
       9   1        for (i = 0 ; i < 7; ++i )  {
      10   2          if (displ & 0x01)  { // (displ^0 == 1){
      11   3            display_data = 0;
      12   3          }
      13   2          else {
      14   3            display_data = 1;
      15   3          }
      16   2          displ >>= 1;
      17   2        }
      18   1      }
    
                 ; FUNCTION test (BEGIN)
                                               ; SOURCE LINE # 7
                                               ; SOURCE LINE # 8
    0000 850000      R     MOV     displ,display3
                                               ; SOURCE LINE # 9
    0003 E4                CLR     A
    0004 F500        R     MOV     i,A
    0006         ?C0001:
                                               ; SOURCE LINE # 10
    0006 E500        R     MOV     A,displ
    0008 30E004            JNB     ACC.0,?C0004
                                               ; SOURCE LINE # 11
    000B C290              CLR     display_data
                                               ; SOURCE LINE # 12
    000D 8002              SJMP    ?C0005
    000F         ?C0004:
                                               ; SOURCE LINE # 13
                                               ; SOURCE LINE # 14
    000F D290              SETB    display_data
                                               ; SOURCE LINE # 15
    0011         ?C0005:
                                               ; SOURCE LINE # 16
    0011 E500        R     MOV     A,displ
    0013 C3                CLR     C
    0014 13                RRC     A
    0015 F500        R     MOV     displ,A
                                               ; SOURCE LINE # 17
    0017 0500        R     INC     i
    0019 E500        R     MOV     A,i
    001B B407E8            CJNE    A,#07H,?C0001
                                               ; SOURCE LINE # 18
    001E         ?C0006:
    001E 22                RET
                 ; FUNCTION test (END)
    

  • I don't have any warning or error, but the result of test is wrong.

    As Andy said - the ^ operator has special meaning only in sbit declarations. In all other cases, it is an XOR operator.

    is it possible to do in c?

    Yes, as long as the unsigned char is located in bdata memory and the appropriate bit within the char is declared with a sbit declaration. Refer to the compiler documentation, especially the chapter "Bit-Addressable Objects".

  • I detest the use of

      for (i = 0 ; i < 7; ++i )  {
    instead of
      for (i = 0 ; i < 7; ++i )
      {
    

    Is it just me that consider that style rendering the code unreadable?. In my opininion any '{' should be in the same column as the matchibg '}'

    now that I have been 'mean', let me be 'kind'

    instead of

      if (displ^0 == 1)
    use
    sbit Ralph displ^0
    ....
      if (Ralph)
    

    Erik

  • "I detest the use of..."

    It is purely a matter of style - and such debates always produce strong opinions.

    Others would say that they detest the useless waste of a line with just a '{' on it, that it unnecessarily breaks up the code, etc, etc...

    "Is it just me that consider that style rendering the code unreadable?"

    I don't know about "unreadable", but I also dislike it.

    However, this style has extremely good credentials - it's what messrs Kernighan & Ritchie themselves use in their definitive work on the subject!

    c-faq.com/.../layout.html

  • I used to detest that K&R style also, but after contracting for so many companies, each invariably with different coding style rules, I've learned to be at peace with whatever as long as it's consistent. For forum posts however, I have adopted the K&R style for the simple reason of conserving vertical space in threads.

    Right now, I'm contracting to the same outfit where the K and the R of K&R work, so guess which brace style I'm using at present. ;-)

  • This is not quite as K&R would have it:

    for (i=0; i<7; i++) {
            if (displ^0 == 1){
            display_data = 0;
            }
            else {
            display_data = 1;
            }
            displ>>=1;
    }
    


    "True" K&R style would be:

    for (i=0; i<7; i++) {
            if (displ^0 == 1){
                    display_data = 0;
            }
            else {
                    display_data = 1;
            }
            displ>>=1;
    }
    


    The "controlled" lines are indented relative to the "controlling" lines.

  • However, this style has extremely good credentials - it's what messrs Kernighan & Ritchie themselves use in their definitive work on the subject!

    I guess they did that to illustrate the lf/cr independence of C.

    so, this would be step one towards the 'ultimate' C program (the whole shebang in one line)

    OK, I agree that on matters of style everybody has a (different) opinion and the only reason I happened to bring it up was that this particular 'style' threw me off a bit in this case. I appreciate getting one 'yes' (makes me feel not crazy [in this respect]) and let us leave it at that.

    Erik

    PS re 'conserving linespace' I often do this
    if (blah)
    { // since blah is set .....

  • "PS re 'conserving linespace' I often do this
    if (blah)
    { // since blah is set ....."

    Yes - so do I!

    The comment aligns with the indented text:

    if( condition )
    {   // Condition is true - time to do stuff
        do_stuff();
        do_other_stuff();
        etc();
    }
    

  • well, fortunately, while we have to adhere to the syntax, we are free to improve on the style.

    I have a lingering suspicion that K&R are, at least partially, responsible for much of the "elegant" C that abounds

    Erik

    PS if anyone does not get that I am fastidious when stating "elegant" the are now told.

  • The standard, portable way to test bits in C has been presented -- the bitwise and (&).

    On an 8051, you can also test bits directly if the bit happens to be in an SFR or bit-addressable RAM.

    if (TI) ...

    It's generally not worth moving a bit to bit-addressable RAM just to access its bits. If a variable lives there, fine; if you just have some byte, use &.

    On the all-important braces question:

    - I agree that consistency is more important than any of the styles

    - Lef to my own devices, I go for seperate lines and indented braces:

        if (TI)
            {
            }
        else
            {
            }
    

    - My favorite style is not the Pascal/C "block statement" syntax, but rather the Algol/Modula/Ada style where the grammar allows multiple statements in control structures:

       if (TI)
       else
           for ()
           end
       end
    

    The begin/end {/} delimiters are grammatically unnecessary and just visual clutter. But there's nothing to be done about the C grammar at this point. Unfortunately, C is popular enough that nearly all the minor languages feel obliged to be "C-like" so that people will use them.

  • "On an 8051, you can also test bits directly if the bit happens to be in an SFR or bit-addressable RAM."

    To be precise, that should be "...in a bit-addressable SFR or bit-addressable RAM."

    Not all SFRs are bit-addressable.

  • Thanks for the correction. Not all SFRs are bit addressable.