We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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
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)