Forum: Compiler & IDEs sprintf, printet nicht mehr.


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Board G. (boardgeist)


Lesenswert?

Hallo.
Ich Programmiere an einem Freescale µC in Codewarrior, ProzessorExpert.
Die angebotenen Routinen sind laut ProzessorExpert ANSIc.

Mein problem ist leicht, war auch schon gelöst, aber jetzt geht es 
plötzlich nicht mehr.
1
          char ADCwert[20],ADCwert2[20],ADCwert3[20],ADCwert4[20];
2
             extern byte ADC, ADC2,ADC3,ADC4;
3
  
4
 I2C_ADC()
5
 { 
6
  I2C_SelectSlave(0x49);
7
 /* 
8
 I2C_SendChar(0x40);
9
 I2C_SendChar(0x40);
10
 I2C_SendChar(0xFF);    
11
 */
12
13
 I2C_SendChar(0x40);
14
 I2C_RecvChar(&ADC);
15
 I2C_SendChar(0x41);
16
 I2C_RecvChar(&ADC2);
17
 I2C_SendChar(0x42);
18
 I2C_RecvChar(&ADC3);
19
 I2C_SendChar(0x43);
20
 I2C_RecvChar(&ADC4);
21
 
22
   if(schreiben==1)
23
 {
24
   sprintf(ADCwert,"rueckgabe1: %i",ADC);
25
   sprintf(ADCwert2,"rueckgabe2: %i",ADC2);
26
   sprintf(ADCwert3,"rueckgabe3: %i",ADC3);
27
   sprintf(ADCwert4,"rueckgabe4: %i",ADC4);
28
  I2C_LCD_send_string_xy("   ",12,0);
29
  I2C_LCD_send_string_xy("   ",12,1);
30
  I2C_LCD_send_string_xy("   ",12,2);
31
  I2C_LCD_send_string_xy("   ",12,3);
32
   I2C_LCD_send_string_xy(ADCwert,0,0);
33
   I2C_LCD_send_string_xy(ADCwert2,0,1);
34
   I2C_LCD_send_string_xy(ADCwert3,0,2);
35
   I2C_LCD_send_string_xy(ADCwert4,0,3);
36
   };
37
   
38
 }//Ende ADC-Routinen

Das ist der Code, ein Wert wird von I2C-ADC abgegriffen (was überprüft 
wurde im real-time-debugger) und dann am Display dargestellt.
Damit der Wert Display fähig ist, jage ich ihn durch sprintf.

Das hat bis jetzt immer funktioniert, nur plötzlich kommt anstelle 
meines schönen strings nur ein schwarzes Kästchen am Display und laut 
Debugger ist das char-array auch leer.
sprintf verweigert somit nun seinen Dienst.

Hab ich eine andere Wahl? Woraus kann soetwas resultieren obwohl ich an 
der funktion nichts verändert habe?
Mfg

von Philipp Karbach (Gast)


Lesenswert?

hast du mal deine hardware gecheckt? normalerweise resultieren solche 
fehler NUR weil man falsch programmiert. sprintf geht eigentlich nie 
kaputt.

von Board G. (boardgeist)


Lesenswert?

Ja :)
im true time simulator haben aber die byte-werte noch den ADC Wert und 
geändert habe ich nix... hab mir jetzt was eigenes geschrieben das 
dez->ASCII macht... nicht so toll wie sprintf aber es geht... .

MfG

von Board G. (boardgeist)


Lesenswert?

Hm,
habe etwas geschrieben was sprintf ersetzen soll:

Aufruf:
1
zahlzuascii(antw,&antw2[0]);
2
I2C_LCD_send_string_xy(antw2,0,3);

Funktion:
1
//sprintf ERSATZ:
2
zahlzuascii(byte zahl,unsigned char *adresse)
3
  { unsigned char text[3];
4
  
5
      if(zahl>99) {text[2]=((zahl%10)+0x30); zahl=zahl/10;} else text[2]=0x30;
6
      if(zahl>9)  {text[1]=((zahl%10)+0x30); zahl=zahl/10;} else text[1]=0x30;
7
      if(zahl>0)  {text[0]=((zahl%10)+0x30);} else text[0]=0x30;
8
       adresse[2]=text[2]; adresse[1]=text[1]; adresse[0]=text[0];
9
       
10
  }//ende zahlzuascii

Nur, wenn ich diese fkt aus main.c Aufrufe, funktioniert es(123 in 
ascii). Rufe ich es aber aus der Baugruppen.c ab bekomme ich immer 000 
zurück.

Variabelen:
byte antw=123;
unsigned char antw2[10]="";

in I2C.h mit extern und ohne =zuweisung, in main.c genau-so(ohne extern 
und zuweisung).

wieso klappt das aus der main.c und aus der baugruppe.c nicht??
MfG

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Variabelen:
> byte antw=123;
> unsigned char antw2[10]="";
>
> in I2C.h mit extern und ohne =zuweisung, in main.c genau-so(ohne extern
> und zuweisung).

Was soll das heißen?

von Karl H. (kbuchegg)


Lesenswert?

Board Geist wrote:
> wieso klappt das aus der main.c und aus der baugruppe.c nicht??

Ich vermute mal, dass du keinen Protoypen dafür hast.
Kriegst du keine Compiler Warnings?

Übrigens hat deine Funktion einen bösen Fehler: sie setzt
kein abschliessendes '\0' Byte um den String zu terminieren.

Man könnte das ganze auch etwas einfacher schreiben, aber
was solls:
1
void zahlzuascii(byte zahl,unsigned char *adresse)
2
{
3
  adresse[0] = ( zahl / 100 ) + '0';
4
  zahl = zahl % 100;
5
6
  adresse[1] = ( zahl / 10 ) + '0';
7
  zahl = zahl % 10;
8
9
  adresse[2] = zahl + '0';
10
11
  adresse[3] = '\0';
12
}//ende zahlzuascii


von Board G. (boardgeist)


Lesenswert?

d.h.:

in der main.c befindet sich ein include der I2C_Prim.h, in der 
I2C_Prim.h befindet sich ein include für I2C_Baugruppen.c
---
in der main.c steht:

byte antw;
unsigned char antw2[10];
UND include für I2C_Prim.h
---
in der I2C_Prim.h steht:

extern byte antw;
extern unsigned char antw2[10];
UND
zahlzuascii(...);
//Auskommentierung
UND include für I2C_Baugruppen.c
---
in der I2C_Baugruppen.c steht:

byte antw=123;
unsigned char antw2[10]="";
UND
zahlzuascii(...)
{tuewas;};
-----

steht der Aufruf jetzt in der main(){hier;};
bekomme ich aus (byte)123 ein (char)"123"

wird der aufruf über eine main(){pollingfkt;}; Welche sich z.b. bei 
einem Tastendruck auslöst, gestartet.. kommt aus meinem (byte)123 ein 
(char)"000"

Die gleiche fkt, nur woanders aufgerufen, sogar die gleichen Variablen.. 
da ja extern.
das byte wird mir auch richtig im realtime-manager als 123 angezeigt, 
immer.
das char halt nicht.

was mach ich falsch?
--
Edit1:
Nein, Warnings bekomme ich nicht, also eig. schon aber ich habe ein paar 
Timings geändert und mein Compiler ist der Meinung jedes einzelne mit 
"Abweichung von Standart" anzuzeigen.
Mehr als 50 Warnings bekomme ich nicht.. .

von Karl H. (kbuchegg)


Lesenswert?

> zahlzuascii(...);

steht das so drinnen?

Wenn ja, dann wundert es mich nicht, dass deine
Werte falsch rüberkommen.
Benutze keine variadischen Funktionen wenn du nicht
musst! Wenn du sie aber benutzt, dann achte drauf, dass
dann einige Standardkonvertierungen gelten. Insbesondere
wird auf der Aufrufseite ein uint8_t (also dein byte)
automatisch auf einen int hochgecastet. Damit stimmt
aber die Byte-Anzahl am Stack auf der Aufruferseite
nicht mit dem überein, was sich der Aufgerufene vom
Stack holt. Eigentlich ein Wunder, dass das keinen
Absturz produziert hat.

Also: schreib den Protoypen aus
Deine Funktion sieht so aus

zahlzuascii(byte zahl,unsigned char *adresse)
{
  ...
}

und genau das schreibst du auch in den Protoypen in
I2C_Prim.h:

zahlzuascii(byte zahl,unsigned char *adresse);

Alles andere ist: ask for troubles

von Karl H. (kbuchegg)


Lesenswert?

Board Geist wrote:
> Mehr als 50 Warnings bekomme ich nicht.. .

Die solltest du alle bereinigen.
Viele der Warnings mögen harmlos sein, aber einige sind es
nicht. Und genau die gehen dann in den Warnings unter.

In der professionellen Softwareentwicklung werden Warnings
nicht ohne Grund wie Fehler behandelt. Ein Programm muss
ohne Fehler und ohne Warnings compilieren.

von Board G. (boardgeist)


Lesenswert?

Mein Prototyp: (Ausschnitt)
1
//Funktionen im I2C_Baugruppen:;
2
void I2C_Relai(bool eins,bool zwei,bool drei,bool vier);;
3
void I2C_DAC1(byte WertDac);
4
void I2C_DAC2(byte WertDac);
5
void I2C_DAC3(byte WertDac);
6
void I2C_DAC4(byte WertDac);
7
void I2C_DAC5(byte WertDac);
8
void I2C_DAC6(byte WertDac);
9
void I2C_DAC7(byte WertDac);
10
void I2C_DAC8(byte WertDac);
11
 DAC_Test();
12
 I2C_ADC();
13
 FehlerOderBefehl();
14
 Fehler0();
15
 Fehler1();
16
 Fehler2();
17
 Fehler3();
18
 Steuer0();
19
 Steuer1();
20
 Steuer2();
21
 Steuer3();
22
void AlleFehlerMenuAusgabe(byte design);
23
 Uhr_auslesen_LCD();
24
 zahlzuascii(byte zahl,unsigned char *adresse);

Das ist doch richtig, oder soll ich es hier Ausschreiben?
Du meintest nur das (...), oder?

von Karl H. (kbuchegg)


Lesenswert?

Board Geist wrote:
> Das ist doch richtig, oder soll ich es hier Ausschreiben?
> Du meintest nur das (...), oder?

Ja, das meinte ich.

Also hast du das doch richtig und vielleicht auch gelernt,
dass du deinen Code nicht beschreiben sollst, sondern den
tatsächlichen Code posten sollst. Ansonsten kommt es nämlich
zu Missverständnissen und ich habe absolut keine Lust Fehlern
nachzujagen und zu beschreiben die du gar nicht gemacht hast.

Kannst du ein kleines Testprojekt bauen, welches den Fehler
zeigt?

von Board G. (boardgeist)


Lesenswert?

Ein Testprojekt?

zahlzuascii(antw,&antw2[0]) in main-> (dort hatte ich es nur zu 
testzwecken) -> antw2="ZahlAusAntwInASCII";

Verschoben in I2C_Baugruppen, -> antw2="000"
,
verschieb ich es wieder zurück-> antw2="123"
---
Das ist genau so n Mist wie das mit dem sprintf (code oben)
Das hat Funktioniert, ich habe nichts daran verändert, der string bleibt 
leer.
Eines Zeigt mir mein Praktikum: das hier, werde ich nie Professionell 
Beruflich machen. (genau um das herauszufinden amche ich es ja)



++++++++++++++++++

Wegen den Warnings:
Ich kann die Timings nicht zurückändern... also ich kann schon, nur im 
Std. sehe ich so 1 char/sek auf dem Display erscheinen. Wenn er dafür 
dann solange braucht, muss alles andere warten und das Gesammtkonzept 
geht nicht mehr auf
MfG

von Karl H. (kbuchegg)


Lesenswert?

Board Geist wrote:
> Ein Testprojekt?
>
> zahlzuascii(antw,&antw2[0]) in main-> (dort hatte ich es nur zu
> testzwecken) -> antw2="ZahlAusAntwInASCII";
>
> Verschoben in I2C_Baugruppen, -> antw2="000"
> ,
> verschieb ich es wieder zurück-> antw2="123"

Sorry, aber nur mit der Beschreibung wird dir hier beim
besten Willen keiner helfen können. Du hast einen Fehler
gemacht, kommt vor. Aber wir hier, auf der anderen Seite
des Bildschirms, können nicht Gedanken lesen, noch können
wir in deinen Sourcen nach dem Fehler suchen. Was wir
tun können, machen wir. Und wir machen es, weil wir es
gerne machen. Aber du musst auch mitmachen. Und wenn es
dir zuviel Arbeit ist, einen 10 Zeiler dem Prinzip nach
genauso aufzusetzen wie es in deinem realen Projekt der
Fall ist, dann ist mir weiteres Rätselraten auch zuviel
Arbeit.

Noch einen schönen Tag

von Board G. (boardgeist)


Lesenswert?

Ich meine, was ist ein Testprojekt?

Du hast den Quellcode von ZahlzuAscii, der Aufruf steht beschrieben, 
genau dieser steht mal in der main() und mal in der pollingfkt().

Was bedeutet jetzt ein Testprojekt?
Ein Structogramm?

Egal, einen Versuch wars Wert hier.

MfG + Danke für die Tipps bis jetzt + einen schönen Tag ebenso.

von Uhu U. (uhu)


Lesenswert?

Eine int -> ASCII-Wandlung muß man nicht selbst schreiben -- die gibt es 
bereits in der C-RTL: itoa

von Karl H. (kbuchegg)


Lesenswert?

Board Geist wrote:
> Ich meine, was ist ein Testprojekt?

Na, ein Testprojekt halt:

Nimm deine Funktion her, fang ein neues Projekt an
und bau dort die Funktion ein. Dieses Testprojekt
baust du genauso auf, wie das an dem du gerade arbeitest,
nur dass alles was nicht direkt mit dem Problem zu tun
hat in diesem Testprojekt nicht enthalten ist.

Dann stellst du noch sicher, dass sich dieses Testprojekt
genau so verhält (gleicher Fehler) wie dein reales
Projekt und postest das.

Dadurch brauchen wir nicht durch hunderte von Funktionen
und Codezeilen waten und können uns auf das Problem
konzentrieren.

>
> Du hast den Quellcode von ZahlzuAscii, der Aufruf steht beschrieben,
> genau dieser steht mal in der main() und mal in der pollingfkt().

Wie sieht das genau aus?
Beschreibe es nicht sondern poste den Code.
Dein Problem mag eine Kleinigkeit sein, die du ständig
übersiehst.

> Was bedeutet jetzt ein Testprojekt?

Im Grunde ist es dein Projekt, wobei alles was nicht zum
unmittelbaren Problem gehört weggelassen wird.
Aber: Es soll compilierbar sein und es muss den gleichen
Fehler zeigen.

Aber ansonsten: gleiche Filestruktur, gleiche Funktionen

Testprojekt: Die zu untersuchende Funktionalität in ein
kleines Programm verpackt, das sich nur um diese Funktionalität
dreht und indem man, losgelöst vom Rest deines realen Projektes
genau diese Funktionalität testen kann.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.