Forum: Mikrocontroller und Digitale Elektronik Attiny2313 Analog Comparator laeuft nicht


von Robert (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

ich probiere mich am Analog Comparator des Attiny2313 und
will ihn erstmal nur zum Laufen kriegen.
Das Datenblatt liest:
1
When the voltage on the positive pin AIN0 is higher than the voltage on the negative pin
2
AIN1, the Analog Comparator output, ACO, is set

Mein (Test-)Programm:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#define F_CPU 8000000UL
4
5
int main(void) {
6
        DDRD |= (1<<PD5);
7
        ACSR &= ~(1<<ACD); //eigentlich nutzlos, ist ja auf 0     
8
        DIDR = (1<<AIN1D) | (1<<AIN0D); //nur zum Stromsparen oder?
9
        while (1) {
10
                if((ACSR & (1<<ACO)) == 1){
11
                //AIN0 voltage higher than AIN1
12
                PORTD &= ~(1<<PD5); //aus
13
                _delay_ms(500);
14
                PORTD |= (1<<PD5); //an
15
                }
16
                else{
17
                PORTD |= (1<<PD5);
18
                }
19
        }
20
}

Ein einfaches Programm wie:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#define F_CPU 8000000UL
4
5
int main(void) {
6
        DDRD |= (1<<PD5);
7
        while (1) {
8
                PORTD ^= (1<<PD5);
9
                _delay_ms(1000);
10
        }
11
}
funktioniert einwandfrei.

Compiliert wird mit Optimierung -Os,
allerdings funktioniert -O0 auch nicht.
Ich hab die hex-Datei mal angehangen.
Spannungsversorgung sind 5V aus einem Labornetzteil,
ansonsten hab ich parallel 5 22nF Keramikkondensatoren zwischen
VCC und GND mangels 100nF Kondensator.
VCC und Reset sind mit einem 48k Widerstand verbunden,
wobei es keinen Unterschied macht ob er da ist oder nicht.
Wenn ich mit dem Oszi mein PD5 messe, dann ist der auf HIGH und
zwar die ganze Zeit, egal welchen Spoekes ich mit Pin12 und Pin13,
also AIN0 und AIN1 mache.
Zum Test habe ich AIN0 und AIN1 ueber 1,8k Widerstand auf GND und
probiere ueber 1,8k von VCC eine Reaktion aus dem attiny rauszukriegen.
Das sollte ja theoretisch einen Spannungsteiler mit 2,5V erzeugen,
welcher auf AIN0 angelegt in die erste if-Bedingung springt und
ein Signal erzeugt was an und aus geht.
Der 1,8k Widerstand auf AIN1 soll sicherstellen, dass AIN1 wirklich
auf 0 ist, ist aber auch sonst auf 0 mit minimalem rauschen.

Was mache ich falsch?
Was sind noch moegliche Fehlerquellen?


lg Robert

von leo (Gast)


Lesenswert?

Robert schrieb:
> if((ACSR & (1<<ACO)) == 1){

Das ist nur fallweise true, wenn ACO := 0. Lass einfach das '== 1' 
weg.

von Robert (Gast)


Lesenswert?

Ich gebe dir recht, es ist ueberfluessig.
Allerdings ist ACO entweder 1 oder 0,
weswegen == 1 eigentlich keinen Effekt darauf haben sollte.
if(1 == 1) sollte if(1) ja gleichwertig sein...

Nichtsdestotrotz beschwert sich der Compiler,
wenn ich == 1 weglasse mit:
1
avr1.c:(.text.startup+0x18): undefined reference to `_ms_delay'
2
collect2: error: ld returned 1 exit status
3
make: *** [makefile:28: blink.elf] Error 1

Wenn ich _ms_delay auskommentiere, dann kompilierts wieder.
Funktionieren tut es dann allerdings immernoch nicht,
allerdings bleibt diesmal der PD5 dauerhaft LOW...
das finde ich wirklich merkwuerdig...



lg Robert

von S. Landolt (Gast)


Lesenswert?

> Allerdings ist ACO entweder 1 oder 0
Schon richtig - aber (1<<ACO) ist 32.

von S. Landolt (Gast)


Lesenswert?

... wenn ACO==1.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Robert schrieb:
> undefined reference to `_ms_delay'

Die Funktion heisst ja auch "_delay_ms()".

von Falk B. (falk)


Lesenswert?

Robert schrieb:
> Ich gebe dir recht, es ist ueberfluessig.
> Allerdings ist ACO entweder 1 oder 0,
> weswegen == 1 eigentlich keinen Effekt darauf haben sollte.
> if(1 == 1) sollte if(1) ja gleichwertig sein...

Nö, siehe Bitmanipulation.

Tip. Welchen Wert hat ACO?

von S. Landolt (Gast)


Lesenswert?

Da gingen mir jetzt die Begriffe durcheinander, nochmal: ACO hat den 
Bitwert 5, wenn also der 'Analog Comparator Output' gesetzt ist, hat 
(1<<ACO) den Wert 32.

von Robert (Gast)


Lesenswert?

Oh...
mein Fehler, natuerlich ist 32&32 = 32,
und die if Anweisung funktioniert immer,
wenn sie != 0 kriegt.
Ich war innerlich von 32&32 = 1 ausgegangen,
was natuerlich schwachsinn ist.

Und natuerlich heisst die Funktion _delay_ms();
Was ich mich allerdings frage ist, warum
mein Compiler vorher kompiliert hat und nicht
sofort ne Fehlermeldung ausgespuckt hat.
Also es wurde mit einer nicht definierten
Funktion kompiliert...

von HildeK (Gast)


Lesenswert?

Robert schrieb:
> Was ich mich allerdings frage ist, warum
> mein Compiler vorher kompiliert hat und nicht
> sofort ne Fehlermeldung ausgespuckt hat.

Dein oben geposteter Code enthält kein falsches _ms_delay, sondern nur 
die richtige. Du hast anschließend was verschlimmbessert.

von Robert (Gast)


Lesenswert?

So ist es wohl.

Tatsaechlich waren die Ursache meines Ungluecks all
die summierten peinlichen Programmierfehler.

Ich danke euch vielmals, ich haette nicht erwartet in
so wenigen Zeilen so viele Fehler beim Code machen zu koennen.



lg Robert.

von leo (Gast)


Lesenswert?

Robert schrieb:
> Was ich mich allerdings frage ist, warum
> mein Compiler vorher kompiliert hat

Weil durch die (immer) falsche Bedingung der Code schon wegoptimiert 
war.

leo

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.