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!
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.