Forum: Mikrocontroller und Digitale Elektronik Berechnungen mit µC in ANSI C


von Daniel X. (daniel_78)


Lesenswert?

Hallo User,

kann mir evtl. jemand helfen bei ANSI C für meinen µC.

Ich möchte etwas berechnen und habe folgendes deklariert:

volatile unsigned int AN6;      // 0 ….65565
volatile unsigned int AN6_1;    // 0 ….65565
volatile unsigned int AN6_2;    // 0 ….65565
volatile unsigned int AN6_3;    // 0 ….65565
volatile float Ergebnis;      // Gleitkomma

Ergebnis = ((AN6 + AN6_1 + AN6_2 + AN6_3)/4) * 0.2356 – 85,66

Wie schreibe ich die Formel richtig in ANSI C?

Ich benutze den C18 Compiler von Microchip.

Besten Dank.

Daniel

von Johannes S. (jhs)


Lesenswert?

Hi!
1
unsigned int ZwischenErgebnis = AN6 + AN6_1 + AN6_2 + AN6_3; // evtl. auch uint32_t falls das Ergebnis größer als 65565 ist
2
Ergebnis = (float) (ZwischenErgebnis / 4) * 0.2356 - 85.66;

Natürlich kannst du auch ohne die temporäre Variable auskommen, aber 
dann wirds unübersichtlich. Ich denke du weißt ja, was bei der Addition 
rauskommt also kannst du da auch einen gutem Namen vergeben.

Eigentlich ist der C Compiler davon auch recht unabhängig, so lange er 
ANSI C sauber implementiert. Denk dran, dass du vielleicht noch die libm 
mit einlinken musst, weil dein uC hat wahrscheinlich keine FPU.

Gruß
Johannes

von B e r n d W. (smiley46)


Lesenswert?

Der Term (ZwischenErgebnis / 4) wird noch als unsigned int durchgeführt 
und dabei wird gerundet, die Nachkommastellen gehen verloren.
Dann wenigstens so: ((float)ZwischenErgebnis / 4)

Oder gleich so:
Ergebnis = (((float)AN6 + AN6_1 + AN6_2 + AN6_3)/4) * 0.2356 – 85.66;

Gruß, Bernd

von Michael H. (morph1)


Lesenswert?

Ergebnis = ((float)(AN6 + AN6_1 + AN6_2 + AN6_3)/4) * 0.2356 – 85.66;

wenn dann müssen die klammern schon richtig sitzen ;)

von B e r n d W. (smiley46)


Lesenswert?

@Michael H.
Das spart eventuell ein wenig Rechenzeit, da erst 3 Additionen per 
unsigned int durchgeführt werden und dann erst gecasted. Falls die Summe 
der vier ANs größer als 65565 werden kann, müßte man zuerst nach (long) 
casten, dann addieren, dann nach (float) casten und dann erst /4 
dividieren.

Falls es sich um eine zeitkritische Berechnung handelt, könnte man noch 
weiter optimieren und eventuell ganz auf float verzichten. Mir 
persönlich ist es lieber, wenn die Float-Library nicht eingebunden 
werden muß.

Gruß, Bernd

von Rolf M. (rmagnus)


Lesenswert?

> Falls die Summe der vier ANs größer als 65565 werden kann, müßte man
> zuerst nach (long) casten, dann addieren, dann nach (float) casten und
> dann erst /4 dividieren.

Oder man schiebt das /4 nach hinten zum anderen Faktor, dann kann man 
sich den Cast sparen, und man hat die besten Chancen, daß diese Division 
schon zur Compilezeit gemacht wird:
1
Ergebnis = ((unsigned long)AN6 + AN6_1 + AN6_2 + AN6_3) * (0.2356 / 4)  85.66;

von Maik W. (werner01)


Lesenswert?

sevus ,


ich habe die erfahrung gemacht beim hitech comiler das wenn ich a=a+2
schreibe er dann weniger code erzeugt als wenn ich a +=2?

warum ist das so?




mfg

von der mechatroniker (Gast)


Lesenswert?

Optimierungen vergessen einzuschalten?
Ansonsten: Compiler ist schrott.

von Daniel X. (daniel_78)


Lesenswert?

Hallo User,

vielen Dank für die vielen Antworten. Bei der Addition ist der Wert 
übrigens kleiner als 65565.

Ich werde den Code heute Abend gleich mal änden und testen/schauen was 
geht.

Vielen Dank erst einmal uns schönen Sonntag noch.

Daniel

von Walter (Gast)


Lesenswert?

Wenn du nur Int brauchst, und es optimierten müsstest, dann wäre der Weg 
folgender:

unsigned int32 T;
T =(AN6 + AN6_1 + AN6_2 + AN6_3); T/=4; T *= 15440; T-=5613813;
Ergebnis = T>>16 // oder union high short byte von unsigned int.
Eventuell
Ergebnis = (uint16)((((uint32)(AN6 + AN6_1 + AN6_2 + AN6_3)/4 * 
(uint16)(256*256*.2356) ) - (uint32)(256*256*85.66))>>16)

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.