Berechnungen mit µC in ANSI C

OP #1587296
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
#1587312
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
#1587429
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
#1587432
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;
Gast #1587624
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)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren