Forum: Mikrocontroller und Digitale Elektronik ADC?? bitte um Hilfe


von Mesa K. (mesa)


Lesenswert?

Hallo liebe Kollegen,
ich brauche hilfreiche tips. (arbeite mit ATmega16)
Und zwar will ich mit einem Poti eine Spannung von 0-5V (AVCC und AREF
=5V) einstellen und dann auf dem Display anzeigen.
Display ist an PORTC angeschlossen und den für die A/D Wandlung
benutze
ich den PORTA Pin ADC7.
Einen Text auf dem Display mit dem Befehl ".db" habe ich vor zwei
Woche hingekriegt und über mein ersten Erfolg bin ich sehr glücklich.
(natürlich auch durch die guten hilfen von mikrocontroller.net und
avr-asm-tutorial.net, DANKE).
So meine nächste Schaltung steht, komme seit paar Tagen nicht weiter
daher wende ich mich an alle hier im Forum.
Die Initialisierung für den A/D converter habe ich schon fertig. Soll
ich für drei Ziffern (beispiel: 2,56) jeweils ein Register nehmen oder
wie würde es besser gehen?? Ist das sinnvoll mit macros zu arbeiten??
Wie würdet Ihr da vorgehen?
Bitte um kompetente tips.
danke Mesa

von Hannes L. (hannes)


Lesenswert?

Nunja, der ADC liefert dir nur einen 8-Bit-Wert oder 10-Bit-Wert. Wenn
du diesen am LCD zeigen willst, musst du die Zahl in ASCII-Text
umwandeln. Dazu musst du entweder Funktionen unbekannter Herkunft
vertrauen oder aber die Umwandlung in Text selbst programmieren.

Zuerst ermittelst du mal die höchste mögliche Stellenwertigkeit.
Beim Byte (0...255) sind das die "Hunderter". Beim 16-Bit-Wert
(0...65535) sind das die "Zehntausender".

Dann subtrahierst du den Wert der höchsten Stelle so oft, dass die Zahl
noch positiv bleibt. Die Anzahl der möglichen Subtraktionen ergibt den
Wert der jeweiligen Stelle.
Dies machst du dann für alle Dezimalstellen, beginnend mit der höchsten
Wertigkeit.

Hier ein Beispiel für die Ausgabe eines Bytes als Ziffern an das LCD.
Es wird davon ausgegangen, dass das auszugebende Zeichen von der
Routine "lcd_data" im Register wl erwartet wird. Der Aufruf des
Unterprogramms erfolgt über ein Macro:

.macro print8 ;Registername
                        ;Gibt Zahl im Register 2- oder 3-stellig am LCD
aus.
                        ;Parameter bestimmt das Register, in dem die
Zahl liegt.
                        ;Dieses Register wird nicht verändert.
                        ;Kopie der Zahl temporär in xl,
 push xl                    ;verwendete Register sichern
 mov xl,@0                  ;Kopie vom Quellregister
 rcall lcd_print8           ;Aufruf...
 pop xl                     ;verwendete Register wiederherstellen
.endmacro               ;


lcd_print8:             ;Wird vom Makro aufgerufen. Gibt Byte als 2
oder 3 Ziffern an LCD aus.
 push wl                    ;Reg sichern
 ldi wl,-1+'0'              ;Hunderter-Stelle als ASCII-Zeichen, Zahl
ist positiv
 inc wl                     ;Hunderter hoch und
 subi xl,100                ;100 subtrahieren bis negativ wird
 brsh pc-2                  ;negativ? nein, 2 Zeilen hoch
 cpi wl,'0'                 ;ja, ist Ziffer = "0"?
 breq pc+2                  ;ja, nicht ausgeben...
 rcall lcd_data             ;Hunderter ausgeben...
 ldi wl,10+'0'              ;Zehner-Stelle als ASCII-Zeichen, Zahl
ist negativ
 dec wl                     ;Zehner runter und
 subi xl,-10                ;10 addieren bis positiv wird
 brlo pc-2                  ;positiv? nein, 2 Zeilen hoch...
 rcall lcd_data             ;ja, Zehner Stelle ausgeben...
 ldi wl,'0'                 ;ASCII-0
 add wl,xl                  ;Einer addieren (Rest war ja positiv)
 rcall lcd_data             ;Einer ausgeben...
 pop wl                     ;Reg wiederherstellen
 ret                        ;zurück

Schreibt man nun im Hauptprogramm:

 print8 r4

so wird der Wert in Register r4 als Ziffernfolge an das LCD ausgegeben.
Analog dazu kann man Routinen für größere Zahlen entwerfen (16 Bit, 24
Bit, 32 Bit...).

Wenn dich aber nicht der absolute Wert des ADC interessiert (0...255
bzw. 0...1023), sondern der Wert der anliegenden Spannung, dann musst
du den ADC-Wert vor der Ausgabe noch skalieren. Dazu musst du ihn mit
einem Wert (Konstante) multiplizieren (und ggf dividieren), um in in
deinen gewünschten Wertebereich zu "pressen".

In der Codesammlung bzw. mit der Suchfunktion im allgemeinen Forum
solltest du Beispiele finden.

...

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.