Forum: Mikrocontroller und Digitale Elektronik HEX Größe verzehnfacht durch if Abfrage


von Georg (Gast)


Lesenswert?

Hallo,

ich scheitere gerade am programmieren eines ATTINY13a im AVR Studio 4 
mit avr-gcc. Für eine Berechnung benötige ich eine 32Bit Variable, die 
ich global anlege. Wenn ich nun nach der Berechnung den Wert abfrage, 
bekomme ich die Meldung: "the selected hex file does not fit in the 
selected device". Und tatsächlich wächst des hex file sobald ich die 
Abfrage drin habe von 1KB auf 10KB an. Wie kann das sein?
1
//vor der main
2
uint32_t summe;
3
4
//in der main
5
if(summe > MAX_VAL)    
6
{
7
    ende = 1;
8
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Das Problem wird an einer anderen Stelle liegen, die uns Dein 
Codeschnipsel nicht zeigt.

Es ist anzunehmen, daß Du mit "summe" auch anderswo was anstellst; sonst 
hätte das ganze ja auch überhaupt keinen Sinn.

von Rolf Magnus (Gast)


Lesenswert?

Ohne zu wissen, was in MAX_VAL steht, kann man dazu nichts sagen. Meine 
Glaskugel meint, es könnte ein float sein, wodurch die float-Library mit 
gelinkt wird.

von Mike (Gast)


Lesenswert?

Immer diese Code-Fragmente ...

Was ist das?

Georg schrieb:
> MAX_VAL

von Georg (Gast)


Lesenswert?

Tut mir Leid, ich wollte euch nicht mit dem ganzen Code erschlagen, da 
er noch nicht richtig strukturiert ist.
MAX_VAL ist 100000

summe wird vor der Abfrage in einer Schleife aufsummiert.
1
//vor main
2
uint32_t dif;
3
uint32_t summe;
4
uint8_t ende;
5
6
7
//in main
8
ende=0;
9
while(!ende)
10
{
11
dif = (542 * ADC_Read()) - 22222;
12
summe += (uint32_t)sqrt(dif));
13
if(summe > 100000)    
14
{
15
    ende = 1;
16
}
17
}

wenn ich nun die Berechnung mit der Wurzel auskommentiere funktioniert 
es. Wenn ich die if Abfrage auskommentiere funktioniert es auch. Nur 
zusammen nicht.

von Marian (phiarc) Benutzerseite


Lesenswert?

Georg schrieb:
> wenn ich nun die Berechnung mit der Wurzel auskommentiere funktioniert
> es. Wenn ich die if Abfrage auskommentiere funktioniert es auch. Nur
> zusammen nicht.

Optimierungen sind an?

Wenn du summe änderst, aber nicht nutzt, schmeißt der Optimierer die 
Änderung logischerweise raus. Ergo ist sqrt dein Problem.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Georg schrieb:
> summe += (uint32_t)sqrt(dif));

Da steht sqrt. Das ist eine Floating-Point-Funktion.

Das ist die Ursache.

von Falk B. (falk)


Lesenswert?

@ Georg (Gast)

>dif = (542 * ADC_Read()) - 22222;
>summe += (uint32_t)sqrt(dif));

Das ist eine FLießkommafunktion, die braucht satt Flash-Speicher!

>wenn ich nun die Berechnung mit der Wurzel auskommentiere funktioniert
>es.

Was aber ein VOLLKOMMEN andere Fehlerbeschreibung als in deinem 1. 
Beitrag ist!

von S. R. (svenska)


Lesenswert?

Wenn du das if weglässt, optimiert der Compiler die Wurzel weg, weil 
"summe" nicht mehr gebraucht wird.

Das Problem ist die Wurzel. Die zieht die Float-Bibliothek mit rein.

von Georg (Gast)


Lesenswert?

Danke euch, jetzt kenne ich schon mal das Problem. Gibt es da auch eine 
Lösung? Eine Integer sqrt Funktion?

von Mathe Freak (Gast)


Lesenswert?

Georg schrieb:
> Eine Integer sqrt Funktion?

Dann rechne mal die Wurzel von z.B. 10 als Ganze Zahl aus ...

von Martin K. (dschadu)


Lesenswert?

Marian B. schrieb:
> Optimierungen sind an?

Wie schauts mit der Antwort auf die Frage aus?

von Marian (phiarc) Benutzerseite


Lesenswert?

Normalerweise kennt man seine Wertebereiche und geht dann z.B. hin und 
erstellt eine Approximation mit hinreichend kleinem Fehler für den 
notwendigen Wertebereich, ggfs als Festkommavariante.

von Wolfgang A. (Gast)


Lesenswert?

Georg schrieb:
> Gibt es da auch eine Lösung? Eine Integer sqrt Funktion?

Du könntest das Heron-Verfahren in Festkomma-Arithmetik einbauen.

von Georg (Gast)


Lesenswert?

Martin K. schrieb:
>> Optimierungen sind an?
>
> Wie schauts mit der Antwort auf die Frage aus?

Entschuldige, ganz vergessen. Ich habe die Einstellungen dazu noch nicht 
ganz verstand. In dem Feld rechts unter Project/Config Options/ Custom 
Options steht unter anderem -Os. mit -O0 habe ich es auch schon 
probiert. Das habe ich so bei google gefunden. Wofür genau die Symbole 
stehen habe ich noch nicht herausgefunden...

Mathe Freak schrieb:
> Dann rechne mal die Wurzel von z.B. 10 als Ganze Zahl aus ...
Schon klar. Es muss eben gerundet werden.

In AVR Arithmetik bin ich auf die sqrt32_round Funktion gestoßen. 
Ich habe aber noch Probleme beim einbinden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Musst Du denn da wirklich mit einer Wurzel hantieren?

Was soll das ganze denn ergeben?

von klausr (Gast)


Lesenswert?

Georg schrieb:
> Eine Integer sqrt Funktion?

Das Internet ist voll davon. Schau mal hier:
http://www.azillionmonkeys.com/qed/sqroot.html
oder hier:
http://helloacm.com/coding-exercise-implement-integer-square-root-c-online-judge/
Ich habe "damals" eine 16-bit integer sqrt auf eine 68HC11 
implementiert. Keine große Sache

von DirkB (Gast)


Lesenswert?

ein
1
if(dif > 10000000000)
 macht es auch ohne Wurzel.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

10000000000 ist kein mit uint32_t darstellbarer Wert.

von Holger L. (max5v)


Lesenswert?

Was geschieht eigentlich wenn ADC_Read() <= 41 ist ?

Georg schrieb:
> uint32_t dif;
> dif = (542 * ADC_Read()) - 22222;

542 * 41 - 22222 = 0
542 * 40 - 22222 = -542

: Bearbeitet durch User
von Chris (Gast)


Lesenswert?

Holger L. schrieb:
> Was geschieht eigentlich wenn ADC_Read() <= 41 ist ?
Gut mitgedacht ;)
Vielleicht fange ich den Fall noch ab. Eigentlich kann das aber nie 
vorkommen, da am ADC ein Sensor hängt, der einen Offset von 0,2V (41) 
hat. Außerdem sollte die untere Grenze eigentlich nie erreichen.

Danke euch nochmal! Ich habe den Wertebereich jetzt erstmal mit if 
Abfragen geclustert und die Funktion dazwischen entsprechend 
linearisiert. Falls ich doch noch Probleme damit bekomme, muss ich 
nochmal eine Wurzelfunktion suchen, es sieht aber soweit ganz gut aus. 
:)

von Teo D. (teoderix)


Lesenswert?

Chris schrieb:
> Eigentlich kann das aber nie
> vorkommen

Diesen Satz würde ich gerne in Blei gießen.
Damit man ihn dem Programmierer so richtig um die Ohren hauen 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.