Forum: Mikrocontroller und Digitale Elektronik [AVR] ADC Register lesen avrgcc


von Mampf F. (mampf) Benutzerseite


Lesenswert?

Grias eich,

soweit ich mich erinnern kann, werden die Ausdrücke von links nach 
rechts ausgewertet, was dann dafür sorgen müsste, dass erst ADCL dann 
ADCH gelesen werden, oder?

Der ADC des AVRs möchte das ja in der Reihenfolge ... Ich wollte nur 
sicher gehen, dass das so passt und dass mir irgendeine Optimierung 
nichts versaut :)
1
uint16_t adc_val = ADCL | (ADCH << 8);

von Falk B. (falk)


Lesenswert?

@  Mampf F. (mampf)

>sicher gehen, dass das so passt :)

Mach es einfach so.

uint16_t adc_val = ADCW;

Der avr gcc macht das dann schon richtig für dich, denn der weiß, wie 
man 16 Bit Register auf dem AVR liest.

von Peter II (Gast)


Lesenswert?

Mampf F. schrieb:
> Der ADC des AVRs möchte das ja in der Reihenfolge ... Ich wollte nur
> sicher gehen, dass das so passt und dass mir irgendeine Optimierung
> nichts versaut :)

warum machst du dann nicht einfach
1
uint16_t adc_val = ADC;

von Falk B. (falk)


Lesenswert?


von Mampf F. (mampf) Benutzerseite


Lesenswert?

Ah okay, danke für die Tipps! :)

von Dr. Sommer (Gast)


Lesenswert?

Mampf F. schrieb:
> soweit ich mich erinnern kann, werden die Ausdrücke von links nach
> rechts ausgewertet,

Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch 
zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten 
Möglichkeiten verwenden...

von Mampf F. (mampf) Benutzerseite


Lesenswert?

Dr. Sommer schrieb:
> Mampf F. schrieb:
>> soweit ich mich erinnern kann, werden die Ausdrücke von links nach
>> rechts ausgewertet,
>
> Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch
> zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten
> Möglichkeiten verwenden...

Mmmhmm, so ganz kann das nicht stimmen ... Oooooder, ich verwechsel das 
mit Conditional Ausdrücken, wie sie bei Ifs vorkommen ... Soweit ich 
mich erinnern kann, kann man sich da auf die Reihenfolge verlassen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Mampf F. schrieb:
> Dr. Sommer schrieb:
>> Mampf F. schrieb:
>>> soweit ich mich erinnern kann, werden die Ausdrücke von links nach
>>> rechts ausgewertet,
>>
>> Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch
>> zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten
>> Möglichkeiten verwenden...
>
> Mmmhmm, so ganz kann das nicht stimmen ... Oooooder, ich verwechsel das
> mit Conditional Ausdrücken, wie sie bei Ifs vorkommen ... Soweit ich
> mich erinnern kann, kann man sich da auf die Reihenfolge verlassen.

Bei
1
ADCL | (ADCH << 8)
ist zwischen dem Zugriff auf ADCL und ADCH kein Sequence Point, und da 
hülft auch kein volatile.  Wenn ADCL vor ADCH gelesen werden soll, dann 
also
1
uint8_t adcl = ADCL;
2
uint16_t adc_val = adcl | (ADCH << 8);
Aber warum den Kopf zerbrechen?  Die beste Lösung steht bereits in der 
1. Antwort.

von krampf (Gast)


Lesenswert?

Mampf F. schrieb:
> Dr. Sommer schrieb:
>> Mampf F. schrieb:
>>> soweit ich mich erinnern kann, werden die Ausdrücke von links nach
>>> rechts ausgewertet,
>>
>> Keineswegs, die Reihenfolge hängt vom Compiler ab und ist praktisch
>> zufällig. Daher sollte man auf jeden Fall die anderen bereits genannten
>> Möglichkeiten verwenden...
>
> Mmmhmm, so ganz kann das nicht stimmen ... Oooooder, ich verwechsel das
> mit Conditional Ausdrücken, wie sie bei Ifs vorkommen ... Soweit ich
> mich erinnern kann, kann man sich da auf die Reihenfolge verlassen.

Vielleicht erinnerst du die dich an deine Erinnerung nicht richtig oder 
auch nur unvollständig. Komm wieder, wenn du eine sichere Auskunft geben 
kannst. So'n Wischiwaschi hilft hier keinem.

von Mampf F. (mampf) Benutzerseite


Lesenswert?

krampf schrieb:
> Vielleicht erinnerst du die dich an deine Erinnerung nicht richtig oder
> auch nur unvollständig.

Nein, ich bin mir absolut sicher ... Bei if-Expressions kann mann sich 
auf die Auswerte-Reihenfolge verlassen ... 100%

Früher habe ich oft Konstrukte wie:

if (ptr && ptr.bla()) { ... }

verwendet ... Das geht nur, wenn die Expression von links nach rechts 
abgearbeitet wird.

§5.14

Unlike &, && guarantees left-to-right evaluation: the second operand is 
not evaluated if the first operand is false.
§5.15

Unlike |, || guarantees left-to-right evaluation; moreover, the second 
operand is not evaluated if the first operand evaluates to true.

Aber das ist halt nur bei && und || richtig ... Insofern war meine 
Unsicherheit aus dem ersten Post richtig, weswegen ich gefragt hatte :)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Mampf F. schrieb:
> Nein, ich bin mir absolut sicher ... Bei if-Expressions kann mann sich
> auf die Auswerte-Reihenfolge verlassen ... 100%

Nein, mit dem if hat das überhaupt nichts zu tun. Bei
1
if(a | b) ...

ist die Auswertereihenfolge von a und b nicht festgelegt.

Bei
1
if(a || b) ...

hingegen schon. Das liegt aber nicht am if, sondern am ||.

Bei
1
c = a || b;

wird, obwohl kein if dasteht, ebenfalls a vor b ausgewertet (und b auch
nur dann, wenn a=0 ist).

Aber du hast ja den entsprechenden Abschnitt aus der Norm gerade selber
zitiert.

von Georg G. (df2au)


Lesenswert?

K&R C Reference Manual, Expressions (frei übersetzt):
Es ist dem Compiler überlassen, ob er von links nach rechts oder von 
rechts nach links übersetzt, auch, wenn der Ausdruck Nebeneffekte 
beinhaltet. Wenn eine bestimmte Reihenfolge unbedingt eingehalten werden 
muss, müssen explizit temporäre Variable benutzt werden.

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.