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

pin writes optimized out

I am pretty new to this stuff, but I am usually able to work out problems on my own. I am trying to interface to some humidity sensor that uses it's own proprietary 2-wire serial interface (clock line and a data line). To make things easier, I declared sbits for each pin (SCK and DATA). When I try to compile and execute code like this:

.
.
DATA = 1;
SCK = 1;
error = DATA;
SCK = 0;
.
.

the compiler omits the line "SCK = 1". This is just an example, and it happens sporadically throughout the code. I read on some other posts that sbits are automatically volatile, and similar rumors, but the compiler is optimizing necessary lines out anyway. My compiler version is 6.20a. Thanks

  • Can you post the actual source code (including declarations) and generated code from the .lst file?

  • Thanks for the reply. Here's the code:
    #include <c8051f120.h>

    #define WAITTIME 0xFF

    // clock and data lines
    sbit SCK = P4^0;
    sbit DATA = P4^1;

    void Hold ()
    {
    unsigned char i;
    for (i = WAITTIME; i > 0; i--);
    }

    void StartTX ()
    {
    char SFRPAGE_SAVE = SFRPAGE;
    SFRPAGE = CONFIG_PAGE;
    DATA = 1;
    * SCK = 0;
    * Hold ();
    * SCK = 1;
    Hold ();
    DATA = 0;
    Hold ();
    * SCK = 0;
    * Hold ();
    * SCK = 1;
    Hold ();
    DATA = 1;
    Hold ();
    SCK = 0;
    SFRPAGE = SFRPAGE_SAVE;
    }

    *The lines with asterisks are ignored by the compiler.

    Here's the listing:
    C51 COMPILER V6.20a FOO 01/29/2004 10:35:42 PAGE 1


    C51 COMPILER V6.20a, COMPILATION OF MODULE FOO
    OBJECT MODULE PLACED IN .\Foo.obj
    COMPILER INVOKED BY: C:\Keil\C51\BIN\C51.EXE Z:\My Documents\tekno\Jsats Test\Foo.c DEBUG OBJECTEXTEND PRINT(.\Foo.lst)
    -OBJECT(.\Foo.obj)

    stmt level source

    1 #include <c8051f120.h>
    2
    3 #define WAITTIME 0xFF
    4
    5 // clock and data lines
    6 sbit SCK = P4^0;
    7 sbit DATA = P4^1;
    8
    9 void Hold ()
    10 {
    11 1 unsigned char i;
    12 1 for (i = WAITTIME; i > 0; i--);
    13 1 }
    14
    15 void StartTX ()
    16 {
    17 1 char SFRPAGE_SAVE = SFRPAGE;
    18 1 SFRPAGE = CONFIG_PAGE;
    19 1 DATA = 1;
    20 1 SCK = 0;
    21 1 Hold ();
    22 1 SCK = 1;
    23 1 Hold ();
    24 1 DATA = 0;
    25 1 Hold ();
    26 1 SCK = 0;
    27 1 Hold ();
    28 1 SCK = 1;
    29 1 Hold ();
    30 1 DATA = 1;
    31 1 Hold ();
    32 1 SCK = 0;
    33 1 SFRPAGE = SFRPAGE_SAVE;
    34 1 }


    MODULE INFORMATION: STATIC OVERLAYABLE
    CODE SIZE = 40 ----
    CONSTANT SIZE = ---- ----
    XDATA SIZE = ---- ----
    PDATA SIZE = ---- ----
    DATA SIZE = ---- ----
    IDATA SIZE = ---- ----
    BIT SIZE = ---- ----
    END OF MODULE INFORMATION.


    C51 COMPILATION COMPLETE. 0 WARNING(S), 0 ERROR(S)

    Thanks for any help you can give!

  • you missed:
    and generated code from the .lst file?

    Erik

  • You will need the CD option to see the code in the listing.

  • While we await the assembly output:

    What optimization level are you using? This sort of repetitive code makes the optimizer rub its hands with glee, as it groups common sequences into subroutines. Are you sure your missing instructions haven't migrated into an apparent subroutine call?

    Also, the Hold() routine could be optimized away entirely, since the loop does nothing. Take a look at the _nop_() intrinsic. For long delays, you'll probably want to use a timer. There are some good past threads on various ways to implement delay loops if you search the forum. If you do want to use a delay loop, you should probably "anchor" it in the code by giving it a loop body that can't be optimized away -- say incrementing an volatile variable.

  • I am sure the code was not executing because I was stepping through in debug mode, and no changes were occuring on those pins. Also, if I looked at the assembly code, there was no code present between successive pin changes. I tried writing a function to change the pin values, and calling it to fool the compiler, but that didn't work.

    I came up with the solution of putting those functions in a separate source file.
    void SetClock (char value);
    void SetData (char value);
    char GetData ();
    It works for now, and since this is an extremely short term project, I am not going to be able to explore the cause.

    By the way, the compiler was set to level 8 (default) optimization. I noticed that in the Keil environment, excluded code has a lighter gray bar to the left of the line. Surprisingly, the Hold routine does work, except for when it is called multiple times.

    Thanks to everyone who replied, and I'm sorry I can't dig deeper into this issue. Have a good day,
    Sean

  • When I compiled your example, I got the following:

    ASSEMBLY LISTING OF GENERATED OBJECT CODE
    
    
                 ; FUNCTION L?0006 (BEGIN)
    0000 C2C8              CLR     SCK
    0002 120000      R     LCALL   Hold
    0005 D2C8              SETB    SCK
    
    ; The above executes
    ;   SCK = 0;
    ;   Hold ();
    ;   SCK = 1;
    ; and then falls into the Hold routine
    
    
                 ; FUNCTION Hold (BEGIN)
                                               ; SOURCE LINE # 9
                                               ; SOURCE LINE # 10
                                               ; SOURCE LINE # 12
    ;---- Variable 'i' assigned to Register 'R7' ----
    0007 7FFF              MOV     R7,#0FFH
    0009         ?C0001:
    0009 DFFE              DJNZ    R7,?C0001
                                               ; SOURCE LINE # 13
    000B         ?C0004:
    000B 22                RET
                 ; FUNCTION Hold (END)
    
                 ; FUNCTION StartTX (BEGIN)
                                               ; SOURCE LINE # 15
                                               ; SOURCE LINE # 16
                                               ; SOURCE LINE # 17
    ;---- Variable 'SFRPAGE_SAVE' assigned to Register 'R6' ----
    
    
    char SFRPAGE_SAVE = SFRPAGE;
    0000 AE84              MOV     R6,SFRPAGE
                                               ; SOURCE LINE # 18
    SFRPAGE = CONFIG_PAGE;
    0002 75840F            MOV     SFRPAGE,#0FH
                                               ; SOURCE LINE # 19
    DATA = 1;
    0005 D2C9              SETB    DATA
                                               ; SOURCE LINE # 20
                                               ; SOURCE LINE # 21
                                               ; SOURCE LINE # 22
                                               ; SOURCE LINE # 23
    SCK = 0;
    Hold ();
    SCK = 1;
    Hold ();
    0007 120000      R     LCALL   L?0006
                                               ; SOURCE LINE # 24
    DATA = 0;
    000A C2C9              CLR     DATA
                                               ; SOURCE LINE # 25
    Hold ();
    000C 120000      R     LCALL   Hold
                                               ; SOURCE LINE # 26
                                               ; SOURCE LINE # 27
                                               ; SOURCE LINE # 28
                                               ; SOURCE LINE # 29
    SCK = 0;
    Hold ();
    SCK = 1;
    Hold ();
    000F 120000      R     LCALL   L?0006
                                               ; SOURCE LINE # 30
    DATA = 1;
    0012 D2C9              SETB    DATA
                                               ; SOURCE LINE # 31
    Hold ();
    0014 120000      R     LCALL   Hold
                                               ; SOURCE LINE # 32
    SCK = 0;
    0017 C2C8              CLR     SCK
                                               ; SOURCE LINE # 33
    SFRPAGE = SFRPAGE_SAVE;
    0019 8E84              MOV     SFRPAGE,R6
                                               ; SOURCE LINE # 34
    001B 22                RET
                 ; FUNCTION StartTX (END)
    

    The compile did not optimize out the instructions you indicate. Instead, it created common functions for them.

    I labeled each instruction with the lines of the C program that are executed.

    Jon