Forum: Compiler & IDEs ACO-Bit Abfrage beim Analog Comparator


von Arthur (Gast)


Lesenswert?

Hallo, ich habe ein Problem beim ACO-Bit Auslesen des Analog 
Comparators.
Ich habe das ACSR richtig eingestellt, nun will ich das ACO Bit 
abfragen.
Im AVR-GCC-Tutorial steht:

Bit 5 ACO - Analog Comparator Output: Hier wird das Ergebnis des 
Vergleichs angezeigt. Es liegt typischerweise nach 1-2 Taktzyklen vor.
Ergebnis:
IST < SOLL --> 1
IST > SOLL --> 0

Meine Frage:

Wie frage ich das ACO Bit ab?

Das geht nicht:

if(ACO == 1)wurst();  //geht nicht!
if(ACO == 0)milch();  //geht nicht!


Kann mir da jemand weiterhelfen?

Danke im Vorraus.

von Johannes M. (johnny-m)


Lesenswert?


von Arthur (Gast)


Lesenswert?

Habs jetzt verstanden, danke:
if((ACSR & (1<<ACO)) == 0) wurst(); // geht


Aber eine Frage hab ich noch zum Analog Comparator:

Ich will zwei Spannungen vergleichen und je nachdem welche größer ist 
soll dann ein Ereignis passieren.

Die Spannungen hab ich an AIN0 und AIN1 angelegt.

Den ACSR hab ich auf externe Referenzspannung eingestellt.

ACSR = (0>>ACIS0) |
       (0>>ACIS1) |
       (0>>ACIC) |
       (0>>ACIE) |
       (0>>ACI) |
       (0>>ACBG) |
       (0>>ACD);


Im AVR-GCC-Tutorial steht das, dass ACO folgende Ergebnisse liefert:

IST < SOLL --> 1
IST > SOLL --> 0


Wenn ich aber das ACO Bit auf logisch 1 abfrage reagiert mein Programm 
nicht:

if((ACSR & (1<<ACO)) == 1) milch(); // keine Reaktion

Bei Abfrage auf 0 gibts keine Probleme:

if((ACSR & (1<<ACO)) == 0) wurst(); // geht


Hat hier jemand schon Erfahrungen gemacht?

Danke für jede Antwort.

von Johannes M. (johnny-m)


Lesenswert?

Arthur wrote:
> if((ACSR & (1<<ACO)) == 1) milch(); // keine Reaktion
Lass das "==1" weg. Hier werden Wahrheitswerte ausgewertet(*). Das Bit 
ACO liegt nicht an der letzten Stelle im Register, weshalb der Ausdruck 
nie 1 werden kann. Schreib einfach
1
if(ACSR & (1<<ACO)) milch();
bzw. im anderen Fall
1
if(!(ACSR & (1<<ACO))) wurst();

(*) Grundsätzlich ist in C alles wahr was nicht 0 ist. Ein if 
überprüft lediglich, ob der Wert in den Klammern von Null verschieden 
(also wahr) ist. Ist das der Fall, dann wird die nachstehende 
Anweisung ausgeführt. Deshalb wäre das "==1" selbst dann überflüssig, 
wenn es nicht falsch wäre.

EDIT:
Du hast es oben ja selbst geschrieben:
> Bit 5 ACO - Analog Comparator Output: [...]
Wenn ACO gesetzt (1) ist, dann hat der Ausdruck "ACSR & (1 << ACO)" den 
Wert "1 << ACO", was aufgelöst 1 << 5, also 100000b oder 20h oder 32d 
entspricht. du könntest also höchstens eine Abfrage wie
1
if((ACSR & (1<<ACO)) == 32) milch();
2
//oder
3
if((ACSR & (1<<ACO)) == (1 << ACO)) milch();
machen, dann müsste es klappen. Das ist allerdings, wie oben schon 
gesagt, überflüssig.

von Arthur (Gast)


Lesenswert?

Danke für die Antwort, es funktioniert jetzt.

Hier nochmal mein Prog falls jemand etwas ähnliches machen will:

ACSR = (0>>ACIS0) |
       (0>>ACIS1) |
       (0>>ACIC) |
       (0>>ACIE) |
       (0>>ACI) |
       (0>>ACBG) |
       (0>>ACD);

for (;;)
{
  switch(ACSR & (1<<ACO))
  {
    case(0): wurst();
    break;

    case(1 << ACO): milch;
    break;
  }
}

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.