Forum: Mikrocontroller und Digitale Elektronik µC rechnet falsch oder ich finde den Fehler nicht


von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich habe hier ein seltsames Problem.

Ich möchte in meinem Progamm Daten aus dem PROGMEM verarbeiten und 
berechnen. Im PROGMEM habe ich eine Tabelle (eigentlich sind es mehrere 
hier nur zur Veranschaulichung des Codes eine) mit 175 Faktoren 
hinterlegt.

Das Programm befüllt dann eine Variable im Flash während der Laufzeit 
(zu Beginn) aufgrund dieser Daten nach folgender Vorschrift:
1
int16_t  ssaTabelle = 0;    
2
3
ssaTabelle[n] = ( ((int32_t)((F_CPU*60)/120000))*((int32_t)(ssaTabelle[n] + VERSCHIEBEWERT)) )/((n+1)*3);

Zuvor wegen in ssaTabelle die Daten des aus der PROGMEM-Tabelle 1:1 
kopiert (nach dem kopieren steht hier auch 1:1 das drin, habe ich über 
UART ausgeben lassen).

Nun kommt dort aber nach der Berechnung nicht das raus, was ich von Hand 
zu Fuß rechne. Das kuriose ist, teile ich die Rechnung in einzelne 
"Häppchen" und arbeite mit Zwischenergebnisse, rechnet sich alles 
korrekt. Obwohl sich meiner Meinung nach die Rechnung mit den 
Zwischenergebnissen von den Datentypen her nicht unterscheidet.

Dabei rechne ich wie folgt: (ZWE steht für Zwischenergebnis)
1
uint16_t ZWE1 = 0;
2
int16_t ZWE2 [ANZAHL2] = {0};
3
int32_t ZWE3 [ANZAHL2] = {0};
4
int16_t ZWE4 [ANZAHL2] = {0};
5
ZWE1= ((F_CPU*60)/120000);
6
ZWE2[n]=(ssaTabelle[n] + VERSCHIEBEWERT);
7
ZWE3[n]= ((int32_t)ZWE1)*ZWE2[n];
8
ZWE4[n]= ZWE3[n]/((n+1)*3);

Anbei der Codeteil des Programms inkl. der Datentypen. Ich habe aufgrund 
der Übersicht erstmal die ganzen Initialsierungen rundherum weggelassen 
außer die hier verwendeten Variablen/Datentypen. Der Code ist daher so 
nicht compilierbar.

Anbei hänge ich auch noch ein Mitschnitt aus der UART (UART-Daten.txt), 
worüber ich debugge. Dort werden die Werte sowohl von den 
Zwischenergebnissen (Ausnahme ZWE1) ausgegeben und die vom µC 
gerechneten (nach obiger "Gesamtformel") Werte, siehe Code-Ausschnitt.
Wie man sieht, unterscheidet sich ZWE4 (das Endergebnis) vom dem 
Ergebnis, was vom µC in einem Rutsch nach obiger Formel gerechnet wurde.

Über Hilfe wäre ich dankbar.

Ach ja, Prozessor ist ein Atmega168.

Über jede Hilfe bin ich dankbar.

Beste Grüße
David

von David Menzeln (Gast)


Lesenswert?

Achso, noch etwas.
Wie man sieht, sind manche Werte korrekt berechnet und manche nicht. 
Anfangs sind mehr falsche Werte als gegen Ende (siehe UART-Daten.txt)

von Karl H. (kbuchegg)


Lesenswert?

Hä?
1
int16_t  ssaTabelle = 0;    
2
3
      for (uint8_t n=0; n<ANZAHL2+25; n++){        // von 0 bis 23 mit 0 befüllen
4
        if (n<24){                    
5
          ssaTabelle[n] = 0;
6
        }
7
        else{                    // danach auslesen und nach Formel berechnen                    
8
          
9
          ssaTabelle[n] = pgm_read_word (&TabellePROGMEM[1][n-24]);   
10
        }

ssaTabelle ist doch gar kein Array!
Wie um alles in der Welt hast du das überhaupt durch den Compiler 
gebracht?

von Stefan E. (sternst)


Lesenswert?

1
#define ANZAHL2 175
1
int16_t ZWE2 [ANZAHL2]
= 350 Bytes RAM
1
int32_t ZWE3 [ANZAHL2]
= 700 Bytes RAM
1
int16_t ZWE4 [ANZAHL2]
= 350 Bytes RAM

== 1400 Bytes nur für diese 3 Arrays

> Ach ja, Prozessor ist ein Atmega168.

RAM-Größe = 1024 Bytes


PS:
Und was bitte soll das darstellen?
1
int16_t  ssaTabelle = 0;    
2
...              
3
          ssaTabelle[n] ...
Ist ssaTabelle nun ein einzelner int16_t, oder ein ganzes Array?

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

David Menzeln schrieb:
> Der Code ist daher so nicht compilierbar.

Tut mir Leid, da ist mir beim herunterbrechen des Codes für das Forum 
hier ein Fehler passiert.
Im eigentlichen Programm ist es ein array und ist so definiert:
int16_t ssaTabelle [ANZAHL2+25] = {0};

Und die ganzen arrays der ZWE sehe ich gerade sind auch [ANZAHL2+25] und 
nicht nur [ANZAHL2]

Anbei nochmal die main "korrigiert"

Was mir gerade noch aufgefallen ist beim Durchsehen der UART-Debug 
Datei:
Sobald dieser Ausdruck (ssaTabelle[n] + VERSCHIEBEWERT) positiv wird, 
scheinen sämtliche Berechnungen zu stimmen. Nur sofern dieser negativ 
ist, kommt offensichtlich Datenmüll raus.

von Karl H. (kbuchegg)


Lesenswert?

David Menzeln schrieb:
> David Menzeln schrieb:
>> Der Code ist daher so nicht compilierbar.
>
> Tut mir Leid, da ist mir beim herunterbrechen des Codes für das Forum
> hier ein Fehler passiert.

Das mögen wir hier gar nicht, wenn du Code postest, der so nicht auf dem 
µC gelaufen ist.

> Im eigentlichen Programm ist es ein array und ist so definiert:
> int16_t ssaTabelle [ANZAHL2+25] = {0};
>
> Und die ganzen arrays der ZWE sehe ich gerade sind auch [ANZAHL2+25] und
> nicht nur [ANZAHL2]

Also noch mehr!
Das ändert nichts daran, dass du in Summ schon viel mehr Daten zu 
speichern versuchst, als du überhaupt SRAM hast.

von Karl H. (kbuchegg)


Lesenswert?

David Menzeln schrieb:

> Sobald dieser Ausdruck (ssaTabelle[n] + VERSCHIEBEWERT) positiv wird,
> scheinen sämtliche Berechnungen zu stimmen. Nur sofern dieser negativ
> ist, kommt offensichtlich Datenmüll raus.

ok. das ist ein Hinweis.
WIe ist n definiert?

signed oder unsigned?

von David Menzeln (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Also noch mehr!
> Das ändert nichts daran, dass du in Summ schon viel mehr Daten zu
> speichern versuchst, als du überhaupt SRAM hast.

Ok, dazu habe ich gleich eine Frage. Beim Compilieren bekomme ich 
folgendes angezeigt:
Data:        679 bytes (66.3% Full)
(.data + .bss + .noinit)

Ist das das SRAM?

Darüber hinaus habe ich diese "Geschichte" mit dem ZWE's nur eingefügt, 
da die Berechnung in "einem Rutsch"
1
ssaTabelle[n] = ( ((int32_t)((F_CPU*60)/120000))*((int32_t)(ssaTabelle[n] + VERSCHIEBEWERT)) )/((n+1)*3);

nicht geklappt hat. Lasse ich diese ganzen ZWE Variablen weg, geht es 
ebenso nicht. Da ich den Fehler dort vermutete, habe ich eben diese 
ganzen ZWEs hinzuprogrammiert, um zu sehen, in welchem Rechenschritt 
sich ein Fehler eingeschlichen hat.
Das kuriose ist ja aber, mit diesen ZWEs, wo der SRAM Speicher ja 
überlaufen müsste, funktioniert es, solange man alles nacheinander 
berechnet (siehe UART-Mitschnitt).

von David Menzeln (Gast)


Lesenswert?

n ist ein uint8_t n=0

von Stefan E. (sternst)


Lesenswert?

David Menzeln schrieb:
> Ok, dazu habe ich gleich eine Frage. Beim Compilieren bekomme ich
> folgendes angezeigt:
> Data:        679 bytes (66.3% Full)
> (.data + .bss + .noinit)
>
> Ist das das SRAM?

Ja, aber nur der statische Verbrauch. Die ZWE* sind da nicht mit drin.

David Menzeln schrieb:
> Lasse ich diese ganzen ZWE Variablen weg, geht es
> ebenso nicht.

Da auch ssaTabelle eine dynamische Variable ist, bist du auch schon ohne 
die ZWE "drüber".

PS: Ok, sehe gerade, dass Letzteres eher nur geraten ist. Anhand deines 
Pseudo-Codes lässt sich nämlich gar nicht sagen, ob sie statisch oder 
dynamisch ist.

von David Menzeln (Gast)


Lesenswert?

Stefan Ernst schrieb:
> Da auch ssaTabelle eine dynamische Variable ist, bist du auch schon ohne
> die ZWE "drüber".

Und welche Variablen sind dann dort mit drin? Wenn du von dynamischen 
sprichst, werden es wohl die statischen sein. Aber welche sind die 
statischen, woran erkenne ich sie?

Und kann daher der Fehler kommen? Aber wieso ist die Berechnung dann 
richtig, wenn ich es in "Häppchen" unterteile?

von Karl H. (kbuchegg)


Lesenswert?

David Menzeln schrieb:
> Stefan Ernst schrieb:
>> Da auch ssaTabelle eine dynamische Variable ist, bist du auch schon ohne
>> die ZWE "drüber".
>
> Und welche Variablen sind dann dort mit drin? Wenn du von dynamischen
> sprichst, werden es wohl die statischen sein. Aber welche sind die
> statischen, woran erkenne ich sie?
>
> Und kann daher der Fehler kommen? Aber wieso ist die Berechnung dann
> richtig, wenn ich es in "Häppchen" unterteile?

Weil du zufällig auf irgendwelchen SRAM Zellen agierst, auf denen sonst 
nichts liegt.

Das ist doch alles Stochern im Nebel.
Bau ein ordentliches Testprogramm, das man starten, testen und debuggen 
kann.

von Fabian O. (xfr)


Lesenswert?

David Menzeln schrieb:
> Und welche Variablen sind dann dort mit drin? Wenn du von dynamischen
> sprichst, werden es wohl die statischen sein. Aber welche sind die
> statischen, woran erkenne ich sie?

Die Variablen, die Du außerhalb von Funktionen definierst sind statisch. 
Sie sind die ganze Programmlaufzeit über vorhanden. Deren 
Speicherverbrauch wird nach dem Compilieren angezeigt.

Die "dynamischen" (besser: automatischen) Variablen sind die, die Du 
(ohne static) innerhalb einer Funktion definierst. Die existieren nur, 
solange die Funktion läuft und werden auf dem Stack angelegt. Wie viel 
Platz die verbrauchen kann man nach dem Compilieren nicht sagen, weil 
das davon abhängt, welche Funktionen Du in welcher Reihenfolge aufrufst, 
was wiederum von Benutzereingaben etc. abhängen kann. Deshalb siehst Du 
deren Speicherverbrauch nicht. Das gilt übrigens auch für Variablen, die 
Du in der main-Funktion definierst ...

Wenn Du Dir nur Zwischenergebnisse zum Debuggen ausgeben willst, 
brauchst Du doch aber keine riesigen Arrays anlegen. Es reicht eine 
einzelne Variable für jedes Zwischenergebnis. Erstell am besten ein 
lauffähiges Minimalbeispiel, das Dein Problem zeigt. Vielleicht findest 
Du den Fehler ja sogar selber, wenn Du nach und nach alle Schritte 
weglässt, die den Fehler nicht verursachen.

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Leider bin ich noch nicht weiter, aber ich habe wunschgemäß 
compilierbaren Code erzeugt aus dem Pseudo Code mit gleichem Ergebnis.
Das Programm ist nur mit UART ausgestattet (Lib von Peter Fleury).

In dem nun angehängten Fall habe ich wieder die Zwischenrechnungen 
eingefügt. Diese sind korrekt und entsprechen einer Hand zu Fuß. Die 
Rechnung der "in einem Rutsch" Formel ist dennoch anders.
Anbei hierzu auch, was der UART ausgibt in der UART-Daten1.txt

Damit keine Probleme bezüglich des SRAMs auftreten können, folgt gleich 
noch das selbe Programm ohne die Zwischenrechnungen nur mit dem einen 
Array int16_t ssaTabelle [ANZAHL2+25] = {0};

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

So und nun das ganze ohne die Zwischenrechnungsschritte.

Was man dem UART entnehmen kann, dass egal ob ich die Zwischenrechnung 
Arrays einfüge, das Ergebnis der "in einem Rutsch" Formel ist immer 
gleich (falsch).

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Eine weitere Erkenntnis, aber keine Lösung.
Schreibe ich die am 08.01.2013 um 22:02 Uhr gepostete main.c den 
"else-Teil" so:
1
        else{                    // danach auslesen und nach Formel berechnen
2
          
3
          ssaTabelle[n] = pgm_read_word (&TabellePROGMEM[0][n-24]);                          
4
          // Für UART Debugging
5
          // Erstes Zwischenergebnis Konstant = 8000 wird vom Compiler gerechnet
6
          ZWE1= ((F_CPU*60)/120000);
7
              
8
          // Zweites Zwischenergebnis
9
          ZWE2[n]=(ssaTabelle[n] + VERSCHIEBEWERT);
10
        
11
          // Drittes Zwischenergebnis
12
          ZWE3[n]= ((int32_t)ZWE1)*ZWE2[n];
13
        
14
          // Viertes Zwischenergebnis
15
          ZWE4[n]= ZWE3[n]/((n+1)*3);
16
17
          // ENDE UART Debugging
18
        
19
          // Eigentliche Rechnung vom µC gerechnet
20
          uart_puts_P("µC gerechnet: ");
21
          ssaTabelle[n] = ( ((int32_t)((F_CPU*60)/120000))*((int32_t)(ssaTabelle[n] + VERSCHIEBEWERT)) )/((n+1)*3);
22
          ltoa( ssaTabelle[n], buffer1, 10 );
23
          uart_puts(buffer1);
24
          uart_puts_P("  ");
25
        }

d.h. ich berechne zwar die Zwischenergebnisse ZWE* aber lasse die 
Ausgabe der Zwischenergebnisse per UART weg, so kommt hier ebenfalls ein 
falsches Ergebnis raus (UART-Auswertung anbei als txt, ebenso die 
vollständige main, uart.c und uart.h identisch).

Demnach scheint es irgendwie nicht an den Zwischenergebnissen zu liegen, 
sondern die dazwischen liegende UART Ausgabe führt zum richtigen 
Ergebnis. Aber wieso?

Ich nutze AVR Studio 5 und den darin enthaltenen GCC Compiler, falls das 
eine Rolle spielt.

von David Menzeln (Gast)


Lesenswert?

Kann es sein, dass der Compiler irgendetwas fehlintepretiert von den 
Datentypen her?

Ich habe ja festgestellt, dass wenn dieser Ausdruck
1
(ssaTabelle[n] + VERSCHIEBEWERT)
nicht mehr negativ ist, sondern >= 0, rechnet der µC richtig. Nur bei 
negativem Vorzeichen kommt nicht das richtige Ergebnis raus. Daher habe 
ich die vage Vermutung, dass es irgendwo mit Vorzeichen etwas zu tun 
haben muss.

von Karl H. (kbuchegg)


Lesenswert?

Nimm doch den Teil hier
1
int16_t ZWE2 [ANZAHL2+25] = {0};
2
int32_t ZWE3 [ANZAHL2+25] = {0};
3
int16_t ZWE4 [ANZAHL2+25] = {0};
4
int16_t ssaTabelle [ANZAHL2+25] = {0};

mal aus dem main raus und mach sie global.
Und dann siehst du dir deine Memory Statstik an, wie weit dein SRAM 
gefüllt ist.
Alleine diese 4 Arrays sind 1000 Bytes. Wenn da jetzt von der UART noch 
was dazu kommt, du sonst noch ein bischen was brauchst und der Stack 
auch noch dazu kommt, dann könnte das schon eng werden.

Oder noch einfacher:
Wenn du wissen willst, ob deine Berechnung irgendwo schief geht, dann 
specke halt dein Programm NUR auf die Berechnung ab. Um die Berechnung 
zu testen, brauchst du die ganzen Arrays nicht! Die sind erst mal nur 
etwas, was dir Ärger im Speicher machen kann, weil sie so groß sind!

Zum Testen geht man auf die einfachste Variante, die man sich vorstellen 
kann. Jedes zusätzliche Teil ist nur wieder eine potentielle 
Fehlerquelle mehr. Testprogramme können gar nicht einfach genug sein!

von Karl H. (kbuchegg)


Lesenswert?

David Menzeln schrieb:

> Daher habe
> ich die vage Vermutung, dass es irgendwo mit Vorzeichen etwas zu tun
> haben muss.

Die Vermutung ist zwar naheliegend, aber sie ist nicht die einzige 
Vermutung die man machen kann.
Denn deine 'negativen Werte' haben auch gemeinsam, dass sie allesamt am 
Anfang deines Progmem Arrays stehen. D.h. wenn du dir ungewollt den 
Speicher niederbügelst, dann kann es sich zufällig auch so ausgehen, 
dass du genau diesen Speicherbereich niedermähst, in der zufällig genau 
diese Werte stehen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

David Menzeln schrieb:
> Kann es sein, dass der Compiler irgendetwas fehlintepretiert von den
> Datentypen her?
Welche Optimierung hast du eingeschaltet?
Wie sieht das Assemblerlisting aus?

Was kommt eigentlich da raus: ((n+1)*3)
Spätestens beim uint8_t n=85 könnte das interessant werden...

von Karl H. (kbuchegg)


Lesenswert?

Konkret.
Was spricht dagegen, wenn dein erstes Testprogramm mal so aussieht
1
int main()
2
{  
3
  char buffer1 [12];
4
  int16_t pgmWert;
5
  itn16_t wert;
6
  
7
  init_ports();                      // Ports initialisieren  
8
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
9
10
  for (uint8_t n=0; n<ANZAHL2; n++)
11
  {
12
    pgmWert = pgm_read_word (&TabellePROGMEM[0][n]);                          
13
    wert = pgmWert + VERSCHIEBEWERT;
14
15
    ltoa( pgmWert, buffer1, 10 );
16
    uart_puts(buffer1);
17
    uart_puts_P("  ");
18
    ltoa( wert, buffer1, 10 );
19
    uart_puts(buffer1);
20
    uart_puts_P("\n");
21
  }
22
23
  while( 1 )
24
    ;
25
}

Wenn die Zahlen gut aussehen, dann ergänzt du sukzessive die Berechnung, 
bis sie komplett ist.

von David Menzeln (Gast)


Lesenswert?

Hallo Karl-Heinz,

erst einmal nochmals danke für den erneuten Post und Weiterverfolgung 
des Themas und das Engagement, dass du hier im Forum an den Tag legst.

Ich hatte gestern Abend diese Variante bereits versucht und habe die 
Zwischenergebnisse ZWE* als ganz normale Variablen (keine Arrays*) 
definiert:
1
int16_t ZWE2 = 0;
2
int32_t ZWE3 = 0;
3
int16_t ZWE4 = 0;
4
int16_t ssaTabelle [ANZAHL2+25] = {0};

Leider kam das gleiche falsche Ergebnis raus.
Und hier war ich bei 2+4+2+400 = 408 bytes + ein bisschen aus dem UART.

Und wie auch am 08.01.2013 22:03 Uhr gepostet, selbst wenn ich die 
ganzen ZWE* weglasse und nur die normale Berechnung mache (also 
Minimal+UART) wird das Ergebnis falsch.

Ich bin auch gerne für Vorschläge offen, etwas zu testen und poste das 
Ergebnis dann. Aber im Moment weiß ich nicht mehr weiter bzw. wo ich 
noch ansetzen sollte.

Dein Programmvorschlag werde ich testen. Dies kann ich aber erst gegen 
späten Nachmittag tun. Berichte dann hier weiter.

*Die Arrays habe/hatte ich nur drin, da ich das debuggen per LCD gemacht 
hatte und Schritt für Schritt die Werte ausgeben wollte (Index habe ich 
über "Taster-gesteuert" hochgezählt für die Ausagbe). Da ich aber für 
hier die Ergebnisse für einen Post hier im Forum sichtbar machen wollte, 
schrieb ich sie später auf die UART-Schnittstelle, damit ich sie 
kopieren und posten kann.

___________________________

Hallo Lothar,

ich habe an dem Grundeinstellung von AVR-Studio erste einmal nichts 
geändert. Daher weiß ich nicht, welche Optmierung da eingeschaltet ist, 
muss ich nachsehen…(ich glaube aber Standard ist 0s, oder?) Ich habe ein 
Projekt erstellt, die beiden Dateien UART-Dateien hinzugefügt und 
compiliert. Ein seperates makefile habe ich nicht erstellt. Kann das 
automatisch erstelle makefile aber gerne dazu mal anhängen.

Bezüglich des Assemblerlistings: Kann ich gerne posten, aber ebenfalls 
frühstens gegen späten Nachmittag (bin vorher nicht zu Hause).

Das ((n+1)*3) müsste ich noch auf die Schnittstelle schreiben.
Das Problem tritt ja aber bereits früher in der Rechnung ab n=25.
Die "höheren" n's rechnet er ja richtig (sobald der Ausdruck 
(ssaTabelle[n] + VERSCHIEBEWERT) >=0 wird). Ein Versuch ist es Wert. 
Testweise kann ich n ja auch mal als uint16_t deklarieren.

Danke.

von Bernd (Gast)


Lesenswert?

wieso tut ihr Euch das eigentlich an?
Solange der TO keinen kompilierbares (und kurzes!) Programm postet dass 
den Fehler zeigt ist es doch Masochismus sich zu bemühen

von David Menzeln (Gast)


Lesenswert?

Bernd schrieb:
> wieso tut ihr Euch das eigentlich an?
> Solange der TO keinen kompilierbares (und kurzes!) Programm postet dass
> den Fehler zeigt ist es doch Masochismus sich zu bemühen

Ab 22:03 habe ich (TO) 3x kompilierbare (kurze!) Programme gepostet 
inkl. der Ausgaben auf der UART-Schnittstelle.

von David Menzeln (Gast)


Lesenswert?

Lothar Miller schrieb:
> Welche Optimierung hast du eingeschaltet?

Unter Vorbehalt sage ich mal, dass dies das Problem war.
Optimierung war auf -O1. Augenscheinlich auf -Os funktioniert es 
(zumindest UART-Ausgabe von oben gepostetem Code ist nun richtig 
berechnet).

Das Programm in seinem vollen (nicht abgespeckt) teste ich heute noch, 
dann gebe ich nochmal Bescheid.

von David Menzeln (Gast)


Lesenswert?

So noch abschließend: Mit der -Os läuft das ganze auch im vollständigen 
Programm richtig berechnet.

Nochmals danke an alle beteiligten, die sich mit Geduld hier Mühe machen 
in Ihrer Freizeit.

von Fabian O. (xfr)


Lesenswert?

Damit ist das Problem aber nicht gelöst, sondern nur verdeckt. Wenn das 
Programm korrekt ist, muss es mit jeder Optimierungseinstellung 
funktionieren. Früher oder später fliegt Dir das wieder um die Ohren, 
wenn Du den Fehler nicht behebst.

von Besserwisser (Gast)


Lesenswert?

Wie passt denn das zusammen?

int16_t pgmWert;
....
ltoa( pgmWert, buffer1, 10 );
long to ascii

Beitrag "Re: ltoa funktioniert nicht?!"

von Besserwisser (Gast)


Lesenswert?

Daneben stimmt die Klammerung und das Casting nicht:
1
ssaTabelle[n] = ( ((int32_t)((F_CPU*60)/120000))*((int32_t)(ssaTabelle[n] + VERSCHIEBEWERT)) )/((n+1)*3);
2
3
versuche mal
4
5
ssaTabelle[n] = ( (          (F_CPU*60)/120000L)*((int32_t) ssaTabelle[n] + VERSCHIEBEWERT ) )/((n+1)*3L);

Oder mache int32_t ssaTabelle[n]   statt int16_t


Du erwartest bei n=24 folgende Werte:
ZWE2[n]=(ssaTabelle[n] + VERSCHIEBEWERT);
       =  -190         +      120        = -70

ZWE3[n]= ((int32_t)ZWE1)*ZWE2[n];
       =    8000        * -70            = -560000  FFFFFFFFFFF77480

ZWE4[n]= ZWE3[n]/((n+1)*3);
       = -560000 / 75                    = -7466,666 FFFFFFFFFFFFE2D6

Es kommt aber 19621 0x4CA5 heraus.

                     hier immer 74
                                ||
n=                              vv
24  19621 *25*3= 1471575  0x00167457
25  11305 *26*3=  881790  0x000D747E
26   3604 *27*3=  291924  0x00047454
27  -3546 *28*3= -297864  0xFFFB7478
28  -10204*29*3= -887748  0xFFF2743C
29  -16417*30*3=-1477530  0xFFE97466
30  -22230*31*3=-2067390  0xFFE07442
                            ^^^^
                            dieser Wert wird um 9 weniger

> sobald der Ausdruck (ssaTabelle[n] + VERSCHIEBEWERT) >=0 wird
das ist ab n=85+24=109 der Fall (-120+120=0). n: 109 µC gerechnet:
-14696*110*3=-4849680 = FFB5FFF0

> mal aus dem main raus und mach sie global.
D.h. schreibe sie vor der main hin!

Versuchsweise mal
#include<math.h>  benutzen!

von Bernd (Gast)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Was spricht dagegen, wenn dein erstes Testprogramm mal so aussieht

was spricht dagegen den Vorschlag von Karlheinz mal auszuprobieren und 
das Ergebnis zu posten?

von David Menzeln (Gast)


Lesenswert?

Nichts.
Ich hatte nur bis dato gedacht, dass durch die Optimierungsumstellung 
das Problem gelöst sei und der Vorschlag dadurch "hinfällig" ist weiter 
zu verfolgen.

Ich weiß nicht, ob ich heute dazu komme (eher nicht), aber ich werde 
spätestens morgen den Vorschlag umsetzen und das Ergebnis posten.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

David Menzeln schrieb:
> Ich hatte nur bis dato gedacht, dass durch die Optimierungsumstellung
> das Problem gelöst sei und der Vorschlag dadurch "hinfällig" ist weiter
> zu verfolgen.
Das ist die "Kopf in den Sand" Taktik eines Straußes(*). Und in einem 
Jahr musst du aus irgenwelchen Gründen eine andere Optimierung 
einstellen, und wunderst dich dann, dass nichts mehr geht...


(*) die so allerdings gar nicht stimmt:
http://de.answers.yahoo.com/question/index?qid=20060709112056AAgLqJQ

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Lothar,

ich wusste nicht, dass es auf allen Optimierungen laufen muss. Ich hatte 
selbiges mal bei einer Inbetriebnahme eines LCDs und dort wurden die 
delays wegoptimiert. Es ging nur auf bestimmten 
Optimierungseinstellungen. Daher meine Unwissenheit, dass es daran 
liegt.

Das Programm von Karl Heinz (main.c, UART-Daten4) habe ich compiliert. 
Die Werte sind ok.
Programm anbei. Die UART.c und UART.h spare ich mir mal mit dem 
anhängen.

Ich poste gleich noch das Programm von Karl Heinz erweitert, bis der 
Fehler auftritt. Mache aber dies getrennt, um jedes Programm separat 
erst einmal anzuhängen mit dem UART-Mitschnitt.

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

So und nun habe ich das Programm um diese Variable erweitert:
1
int32_t wert2;

In die Variable wird folgendes geschrieben (ebenfalls ergänzt im 
Programm):
1
wert2 = ((F_CPU*60)/120000L)*((int32_t)wert);

Sonst habe ich, bis auf weitere UART-Ausgaben nichts ergänzt.

wert ist dabei das int16_t aus dem Programm von Karl Heinz (und wird 
soweit auch noch in diesem Programm richtig berechnet, siehe 
UART-Mitschnitt). Zur Sicherheit habe ich es auf ein int32_t gecastet.
((F_CPU*60)/120000L) ist konst = 8000.

Diese Berechnung geht allerdings in die Hose, siehe UART-Daten5.txt
wert2 hat nicht den Wert, welches es haben sollte. Ich habe bei der 
UART-Ausgabe den Variablen-Namen davor ergänzt und auch die Zählvariable 
n zur Übersicht noch mit ausgeben lassen.

Optimierungseinstellung auf -O1.

Besserwisser schrieb:
1
ssaTabelle[n] = ( (          (F_CPU*60)/120000L)*((int32_t) ssaTabelle[n]  >+VERSCHIEBEWERT ) )/((n+1)*3L);

Diese Variante habe ich übrigens auch durch den Compiler gejagt und 
debugged, ebenfalls falsche Werte.

von Fabian O. (xfr)


Lesenswert?

Probier mal:
1
wert2 = (int32_t) (F_CPU * 60 / 120000UL) * wert;

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Habe ich gerade versucht, liefert das gleiche falsche Ergebnis wie das 
Programm vom Post Datum: 10.01.2013 17:04.
Anbei wie gehabt Programm+UART-Mitschnitt.

von Fabian O. (xfr)


Lesenswert?

Auffällig ist halt, dass die unteren 24 Bit des Ergebnisses stimmen, nur 
die oberen 8 Bit sind falsch:

         Dezimal:  Binär:
Korrekt:  -560000  1111 1111 1111 0111 0111 0100 1000 0000
Falsch:  16217216  0000 0000 1111 0111 0111 0100 1000 0000

Funktioniert das jetzige Programm denn, wenn Du die Optimierung auf -Os 
stellst? Was ist, wenn Du (F_CPU * 60 / 120000UL) durch 8000L ersetzt? 
Oder wert2 einfach mal -560000 zuweist, wird das wenigstens richtig 
ausgegeben?

Probier auch mal die Berechnung von wert2 direkt vor den Aufruf von 
ltoa() zu stellen. Passiert das gleiche? Eventuell überschreibt eine 
Funktion fälschlicherweise das oberste Byte von wert2.

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Fabian O. schrieb:
> Funktioniert das jetzige Programm denn, wenn Du die Optimierung auf -Os
> stellst?

Ja, das geht.

Fabian O. schrieb:
> Was ist, wenn Du (F_CPU * 60 / 120000UL) durch 8000L ersetzt?

Das gleiche (falsche) Ergebnis.

Fabian O. schrieb:
> Probier auch mal die Berechnung von wert2 direkt vor den Aufruf von
> ltoa() zu stellen. Passiert das gleiche? Eventuell überschreibt eine
> Funktion fälschlicherweise das oberste Byte von wert2.

Funktioniert ebenfalls leider nicht. Habe dieses Programm anbei gehängt 
inkl. UART-Mitschnitt und darin ist übrigens auch (F_CPU * 60 / 
120000UL) durch 8000L ersetzt.

von Bernd (Gast)


Lesenswert?

schreib doch Mal

wert2 = 16217216
ltoa(wert2...

hin um zu kontrollieren ob ltoa das richtige macht

von Bernd (Gast)


Lesenswert?

sorry, natürlich
wert2 = -560000

von David Menzeln (Gast)


Lesenswert?

Bernd schrieb:
> wert2 = -560000

Ja, ltoa() macht das richtig, auf der Schnittstelle landet -560000.
Das Programm läuft auch nicht richtig mit diesem berechneten (falschen) 
Wert auf -O1. Daher traue ich auch ltoa(), denn wäre der Wert richtig, 
nur falsch gewandelt/ausgegeben, würde das Programm sauber laufen, wie 
es mit -Os tut.

von eProfi (Gast)


Lesenswert?

stell mal die Ausgabe um auf CR-LF  und lasse die Bezeichner weg, damit 
es besser lesbar wird:
    uart_puts_P("\n"); --->  uart_put(13);uart_put(10);


Bitte erstelle ein File mit n  und den erwarteten gewünschten Werten 
wert1, wert2 etc.

mache wert zu int_32


Wozu ist das ganze?  Stepper-Delay?

von Fabian O. (xfr)


Lesenswert?

Ich habe mal versucht das Problem bei mir zu reproduzieren. Ich habe 
allerdings nur Xmega-Hardware hier, daher musste ich andere 
UART-Routinen benutzen. Es kommen aber unabhängig von der 
Optimierungseinstellung die richtigen Ergebnisse raus.

Hast Du vielleicht noch einen anderen Mikrocontroller, mit dem Du es 
testen kannst? Nicht, dass genau die eine SRAM-Zelle defekt ist ... Auch 
wenns wohl ziemlich unwahrscheinlich ist, aber mehr fällt mir leider 
nicht mehr ein.

von David Menzeln (Gast)


Lesenswert?

Nochmal ein Danke für alle Mühe bis dato.

Ich habe das schon auf zwei verschiedenen Atmega168 versucht, beide mit 
gleichem Problem.
Chips waren fabrikneu.

Ich könnte es mal auf einem Atmega8 versuchen, dazu brauche ich aber 1-2 
Tage, da ich die Schaltung auf dem Steckbrett mit THT Bauteilen 
nachstellen müsste, da ich die jetzige Hardware auf einer fertigen LP 
aufgelötet habe als SMD mit TQFP Atmega168, das ist schwierig den Chip 
umzufummeln.

@eProfi
Tut mir Leid, das habe ich nicht ganz verstanden, was ich machen soll.

von hele (Gast)


Lesenswert?

Versuch mal:
Wert2 = wert;
Wert2 *= 8000;

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Der Ansatz mit
1
Wert2 = wert;
2
Wert2 *= 8000;
war irgendwie nicht verkehrt.

Damit funktioniert es (main.c und UART8.c):
1
  for (uint8_t n=0; n<ANZAHL2+25; n++)
2
  {
3
    if (n<24){                    
4
          pgmWert = 0;
5
      }
6
      else{   
7
      pgmWert = pgm_read_word (&TabellePROGMEM[0][n]);                          
8
      wert = pgmWert + VERSCHIEBEWERT;
9
      wert2=wert;
10
      wert2 = (((int32_t) (F_CPU * 60 / 120000UL))*wert2)/;
11
      wert2 = wert2/((n+1)*3);
12
      ltoa( wert2, buffer1, 10 );
13
      uart_puts_P("wert2:");
14
      uart_puts(buffer1);
15
      uart_puts_P("  ");
16
    }  
17
  }

Ziehe ich dies
1
wert2 = (((int32_t) (F_CPU * 60 / 120000UL))*wert2)/;
2
wert2 = wert2/((n+1)*3);
allerdings zu einer Rechnung zusammen:
1
wert2=wert;
2
wert2 = (((int32_t) (F_CPU * 60 / 120000UL))*wert2)/((n+1)*3);
geht es wieder nicht (siehe UART-Daten9.txt).

Gleichzeitig habe ich heute einen Atmega8 angeschmissen, auch bei ihm 
verhält sich das gleich. Es scheint ein Problem mit dem Compiler zu 
sein.

Ich nutze AVR-Studio 5 mit AVRGCC V.3.3.1.27

von Bernd (Gast)


Lesenswert?

David Menzeln schrieb:
> wert2 = (((int32_t) (F_CPU * 60 / 120000UL))*wert2)/;

das ließ sich übersetzen?

von Karl H. (kbuchegg)


Lesenswert?

Hmm. Hab den Thread jetzt längere Zeit nicht beobachtet und heute keine 
Zeit mehr, da selbst mal ein paar Versuche anzustellen.

Aber, probier mal n auf einen int8_t zu ändern. Also einen Wechsel von 
unsigned Datetyp zu signed. Schön langsam kann ich mich mit der These, 
dass da im Compiler irgendwas schief läuft anfreunden.

von Gedankenspiel (Gast)


Lesenswert?

Gedankenspiele!

wert2 ist laut code ein int32_t.

David Menzeln schrieb:
> (((int32_t) (F_CPU * 60 / 120000UL))*wert2)

Hier wird ein int32_t mit einem int32_t multipliziert. Das Ergabnis 
könnte also im Zahlenraum eines int64_t liegen. Ich gehe davon aus, dass 
der Compiler das berücksichtigt.

Das ganze wird aber wert2 zugewiesen. Hier wird implizit ein Cast auf 
int32_t gemacht, also die oberen 32 bit weggeworfen. Keine Ahnung, ob 
hier auf Vorzeichen geachtet wird.

> wert2 = (((int32_t) (F_CPU * 60 / 120000UL))*wert2)/((n+1)*3);

Hier wird direkt ein int64_t durch ein int16_t dividiert (n = int8_t * 
int8_t). Das Ergebnis könnte ebenfalls im Zahlenraum int64_t liegen. 
Auch hier wird ein impliziter Cast auf int32_t gemacht. Jedoch an 
anderer Stelle.

von Gedankenspiel (Gast)


Lesenswert?

Gedankenspiel schrieb:
>> wert2 = (((int32_t) (F_CPU * 60 / 120000UL))*wert2)/((n+1)*3);

Was passiert mit wert2 wenn Du folgendes machst?

wert2 = (int32_t)(((int32_t) (F_CPU * 60 / 120000UL))*wert2) / 
((n+1)*3);

von Karl H. (kbuchegg)


Lesenswert?

Gedankenspiel schrieb:
> Gedankenspiele!
>
> wert2 ist laut code ein int32_t.
>
> David Menzeln schrieb:
>> (((int32_t) (F_CPU * 60 / 120000UL))*wert2)
>
> Hier wird ein int32_t mit einem int32_t multipliziert. Das Ergabnis
> könnte also im Zahlenraum eines int64_t liegen. Ich gehe davon aus, dass
> der Compiler das berücksichtigt.

Sollte eigentlich nicht sein. Die C-Regeln sind da recht eindeutig. Das 
Ergebnis kann nur wieder den Datentyp int32_t haben. Damit sollte 
eigentlich die Zuweisung an die Variable keine Rolle spielen, weil damit 
keine Casting-Aktion verknüpft ist.



Ich hab da noch was in Erinnerung, dass vor nicht all zu langer Zeit mal 
dem Compiler Mixed Arithmetikroutinen mitgegeben wurden, mit denen er 
Operationen auch auf Ausdrücken mit gemischten Datentypen durchführen 
kann, ohne erst alles auf die gleiche Datentypbasis bringen zu müssen. 
Ich könnte mir vorstellen, dass da in dieser avrgcc Version noch 
irgendwo ein Wurm drinnen ist.

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Hmm. Hab den Thread jetzt längere Zeit nicht beobachtet und heute keine
> Zeit mehr, da selbst mal ein paar Versuche anzustellen.

Ich habe gestern die Version von "Datum: 08.01.2013 22:03" (war zu dem 
Zeitpunkt die einzige vollständige Version ohne "RAM-Problem") im 
Simulator ausprobiert, und konnte keinerlei Problem feststellen. Sowohl 
die berechneten Werte, als auch die Ausgaben (natürlich keine echten 
Ausgaben, da Simulator, sondern den Inhalt von buffer1 betrachtet) waren 
korrekt.
Und nachdem ich nun heute das hier
> Ich nutze AVR-Studio 5 mit AVRGCC V.3.3.1.27
gesehen habe, denke ich, dass sich das Problem mit einem Update in Luft 
auflösen wird.

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:

> Und nachdem ich nun heute das hier
>> Ich nutze AVR-Studio 5 mit AVRGCC V.3.3.1.27
> gesehen habe, denke ich, dass sich das Problem mit einem Update in Luft
> auflösen wird.

Ich denke auch schön langsam, dass es tatsächlich eine Compiler Sache 
ist.

Edit:
Ooops
3.3?
Die ist doch himmelalt, oder nicht?
Wird AVR-Studio 5 wirklich mit diesem alten Hadern ausgeliefert?

von David Menzeln (Gast)


Lesenswert?

Bernd schrieb:
> David Menzeln schrieb:
>> wert2 = (((int32_t) (F_CPU * 60 / 120000UL))*wert2)/;

Nein, das lässt sich natürlich nicht compilieren, das ist leider 
passiert, durch die ganze hin und her Bastelei, da ich das umgestellt 
habe für den Test, siehe Beitrag. Offensichtlich habe ich die falsche 
Datei "zwischengespeichert" um hier anzuhängen. Denke den Schräger weg, 
dann lässt es sich compilieren.

Bezüglich Update:
Ich werde mir mal die neueste Version ziehen und es damit probieren.
Ich glaube auch nun wirklich nicht mehr, dass es am Code liegt.

Fabian O. (xfr) hat es ja gestern auch problemlos auf einem XMega laufen 
lassen. Und im Simulator scheint es ja auch zu gehen.

Werde trotzdem noch die vorgeschlagenen Sachen versuchen (mehr als 
nichts kann es nicht sein) und weiter berichten.

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Karl Heinz Buchegger schrieb:
> Edit:
> Ooops
> 3.3?
> Die ist doch himmelalt, oder nicht?
> Wird AVR-Studio 5 wirklich mit diesem alten Hadern ausgeliefert?

Die Version die ich damals so runtergeladen habe von Atmel 
offensichtlich ja (siehe Anhang)

von Stefan E. (sternst)


Lesenswert?

Karl Heinz Buchegger schrieb:
> Ooops
> 3.3?
> Die ist doch himmelalt, oder nicht?
> Wird AVR-Studio 5 wirklich mit diesem alten Hadern ausgeliefert?

Ne, so alt nun auch wieder nicht. Das ist die Versionsnummer der 
Atmel-Toolchain (nicht des avr-gcc). Da ist AFAIK ein avr-gcc 4.5 drin.

von Karl H. (kbuchegg)


Lesenswert?

Stefan Ernst schrieb:
> Karl Heinz Buchegger schrieb:
>> Ooops
>> 3.3?
>> Die ist doch himmelalt, oder nicht?
>> Wird AVR-Studio 5 wirklich mit diesem alten Hadern ausgeliefert?
>
> Ne, so alt nun auch wieder nicht. Das ist eine Atmel interne
> Versionsnummer der Atmel-Toolchain.


grrr.
und ich dachte schon.
Ein schneller Google Scan auf "avrgcc 3.3" brachte Einträge von 2002 zu 
Tage :-)

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Karl Heinz Buchegger schrieb:
> Sollte eigentlich nicht sein. Die C-Regeln sind da recht eindeutig.

Naja, soweit ich mich erinnere ist ein Signed Overflow "undefined 
behaviour", was spricht eigentlich dagegen, diese ganze "Wurst" mal in 
einzelne Operationen zu zerlegen (mit jeweils passenden Datentypen) und 
sich die Zwischenergebnisse auszugeben?
Uncool weil es nicht mehr so wahnsinnig genial aussieht? Zuwenig platz 
in der Höhe auf dem Monitor? Festplattenplatz und/oder Variablen sparen?

Wieso wird diese komische Konstrukt mit < 24? Was bedeutet diese "magic 
number" und wieso startet nicht einfach der Schleifenzähler bei 24? Die 
schleife scheint mir doch sehr suspekt...

Ich hab das mal etwas umgestellt, allerdings ungetestet nur so als 
Anregung:
1
int main() {  
2
  init_ports();
3
  uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); 
4
5
  for (uint8_t n = 24; n < ANZAHL2 + 25; n++) {
6
      int16_t pgmWert = pgm_read_word (&TabellePROGMEM[0][n]);
7
        printVal("pgmWert: ", pgmWert);
8
      int16_t pgmVerschoben = pgmWert + VERSCHIEBEWERT;
9
        printVal("pgmVerschoben: ", pgmVerschoben);
10
      int32_t frequenzWert = (int32_t)(F_CPU * 60 / 120000UL);
11
        printVal("frequenzWert: ", frequenzWert);
12
      int32_t finalerWert = frequenzWert * pgmVerschoben;
13
        printVal("finalerWert: ", finalerWert);
14
      uart_puts_P("\r\n");
15
  }
16
17
  while( 1 ) {}
18
  return 0;
19
}
Ich hoffe ich hab das jetzt so frei Hand korrekt umgesetzt, du solltest 
versuchen sowas mehr zu strukturieren und Variablen so lakl wie möglich 
zu halten, printVal entweder als Funktion oder Makro noch hinzufügen...

von Karl H. (kbuchegg)


Lesenswert?

Läubi .. schrieb:
> Karl Heinz Buchegger schrieb:
>> Sollte eigentlich nicht sein. Die C-Regeln sind da recht eindeutig.
>
> Naja, soweit ich mich erinnere ist ein Signed Overflow "undefined
> behaviour",

ok, ich gebe zu, dass ich die Zahlen nicht gecheckt habe. (Sollte man 
mal tun)
Allerdings ist der Wertebereich von int32_t schon so groß, dass ich 
nicht denke, dass man hier in einen Overflow läuft. Die großen Zahlen 
tauchen ja nur bei der Frequenzrechnerei auf und die müsste sich IMHO 
eigentlich ausgehen. Zudem sind das alles Konstanten, d.h. da gäbs 
sicher eine Warnung vom Compiler.

> was spricht eigentlich dagegen, diese ganze "Wurst" mal in
> einzelne Operationen zu zerlegen (mit jeweils passenden Datentypen) und
> sich die Zwischenergebnisse auszugeben?

Irgendwo weiter oben gibt es einen Post mit so einem Ansatz.

> Wieso wird diese komische Konstrukt mit < 24? Was bedeutet diese "magic
> number" und wieso startet nicht einfach der Schleifenzähler bei 24? Die
> schleife scheint mir doch sehr suspekt...

Yep. Ging mir genau so.
Drum hab ich auch angeregt, diesen ganzen Palawatsch mit dem Versatz und 
den zusätzlichen Arrays einfach mal zu eliminieren und sich nur auf die 
Berechnung zu konzentrieren.

von Läubi .. (laeubi) Benutzerseite


Lesenswert?

Sehe gerade das noch die Sache mit "wert2 = wert2/((n+1)*3);" fehlt...

von David Menzeln (Gast)


Angehängte Dateien:

Lesenswert?

Läubi .. schrieb:
> ncool weil es nicht mehr so wahnsinnig genial aussieht? Zuwenig platz
> in der Höhe auf dem Monitor? Festplattenplatz und/oder Variablen sparen?

Nein, im Gegenteil. Diese "lange Schlange" finde ich natürlich auch 
unübersichtlich bzw. nicht nachvollziehbar. Ich habe mir dazu vorab 
Gedanken gemacht und die Rechnung möglichst auf einem Blatt Papier so 
zusammengestückelt, um eben Platz bzw. Variablen zu sparen. Lesbarer ist 
sicherlich das Schritt für Schritt zu machen.

Läubi .. schrieb:
> Was bedeutet diese "magic
> number"

Offensichtlich erkennt man noch, dass es sich im Grunde um eine 
Frequenzberechnung handelt. Ziel ist es, diese ab einer bestimmten 
Frequenz etwas zu manipulieren.
Mein Weg hierzu war, eben, diese Manipulation erst ab einer bestimmten 
Frequenz zu machen, ab der "magic number" 24. Das Programm addressiert 
über den einen Tabellenindex, der sich aus der Frequenz ergibt, dann 
eben den Wert, mit welchem manipuliert werden soll. Liegt dieser Index 
bei <=24, soll eben nur mit dem "Standard" Verschiebewert manipuliert 
werden. Spielt im Grunde aber keine Rolle. Wollte hier nur etwas Licht 
ins dunkle bringen zum Nachvollziehen.

Dass dies fehlt
1
 ((n+1)*3)
habe ich gesehen und ergänzt.

Verzeiht mir, dass ich keine /n und /r nutze, aber mein Terminalprogramm 
(hterm) zeigt diese Umbrüche nicht an, deswegen gebe ich ein paar 
Leerzeichen aus, um das zu trennen.

Ich habe das ganze durch AVR-Studio 5 gejagt und zusätzlich mal meinen 
alten Laptop angeschmissen, wo AVR Studio 4 installiert ist.

Der Compiler in AVR Studio 4 rechnet richtig mit gleicher 
Optimierungseinstellung -O1. AVR Studio 5 tut es nicht.

von Stefan W. (dl6dx)


Lesenswert?

David Menzeln schrieb:
> Der Compiler in AVR Studio 4 rechnet richtig mit gleicher
> Optimierungseinstellung -O1. AVR Studio 5 tut es nicht.

AVR Studio ist nur die Entwicklungsumgebung. Entscheidend ist die 
Version des avr-gcc.

Schau jeweils im Output-Fenster nach, unter welchem Pfad der jeweilige 
avr-gcc liegt und ruf ihn in einem CMD-Fenster mit der Option --version 
auf. Beispiel
1
"C:\Programme\Atmel\Atmel Studio 6.0\extensions\Atmel\AVRGCC\3.4.0.65\AVRToolchain\bin\avr-gcc.exe" --version
Die Ausgabe sollte so aussehen:
1
avr-gcc.exe (AVR_8_bit_GNU_Toolchain_3.4.0_663) 4.6.2
2
Copyright (C) 2011 Free Software Foundation, Inc.
3
This is free software; see the source for copying conditions.  There is NO
4
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

Die GCC-Version ist die letzte Angabe in der ersten Zeile (hier 4.6.2).

Grüße

Stefan

von eProfi (Gast)


Lesenswert?

> Verzeiht mir, dass ich keine /n und /r nutze, aber mein Terminalprogramm
> (hterm) zeigt diese Umbrüche nicht an, deswegen gebe ich ein paar
Versuche es mal mit

uart_put(13);uart_put(10);
oder heißt es uart_putc oder uart_putch?


zur Ausgabe meinte ich, es reicht doch so:
pgmWert  pgmVerschoben  frequenzWert  finalerWert (diese Zeile nur 
einmal)
 -185  -65  8000 -6933
 -185  -65  8000 -6666
 -184  -64  8000 -6320
 -184  -64  8000 -6095
etc.


Probier mal statt
for (uint8_t n=0; n<ANZAHL2+25; n++){    --->
for (uint16_t n=0; n<ANZAHL2+25; n++){   oder
for (uint32_t n=0; n<ANZAHL2+25; n++){

und dann mal statt
int16_t pgmWert;  --->  int32_t pgmWert;

von eProfi (Gast)


Lesenswert?

Bitte poste die List-Files -lss von V.4 und V5. bei gleichem 
Source-Code.

von Stefan E. (sternst)


Lesenswert?

Ich weiß gar nicht, was dieses ganze "versuch mal" und "mach mal" hier 
überhaupt noch soll. Studio5 hat erwiesenermaßen diverse Bugs, sowohl in 
der IDE, als auch in der enthaltenen Toolchain. Er soll einfach auf 6 
updaten, und wenn es dann noch Probleme gibt, DANN wird es wieder 
interessant.

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.