Forum: Mikrocontroller und Digitale Elektronik Frage zu Assemblercode für AD-Wandler


von Robert (Gast)


Lesenswert?

Hallo! Ich hoffe, ich bin damit jetzt im richtigen Forum.

Vorweg: ich beschäftige mich seit etwa einer Woche mit dem Thema uC und 
bin daher noch nicht allzu bewandert.
Hab mich bisher nur mit Bausteinprogrammierung (LOGO, SPS) und java 
auseinander gesetzt.

Ich habe folgendes Problem: Der Zweck meiner Schaltung dient der 
Feuchtigkeitsmessung in einem Blumentopf. Ich baue also einen 
Feuchtigkeitssensor.
Das Prinzip sollte funktionieren: Ich greife die Spannung an 2 
Elektroden, die in der Erde stecken über einen Spannungsteiler ab und 
will dieses Signal nun mit dem AD-Wandler im Tiny13 sohingehend 
verarbeiten, dass es ein Ausgangssignal gibt, sobald die Spannung einen 
bestimmten Wert unterschreitet (Erde wird nass - >Widerstand 
Pflanzenerde sinkt -> Spannung sinkt).
Dazu hab ich nun folgenden Assembler-Code geschrieben:
1
.include "tn13def.inc"
2
3
.def RefHigh= R17
4
.def ADHigh= r18
5
.def ADLow=r19
6
7
  ldi r16, 0xFF     ; 0xFF in r16 schreiben  
8
  out DDB0, r16     ; Pin5 an Port B als Output definieren
9
10
  ldi r16, 0x00     ; 0x00 in r16 schreiben
11
  out DDB5, r16     ; Pin 0 an Port B als Input definieren
12
13
  ldi RefHigh, 0x40  ; Referenzwert für High festlegen
14
15
  sbi ADCSRA, ADEN  ; AD-Wandler Enable!
16
  sbi ADMUX, ADLAR  ; Linksbuendigkeit der AD-Register einstellen
17
  cbi ADMUX, REFS0  ; Vcc als Referenzwert nehmen (+5V)
18
loop: 
19
  sbi ADCSRA, ADSC  ; erste Messung starten
20
warten:  
21
  sbic ADCSRA, ADSC  ; Abwarten, bis Messung fertig
22
  rjmp warten
23
  
24
  IN ADLow, ADCL
25
  in ADHigh, ADCH
26
27
  cp RefHigh, ADHigh     ; Abgleichen
28
  BRSH setzen  ; "Branch if same or higher" Springt zu "loop"
29
      ; wenn RefHigh größer als ADHigh !!! 
30
    cbi PORTB, 5  ; Bit 5 auf null setzen
31
  rjmp loop;  ; zu loop springen
32
33
setzen:
34
  sbi PORTB, 5  ; Setzt Bit 5
35
36
  rjmp loop  ; Schleife loop wiederholen (weil Sensor)

Da mir die Genauigkeit nicht allzu wichtig ist, Ordne ich die Bits im 
ADC linksbündig an, um nur dieses eine Register (ADCH) abfragen zu 
müssen.

Nun zu meiner eigentlichen Frage: Würde das Programm so nun 
funktionieren, oder fehlt irgendetwas absolut notwendiges? Laut 
AVR-Studio-Simulation is alles super, aber was ist zum Beispiel mit der 
Taktfrequenz des ADC? Ist es notwendig, da noch irgendwas einzustellen? 
Hab mir zwar schon Beispielprogramme angeschaut, aber blicke da 
irgendwie nicht so richtig durch... und meistens gehts ja um eine 
möglichst genaue Messung. Mir reicht ja ein ungefährer Wert.

Bitte helft einem Neuling :)

MfG
Robert

von Klaus (Gast)


Lesenswert?

Der Vorteiler wird im  ADCSRA Reg eingestellt!
Also bei Dir momentan (ADPS2 ADPS1 ADPS0) 0,0,0 ->
Vorteiler = 2

von Robert (Gast)


Lesenswert?

Was heißt das jetzt genau für meinen Messvorgang? Und würde der Rest so 
auch funktionieren?

von Robert (Gast)


Lesenswert?

Achja: und is das notwendig da nachher noch nen quarz dran zu hängen, 
oder reicht der interne Takt für solch "simple" aufgaben aus?

von Robert (Gast)


Lesenswert?

push

von Johannes M. (johnny-m)


Lesenswert?

Robert wrote:
> Achja: und is das notwendig da nachher noch nen quarz dran zu hängen,
> oder reicht der interne Takt für solch "simple" aufgaben aus?
Beim Takt für den ADC kommt es nicht auf Genauigkeit und Stabilität 
an. Für einen Quarz gibt es nur wenige zwingende Gründe, der Betrieb des 
ADC allein zählt nicht dazu.

Abgesehen davon: Wenn Du schon ADLAR gesetzt hast und schreibst, Du 
willst nur ADCH auslesen, warum liest Du dann trotzdem noch ADCL aus?

Ansonsten sieht das bis auf die fehlende Prescaler-Konfiguration gar 
nicht so verkehrt aus.

EDIT:
RUDER ZURÜCK
> out DDB0, r16     ; Pin5 an Port B als Output definieren
DDB0 ist die Nummer eines Bits, der kannst Du nichts zuweisen! Da muss 
ein DDRx hin, mit x = Name des Ports. Schau bitte mal ins 
AVR-Tutorial und in den Artikel Bitmanipulation, da steht, wie 
man einzelne Bits bearbeitet. So, wie es da steht, macht es keinen Sinn. 
Dein Kommentar stimmt auch gar nicht mit dem Inhalt der Zeilen überein.

Und Kommentare wie in der Zeile darüber sind einfach nur überflüssig. 
Ein "ldi r16, 0xFF" muss man nicht kommentieren!

von Robert (Gast)


Lesenswert?

Gut, ich hatte mir das aus der Doku für den Tiny gezogen... habs dann 
unter Umständen falsch verstanden.
Mh... ja und die Kommentare hab ich wohl verdreht -.-

Also muss das so laufen ?
1
sbi DDRB, 5   ; Bit 5 als Output
2
cbi DDRB, 0   ; Bit 0 als Input


ADCL hab ich ausgelesen, weil irgendwo stand, dass man den trotzdem 
auslesen sollte... Dacht mir halt: Schaden kanns nicht ;) Aber gut, 
wenns unnötig is, kann ichs auch wieder raus nehmen.

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.