Forum: Compiler & IDEs Problem mit Mega8 Programm


von Fer T. (fer_t)


Angehängte Dateien:

Lesenswert?

Guten Abend zusammen,
Ich gebe es jetzt auf, ich habe seit 2 Tagen versucht (mehre Stunden an 
jeden Tag) den Fehler zu finden, ich habe jede Zeile 3 mal 
umgeschrieben, Code stellen einzeln getestet, aber ich kann ihn nicht 
finden...
Und zwar geht es um den Code im Anhang, er soll für die Auswertung eines 
Geigerzählers sein.
Als Display Lib wurde die aus diesen Forum benutzt (abgeändert auf 
PortC).
Das Problem ist, dass wenn ich die Schaltung einschalte, erst mal alles 
gut aussieht (Display wird initialisiert, Willkommen wird angezeigt, 
Geigerzähler fängt an zu ticken), aber es wird einfach nicht die 
errechnete Strahlendosis angezeigt.
Um das nur kurz auszuschließen: Schaltung ist richtig, und an dem 
externen Interrupt kann es auch nicht liegen, hatte den Code mal 
abgeändert, dass der mir die Anzahl der Klicks ausgibt, das klappte.
Dem der den Fehler findet, bin ich echt zu dank verpflichtet!
Also Danke!
MfG

von MWS (Gast)


Lesenswert?

Na, der Klassiker, in der ISR verwendete Variablen nicht volatile 
deklariert.

von Peter II (Gast)


Lesenswert?

Fer T. schrieb:
> Dem der den Fehler findet, bin ich echt zu dank verpflichtet!
also

Zeit = 0, count[240]

müssen volatil sein, weil du sie in der ISR änderst. (bei count bin ich

volatil int Zeit = 0;
volatil int count[240];

von Karl H. (kbuchegg)


Lesenswert?

Das fehlende volatile wurde ja schon angemeckert.

1
  click = (click / Zeit) * 240;

click ist ein int, Zeit ist ein int.
Damit verlierst du bei dieser Berechnung Genauigkeit.
100 dividiert durch 120 (als Beispielzahlen) ergibt nun mal 0 und nicht 
0.833.
Die nachfolgende Multiplikation mit 240 rettet das dann auch nicht mehr. 
Denn 0 mal 240 ist immer noch 0. Bei den gegebenen Zahlen (click = 100, 
Zeit = 120) wäre das korrekte Ergebnis aber 200 und nicht 0


1
itoa((click / 1000), Sv, 10);
2
itoa((click - ((click / 1000) * 1000)), _Sv, 10); 
3
4
while(i<=5){
5
 text[i] = Sv[i];
6
 i++;
7
}
wer sagt dir, dass der entsprechende Text 6 Stellen hat?
1
text[7] = _Sv[0];
2
text[8] = _Sv[1];
3
text[9] = _Sv[2];
und ob der 3 Stellen hat, steht auch in den Sternen. Ausserdem hast du 
nicht berücksichtigt, dass itoa keine führenden 0-en erzeugt. Die sind 
aber bei den Nachkommastellen essentiell wichtig! Denn 1.2 ist nun mal 
etwas anderes als 1.02

Wirf diese Ausgabe als ganzes über Bord und sei faul. sprintf erledigt 
dir die Feinheiten mit dem richtigen Formatstring.
1
  click = click * 240L / Zeit;
2
3
  sprintf( text, "%6d.%03d uSv/h", click / 1000, click % 1000 );
4
5
//SENDEN
6
  lcd_clear();
7
  lcd_home();
8
  lcd_string("Strahlendosis:");
9
  lcd_setcursor(0,2);
10
  lcd_string(text);

(und text solltest du nicht so knapp dimensionieren. Dir braucht nur 
eine Zahl überlaufen und schon wird der String länger als gedacht und du 
bügelst Speicher nieder.

So
1
  char text[] = { '0', '0', '0', '0', '0', '0', '.', '0', '0', '0', ' ', 'u', 'S', 'v', '/', 'h'};
ist das sowieso ganz schlecht, weil dein Array um 1 Position zu kurz 
ist. Du hast auf das bei Strings obligatorische abschliessende \0 
vergessen.

Wenn du es schon so machst, dann wenigstens so
1
  char text[] = { "000000.000 uSv/h" };
denn dann dimensioniert dir der Compiler das Array so gross, dass dieser 
String auch wirklich hineinpasst. Inclusive abschliessendes \0 am 
Stringende. (und der Compiler initialisiert den String auch mit diesem 
\0 am Ende)

von Karl H. (kbuchegg)


Lesenswert?

Wozu brauchst du eigentlich 6 Stellen vor dem Komma?

click ist ein unsigned int. Auf einem AVR sind das 16 Bit.
Die Zahl in click kann also per Definition nicht größer als 65535 sein.
Da du als Basiseinheit ein Tausendstel gewählt hast, kann der 
Vorkomma-Anteil niemals größer als 65 sein. Von 65 ist es aber noch weit 
bis zu 6 Stellen vor dem Komma.

von Fer T. (fer_t)


Lesenswert?

Hallo,
Danke schon mal, habe gerade das volatile geändert, jetzt wird schon mal 
0 angezeigt.

ich hatte das extra ohne sprintf gemacht, weil das so viel Speicher 
frisst, ohne war es 50% kleiner (siehe "Frage zum optimieren" Thread von 
mir).
Mit den Nullen hast du recht, das mit den drei stellen, habe ich 
gemacht, weil ich nur 2 Nachkommastellen haben wollte, aber du hast 
recht, wenn es 0-2 sind ist es sinnlos.
Du hast mir schon mal sehr geholfen, werde jetzt alles mal überprüfen 
mir deinen Vorschlägen!
MFG

von Karl H. (kbuchegg)


Lesenswert?

1
 for(zeit2 = 0; zeit2 <= 240; zeit2++){

Nein.
Dein Array umfasst nur 240 Einträge. Das bedeutet: ein Arrayelement mit 
dem Index 240 existiert nicht.

Mach dir das an kleineren Zahlen klar.

Wenn du dimensionierst

int b[5];

dann umfasst b 5 Elemente. Nämlich

b[0], b[1], b[2], b[3], b[4]

Zähl nach. Sind genau 5 Stück.

Eine Schleife die alle diese Werte aufsummiert, wäre

   Summe = 0;
   for( i = 0; i < 5; i++ )
     Summe = Summe + b[i];

von Karl H. (kbuchegg)


Lesenswert?

Wann und wo wird eigentlich das count Array jemals wieder auf 0 zurück 
gesetzt?

von Karl H. (kbuchegg)


Lesenswert?

Was denkst du, wird wohl passieren, wenn während dieser Codesequenz
1
if(bereit == '1'){
2
 for(zeit2 = 0; zeit2 <= 240; zeit2++){
3
  click += count[zeit2];
4
 }
5
}else{
6
  for(zeit2 = 0; zeit2 <= Zeit; zeit2++){
7
   click += count[zeit2];
8
  }
9
  click = (click / Zeit) * 240;
10
}

einer der beiden Interrupts kommt und dir die Zahlen (womöglich mitten 
während der Berechnung) umdreht?

von Fer T. (fer_t)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Wann und wo wird eigentlich das count Array jemals wieder auf 0 zurück
> gesetzt?

Nie, da ich mir dachte, dass das Interrupt, den wert von count[zeit] um 
eins hoch setzt, so muss man nur zeit ändern, aber verdammt du hast 
recht, so würde der wert immer nur erhöht Man bin ich da blöd gewesen...

von Karl H. (kbuchegg)


Lesenswert?

Fer T. schrieb:

> ich hatte das extra ohne sprintf gemacht, weil das so viel Speicher
> frisst, ohne war es 50% kleiner (siehe "Frage zum optimieren" Thread von
> mir).

Kriegst du von Atmel für nicht verwendeten Speicher Geld zurück?

Was ist dir lieber: Code der funktioniert und dafür ein wenig größer 
ist, oder Code zwar kleiner ist, aber nicht funktioniert?


Schalte beim Compiler die Optimierung mittels -Os ein und belasse es 
dabei. Nach allem was ich gesehen habe, bist du noch lange nicht so gut, 
dass Optimierung in irgend einer Form eine Rolle spielen sollte. Wenn du 
deinen nächsten Code einfach weniger umständlich schreibst, bringt dir 
das viel mehr als wenn du dir jetzt wegen ein paar 100 Bytes im sprintf 
Gedanken machst.

Du bist gerade dabei das Krabbelstadium hinter dir zulassen und gehen zu 
lernen. New York Marathon kommt später. Viel später.

von Fer T. (fer_t)


Angehängte Dateien:

Lesenswert?

Also erst mal: DANKE!
Hab jetzt mal einiges von deinen Vorschlägen umgesetzt, und ganz dreist 
es noch einfacher gemacht, und float benutzt.
Jetzt zeigt er mir schon mal mehr, nämlich: ? uSv/h
Mal sehen wie ich das in den Griff bekomme, ich habe auch noch nicht 
alles umgesetzt, was du gesagt hattest... naja
MfG

von Klaus D. (kolisson)


Lesenswert?

Fer T. schrieb:
> Also erst mal: DANKE!
> Hab jetzt mal einiges von deinen Vorschlägen umgesetzt, und ganz dreist
> es noch einfacher gemacht, und float benutzt.

Ich hab gerade den Artikel gelesen und musste oft hüsteln.
Fer t. .. obwohl ich dich als zuverlässig kenne muss ich aber
wegen der Wahrheit auf diesen Satz eingehen:

"und ganz dreist es noch einfacher gemacht, und float benutzt."

Lieber Fer,
glaubst du nicht, dass es milliarden von Programmiern auf der welt gibt,
die es so könnten ? Ist es nicht der Reiz , der einen dazu bringt es
besser zu können ?
Viele deiner Gesprächspartner , die du hattest taten das ...
und du: ich habs mir mal einfach gemacht und float genutzt
Ich fürchte... du must tiefer verstehen lernen.

Buchegger, Danneger und Hannes Lux .. nur als Beispiel,
taten es nicht anders.

Ferdinand, sei gelassen und komm zum Ziel.

Einer deiner Kunden:
Klaus

von Fer T. (fer_t)


Lesenswert?

So, es läuft!
Danke an alle!
(ok, nur noch eine Sache geht nicht: dieses verdammte delay will so 
lange laufen wie es soll...)
MfG

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.