Forum: Mikrocontroller und Digitale Elektronik ATTiny 85 AD-Wandler vs. Portpin in C (AVR Anfänger!)


von Frank (Gast)


Lesenswert?

Hallo zusammen,

ich habe folgendes Problem:
An einem ATTiny 85 habe ich an PB0, PB2, PB4 ein LC-Display über ein 
4094 hängen. Initialisierung und ausgabe via Printf funktioniert 
wunderbar.
Ich möchte jetzt über ADC3 -> PB3 einen analogen wert einlesen und auf 
dem
Display ausgeben. Sobald ich aber das ADMUX=0xC3; register setzte kommt 
nur noch müll auf der Anzeige. Selbst wenn ich das ADMUX register setze 
und direkt danach das DDRB=0b00111111; register neu beschreibe habe ich 
dieses verhalten. Muss ich da noch irgendwas umstellen.
Ich wollte eigentlich so vorgehen:

1. Display initialisieren
2. Displayausgabe in erster Zeile
3. Auf AD Wandlung umstellen und ADC3 lesen und in eine Variable 
schreiben
4. Displayausgabe dieser Variablen in der zweiten zeile
5. sprung zu drei um den Messwert zu aktualisieren

Gruß

Frank

von Johannes M. (johnny-m)


Lesenswert?

> Muss ich da noch irgendwas umstellen.
Zunächst mal muss der ADC-Eingang als Eingang (DDR = 0) ohne Pull-Up 
(PORT = 0) konfiguriert sein, sonst klappt schonmal die Messung nicht. 
Das was Du da beschreibst, ist aber zunächst mal noch ziemlich konfus. 
Schick doch bitte mal den Programmcode. Ohne den kann man nicht wirklich 
nachvollziehen, was da was ist.

von Frank (Gast)


Lesenswert?

Hallo Johannes,

der "Programmcode" ist noch nicht wirklich vorzeigbar, so das ich dieses 
Kuddelmuddel erstmal keine zumuten möchte. Die Frage die ich eigentlich 
habe ist, wie schaffe ich es zwischen dem Modus digitale Portausgabe und 
Analoger messwerterfassung "unbeschadet hin und her zu schalten.
Ich habe bis jetzt eigentlich nur mit 8051 gearbeitet und da hat man 
diesen "Ärger" mit DDR Registern nicht.

d.h. also jetzt:
1. DDRB=0b00111111; //auf ausgang
2. Ausgabe via printf
3. DDRB=0b00110111; //ADC3 auf eingang
4. ADMUX=0xC3; //ADC3 eingang auwählen
5. ADCSRA=0xC3; //ADC enable
6. wert lesen und in Variable schreiben
7. ?

Ich weiss jetzt halt nicht, wie ich aus der AD-wandler routine wieder 
raus komme und den Port wieder digital zur ausgabe nutzen kann ?

Gruß

Frank

von Roland (Gast)


Lesenswert?

> 4. ADMUX=0xC3; //ADC3 eingang auwählen

Laut Datenblatt wählst du damit eine unsinnige ("reserved") 
Referenzspannung aus.

ADMUX = PORTB3;

oder

ADMUX = PORTB3 | (0<<REFS2) | (1<<REFS1) | (0<<REFS0);

sind besser les- und wartbare Varianten.

von Frank (Gast)


Lesenswert?

Hallo Roland,

stimmt Du hast recht, ist eindeutig reserved, ich hab Ref2 mit Ref0 
vertauscht, danke.
Aber die Frage ist immer noch, wie ich "vorschriftsmässig" zwischen 
AD-Wandlung und Digitaler Portausgabe umschalten kann. Kann mir das mal 
bitte jemand Punkt für Punkt auseinanderbröseln.
Das habe ich irgendwie noch nicht kapiert.

Gruß

Frank

von Roland D. (eigengott)


Lesenswert?

// Setup port PORTB3 for ADC input
PINB &= ~(1<<PORTB3);
DDRB &= ~(1<<PORTB3);
DIDR0 |= (1<<ADC3D);
ADMUX = PORTB3 | (1<<REFS2) | (1<<REFS1);

// Read ADC
...

// Turn off ADC
ADCSRA &= ~(1<<ADEN);

// Setup port PORTB3 for output
DIDR0 &= ~(1<<ADC3D);
DDRB |= (1<<PORTB3);

von Michael Wilhelm (Gast)


Lesenswert?

AD-Wandler initialisieren
ADMUX setzen
wenn fertig (Bit abfragen) dann Portaktion
wenn nict fertig - keine Portaktion
wenn Portaktion fertig - AD-Wandler starten

MW

von Michael U. (amiga)


Lesenswert?

Hallo,

irgendwie verstehe ich Dein Problem nicht ganz:

an PB0, PB2, PB4 das Display -> sind also Ausgänge.

an PB3 der ADC-In -> also Eingang.

Beim init also out DDRB, 0b0xxx101x1
mein x steht für Portleitungen, die Du hier nicht beschrieben hast, muß 
Du also selbst wissen, ob In oder Out.

Da der ADC Eingang ohne PullUp sein muß, mußt Du beim Schreiben auf 
PortB aufpassen, daß PB3 immer 0 geschrieben wird.
Das muß Du aber immer, wenn In und Out gemischt sind, damit Du nicht 
versehentlich die Zustände der PullUps änderst.

Ich mach das meist mit passenden Masken.

.def IN_MASK = 0b00001000

daten enthält das auszugebende Byte

  in temp, PortB

  andi temp,IN_MASK ; jetzt ist im Bit 3 der Wert des Portbits, der den 
Zustand des PullUp festlegt, der Rest ist 0
  and daten, ~IN_MASK ; jetzt ist in daten das Bit 3 auf jeden Fall 0
  or  daten, temp     ; den alten bit 3-Zustand wieder dazu

  out PortB,Daten

Ansonsten tut sich der Kram doch nichts, die Datenrichtungen ändern sich 
ja nicht von allein. ;)

Gruß aus Berlin
Michael

von Frank (Gast)


Lesenswert?

Hallo,

danke erstmal, ich glaube, jetzt hab ich es verstanden.
Ich werde es morgen mal in meinen Code einbauen, schaffe ich jetzt 
leider nicht mehr.

Gruß

Frank

von Frank (Gast)


Lesenswert?

Hallo zusammen,

ich wollte nur nochmal allen danken, es hat geklappt.
Ich habe es jetzt nach der Methode von Roland D. ausprobiert und es 
löpt.

Eine frage habe ich noch zum DIDR0 Register. Roland schaltet das 
Register vor der AD-Wandlung auf 1 und nach der Wandlung auf 0. Da 
dieser Pin bei mir aber nur ein analoges Signal bekommt, könnte man ihn 
doch nur einmal auf 1 setzen und dann so stehen lassen. Geht das so oder 
funktioniert dann, nach der AD-wandlung, meine Digital Ausgabe auf den 
restlichen Portpins nicht mehr ?

Gruß

Frank

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.