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

Sprintf doesn't work correctly?

Hi,

First of all, I'm programming the T89C51CC01 Microcontroller using C51 with Keil µVision4. My head teacher wrote the following header file for it (source file also included) -- it's German:

//**************************************************************************
//Ferdinand von Steinbeis-Schule Reutlingen
//
//C - Funktionen - für LCD - Anzeige                             04.10.2007
//(angepasst für Atmel Controller)  (ae)
//**************************************************************************
#ifndef LCD
#define LCD
// Übersicht der Funktionen                          Header-Datei     lcd_zeitae.h

void init_lcd(void);            // Initialisierung für Atmel FVS Controller
void store(void);          //Daten übernehmen
void clear(void);          //Löscht LCD Bildschirm
void lcdsend(char* );     //Sendet Zeichenfolge an LCD Display (akt.Cursorpos)
void zeichen(char z1);     //Sendet ASCII Zeichen an LCD Display
void init(void);           //Initialisiert
void display(void);        //Schaltet auf entsprechenden Anzeigemodus um.
                          //Punktmatrix 5x7     1-zeilig mode = 00H
                          //(Nur dieser Mode verfügbar!)
                                                  //                              2-zeilig mode = 08H
                          //Punktmatrix 5x10    1-zeilig mode = 0CH
                          //                    2-zeilig mode = 04H
void rshift(void);        // Anzeigefenster des Displays um 1 Spalte rechts
void lshift(void);        // Anzeigefenster des Displays um 1 Spalte links
void currshift(void);     // Cursor um 1 Spalte rechts
void curlshift(void);     // Cursor um 1 Spalte links
void dis_off(void);       // Display aus
void dis_on1(void);       // Display on
void dis_on2(void);       // Display on mit Cursor
void dis_on3(void);       // Display on mit Blinkendem Cursor
void pos(char posi);      // Positioniert Cursor im Speicher des LCD Displays
                          // an n-te Stelle  Zeile 1 (00h-0Fh) Zeile 2 (40h-4Fh)
void home(void);          // Setzt Cursor an Display Anfang
//--------------------------------------------------------------------------------

//********************************************************************************
//Zeit- Funktionen

void sec(unsigned char s);                 //  Wartet n Sekunden
void msec(unsigned char ms);               //  Wartet n Millisekunden

//********************************************************************************


void wait(void);
void init(void);
void display(void);
void dis_on1(void);
void clear(void);
void pos(unsigned char posi);
void msec(unsigned char ms);
void sec(unsigned char s);
void zeichen(unsigned char z1);
#endif

This file can makes it easy to write something to the LCD-Display on the microcontroller.

Well, the file (normally) worked without a problem with Keil. Little examples:

// without sprintf

#include <t89c51cc01.h>
#include "fvs_bib_lcd.h"

void main(void)
{
    init_lcd(); // initialize

    pos(0x00); // cursor-position to the beginning
    lcdsend("Hello"); // print something to the lcd
}
// with sprintf


#include <stdio.h> #include <t89c51cc01.h> #include "fvs_bib_lcd.h"
void main(void) { char text[17]; // the variable we use to format the text
init_lcd();
pos(0x00); lcdsend("Hello");
pos(0x40); // beginning of the second line sprintf(text, "50 = %i", 50); // very trivial, I know lcdsend(text); }

The second example worked for me without a problem. But now the following "error" occured:

Every time I want to format a text, like

sprintf(text, "50 = %i", 50);

and print it on the display, I get:

Hello
50 = 12869

Now my question is, how can this be possible? It happened sometime ago, I don't know what the reason for that is... Can you help me please? Many thanks in advance!

Parents Reply Children
  • Yes, an 8-bit signed character have the range -128..127. And when you go from 127 to "128", you will set the sign bit making the value look like a negative number.

    But an 8-bit unsigned character (printed with u instead of d) has range 0..255 and is way cheaper for an 8-bit processor as long as 0..255 is enough numeric range.

    So in your case, your error was that you used an unsigned char (range 0..255) but called sprintf() and supplied the data type character "d" which represents signed data instead of "u" for unsigned data.

    So try:

    sprintf(t, "I: %bus", i); // s stands for seconds
    

  • Oh my gosh... I had to know that... but I'll need more than 255 in my program, so int is just fine. But thanks again, I could use that info for other things =)

  • Remember that when removing the "b" size character and using "int" or "unsigned" (short for "unsigned int"), you should still consider if you want a signed or unsigned variable.

    If you ask for input from a user, a signed variable may need a test "if (var >= 0 && var <= 10) then_ok();"

    While an unsigned variable might only need "if (var <= 10)" since it - by definition - can't be below zero. If you subtract 1 when it was already zero, the end result would be 65535 given a standard 16-bit number design.