I have to following code:
// Write screen n = sprintf( screen_msg, " TV: %#4.1f FV: %#4.1f CV: %#4.1f SV: %#4.1f\r\n", ad_value[2], ad_value[1], ad_value[0], ad_value[3] ); n += sprintf( screen_msg + n, " TI: %#4.1f AT: %#4.1f CT: %#4.1f ST: %#4.1f\r\n", ad_value[4], ad_value[5], ad_value[7], ad_value[6] ); n += sprintf( screen_msg + n, "\r\n" ); n += sprintf( screen_msg + n, "ENGINE CHARGE CLK EN DIS" ); write_0( screen_msg );
When the string is printed to my LCD CV, SV, and ST are always zero, regardless of the value in the ad_value array. If I print just those values in the same routine they appear as they should. When I debug the program the entire string appears as it should. My screen_msg buffer is 256 characters and the entire string in only 170.
I have looked over the code a dozen times and can't figure out what's going on. Can anyone see something that I may be missing?
Thanks, Paul
Hello,
Here is the root fault: sprintf() returns NUMBER OF CHARACTERS written (or a negative value if an output error occurred), so trying to use the n to shift pointer is totally wrong. Example: your first line would return 4 so at your 2nd line you refresh buffer starting at screen_msg[4] having had screen_msg filled-up well after that. And... from line to line you have even more interesting behaviour with shift value not really being grown as you probably expected - in reality, you are hitting near the same index.
So, while troubleshooting, it is worth to check values of every variable in the scope + get familiar with ANSI C functions description...
-- Nikolay.
Nikolay,
That is the way I have seen it written in pretty much every example that I have read. Should I check n after every sprintf() to make sure my index increments as expected?
Also, if I just write the first line I have the same results. No index is involved for that one.
Paul
I've never seen string handling done like that either (I like to keep things simple so would write sprintf to a temporary string and strcat() it to the message buffer after each step) but after a quick glance at your code I can't see why it shouldn't work.
How are you declaring screen_msg?
unsigned char xdata screen_msg[256];
Just remembered this: http://www.keil.com/support/docs/867.htm
Hmm, lost the end of the previous post..
Does the limitation apply to your situation?
Paul,
Sorry, I confused you with the notation of return value of sprintf(). The function does return number of characters written, so in my example I should be showing an estimate value around 40 (for floats like 1.1, 2.2, 3.3, ...), and not 4 as I wrote (0 omitted). In other words, what you have, YES, IT IS VALID WAY to go, but nevertheless care should be taken to check how the n is really changing - did you check it is changing? - Don't you hit the same index?
However typically in cases like this one I would use sprint() to temporary long enough buffer, then concatenate it to the main string using strcat() + do the verification no array boundaries are crossed.
Try to check whether XDATA places the buffer in a right location. You may just write to the buffer IMPLICITLY, then read it back. You may have problem accessing physical memory. Try place the string to the near memory/reduce size if needed, and play with the single line - does it help?
Regards, Nikolay.
Also, you may want to check whether ad_value[] buffer gets both its right values and location in the address space. Try to substitute ad_value[] with some constants when doing sprintf(). Try to write and then read back the ad_value[] to verify access is OK. Hope, some of it will help.
View all questions in Keil forum