Forum: Mikrocontroller und Digitale Elektronik ADC an ATtiny25


von john (Gast)


Lesenswert?

Ich versuche ein stark verauschtes, langsames (ewig high - 0.5sek bis 
einige sek Signal low - wieder ewig high) mittels ADC "auszulesen", dh 
ich muss eigentlich nur bei einem high-low Übergang gewissen Code 
ausführen.
Ursprünglich versuchte ich dies mit dem Analog Comparator - doch wegen 
dem starken Rauschen führte dies zu mehrfach auslösungen (die Flanken 
sind aufgrund von Kapazitäten leider auch nicht unendlich steil).
Ich verwende einen ATtiny25 mit dem Signal an ADC1 und folgendem code:

DDRB=0xfb;
ADMUX=0x81;
ADCSRA=0xe2;
ADCSRB=0x00;
DIDR0=0x04;     //ausschalten des Digitaleingangs von PB2/ADC1;

//// ADC-auslesen
        uint8_t adc=ADCH;
        if((adc|0x03)==0x03)       //oberer Bereich
        {
            bf0.adcLastTime=1;
        }
        else if((adc|0x03)!=0x02)  //unterer Bereich
        {
           ...
           bf0.adcLastTime=0;
        }


dies in einer Endlosschleife

da ich ja nur zwei Zustände habe sollten die 4 höchsten Bit ja genügen.

Aus irgend einem Grund funktioniert jedoch nichts (der ... code wird nie 
ausgeführt) - deshalb hab ich den Verdacht, dass der ADC gar nicht 
wirklich läuft ?!

vielen Dank bereits im Voraus

von Εrnst B. (ernst)


Lesenswert?

Gewöhn dir am besten gleich an, Konstanten für Steuerregister besser als 
Kombination der einzelnen Bits darzustellen, und dabei die von der 
avr-libc vordefinierten Namen zu verwenden.

Also z.B.
1
ADCSRA  = _BV(ADEN)  | _BV(ADPS1) | _BV(ADPS0) | _BV(ADIE); // Enable, clk/8 clock,IRQ

Dann sieht man gleich, welche Optionen aktiviert sind.
Ich zumindest hab jetzt keine Lust aus dem Datenblatt rauszufriemeln, 
was nun wohl ein 0xe2 im ADCSRA bewirkt.

von ... .. (docean) Benutzerseite


Lesenswert?

Dann setz doch einfach einen analoges RC Glied davor.

Vlt, hilft das schon

von john (Gast)


Lesenswert?

also - hab jetzt rausgefunden, dass die internen Referenzspannungen 
anscheinend von VCC her gerechnet sind und nicht von GND - deshalb hab 
ich diese jetzt ausgeschaltet, die neuen Register:

 ADMUX=0x01;
-> also Vcc als Ref-Spannung (REFS2=REFS1=REFS0=0)
-> ADLAR=0 richtet den gemessenen Wert so aus, dass die beiden höchsten 
Bit in ADCH an den Positionen 0 und 1 sind (so verstehe ich wenigstens 
das Datenblatt)
-> MUX3..0: 0001, also ADC1 als Input gewählt.

 ADCSRA=0xe0;
-> ADEN=1 : einschalten des ADC
-> ADSC=1 : starten des ADC
-> ADATE=1: autotrigger enabled
-> ADIE=0:  interrupt disabled
-> ADPSx=000: division factor 2

 ADCSRB=0x00;
alles 0, also free running mode!

ich hab diese sequenz nur beim initialisieren eingefügt!
ich nehme an, dass der ADC danach immer eingeschalten bleibt und die 
Werte ständig aktualisiert. ?
Oder muss ich vor jeder Messung den ADC starten?

von john (Gast)


Lesenswert?

ACH!
ich bin ei depp!

if((adc|0x03)==0x03)

anstelle von

if((adc&0x03)==0x03)

ersteres ist natürlich immer TRUE

:)

es funktioniert immer noch ganz, aber das ist ein anderes Problem!

entschuldigt meine Dummheit!

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.