mikrocontroller.net

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


Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
.include "tn13def.inc"

.def RefHigh= R17
.def ADHigh= r18
.def ADLow=r19

  ldi r16, 0xFF     ; 0xFF in r16 schreiben  
  out DDB0, r16     ; Pin5 an Port B als Output definieren

  ldi r16, 0x00     ; 0x00 in r16 schreiben
  out DDB5, r16     ; Pin 0 an Port B als Input definieren

  ldi RefHigh, 0x40  ; Referenzwert für High festlegen

  sbi ADCSRA, ADEN  ; AD-Wandler Enable!
  sbi ADMUX, ADLAR  ; Linksbuendigkeit der AD-Register einstellen
  cbi ADMUX, REFS0  ; Vcc als Referenzwert nehmen (+5V)
loop: 
  sbi ADCSRA, ADSC  ; erste Messung starten
warten:  
  sbic ADCSRA, ADSC  ; Abwarten, bis Messung fertig
  rjmp warten
  
  IN ADLow, ADCL
  in ADHigh, ADCH

  cp RefHigh, ADHigh     ; Abgleichen
  BRSH setzen  ; "Branch if same or higher" Springt zu "loop"
      ; wenn RefHigh größer als ADHigh !!! 
    cbi PORTB, 5  ; Bit 5 auf null setzen
  rjmp loop;  ; zu loop springen

setzen:
  sbi PORTB, 5  ; Setzt Bit 5

  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

Autor: Klaus (Gast)
Datum:

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

Autor: Robert (Gast)
Datum:

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

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
push

Autor: Johannes M. (johnny-m)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Robert (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ?
sbi DDRB, 5   ; Bit 5 als Output
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.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.