Forum: Mikrocontroller und Digitale Elektronik ADC Wandler - ASCII


von Ano N. (oorim)


Angehängte Dateien:

Lesenswert?

Hallo,

Eine neue Frage von mir: Wir haben demletzt die Aufgabe gehabt den ADC 
ans laufen zu bringen. Nachdem wir dann "Single Conversion Mode" und den 
"Free Running Mode" gemeinsam aktiviert hatten lief er auch (warum beide 
Aktiviert sein müssen weis ich nicht, das war mir auch mit Manual nicht 
ganz klar aber nur so läuft er beim Mega128). Jetzt stellen sich mir 
aber zwei Fragen:
1) Wir haben den ADC Wert linksbündig ausgerichtet (also die niedrigsten 
2 Bit sind in ADCL) und nur ADCH weiter verarbeitet um die ungenauigkeit 
von 2LSB zu eliminieren. Funktioniert auch soweit Tadellos, die letzten 
2 Bit flackern zwar ab und an aber das ist nicht weiter Tragisch da die 
Anzeige ziemlich Stabil ist (Anzeige = 8 LED). Im Tutorial wurde der 
Mittelwert aus 256 Werten gebildet - ist das "immer" ein guter Weg oder 
reicht es bei einfachen Aufgaben wie unserer (ADC Wert auf 8 LEDs 
abbilden) einfach den ADC Wert selbst zu nehmen und abzubilden? Ich 
denke nicht das die Mittelwertbildung sehr stark ins Gewicht geht. Wenn 
ich es richtig verstand braucht der ADC bei 128kHz Takt 1/128kHz=7,8µs 
für eine Wandlung (was mir allerdings schnell vorkommmt) - da tut es 
nicht weh wenn man 256 Werte misst. Den Code habe ich angehangen - 
sollten wir die Mittelwertbildung noch einbauen und sei es aus dem 
lernzweck?

2) Umwandlung des ADC Wertes in einen ASCII Wert. Ich habe mir das ganze 
im Tutorial angesehen, aber die Wandlung an sich versteh ich noch nicht 
ganz. Es gibt zwar dort eine Tabelle mit Zahlen, aber wie die Wandlung 
selbst von statten geht (ich sehe keinen Zugriff auf die Tabelle) das 
ist mir noch schleierhaft. Kann mir da jemand auf die sprünge helfen?



Danke für eure Antworten und Hilfestellungen!




Grüße

von spess53 (Gast)


Lesenswert?

Hi

Wenn du dich auf das hier beziehst:

Int_to_ASCII:

    push    ZL                      ; Register sichern
    ....
    ldi     ZL,low(Tabelle*2)       ; Zeiger auf Tabelle
    ldi     ZH,high(Tabelle*2)

dann findest du den Tabellenzugriff inden letzten beiden Zeilen. 
Innerhalb des Programms wird mit 'lpm xyz,Z+' auf die Tabelle 
zugegriffen.

MfG Spess

von Sven (Gast)


Lesenswert?

zu 1. wenn ihr nur die oberen 8 Bit nehmt, sollte da nichts flackern, 
wenn die Eingangsspannung konstant ist. Wo kommt die Eingangsspannung 
her und wie ist der Eingang beschalten?

zu 2. Du musst Deinen Wert in die Ziffern zerlegen.

a) teile den ADC-Wert jeweils durch 10, der Rest ist Deine Ziffer, das 
Ergebnis wieder teilen, 3 mal. Du bekommst die Ziffern in der 
Reihenfolge Einer-Zehner-Hunderter. Die Ziffern plus 48 (ASCII-Wert von 
0) ergibt die ASCII-Zeichen, die ans Display oder PC oder wasauchimmer 
schicken, Reihenfolge beachten. Rechenaufwändig, da Div-Routinen 
benötigt.

b) zähle die Ziffern pro Stelle runter. Schnell, aber mehr Code bei 
mehrstelligen Zahlen als Variante a).

Mal als Anregung, musst Du noch auf 3 Stellen erweitern:
1
  ;**** Ausgabe TEMP1 als ## an Display ****
2
3
display_nn:
4
  ldi  DATA, '0' - 1    ;Data mit ASCII'0'-1 setzen
5
disp_nn_2:
6
  inc  DATA
7
  subi  TEMP1, 10    ;Subtrahiere 10
8
  brcc  disp_nn_2    ;wiederholen, solange positiv
9
  subi  TEMP1, -10    ;Addiere 10
10
  cpi  DATA, '0'
11
  brne  disp_nn_nlz    ;keine führende Null
12
  ldi  DATA, ' '    ;sonst unterdrücken
13
disp_nn_nlz:
14
  rcall  display_write    ;Ziffer schreiben
15
  
16
  ldi  DATA, '0' - 1    ;Data mit ASCII'0'-1 setzen
17
disp_nn_1:
18
  inc  DATA
19
  subi  TEMP1, 1    ;Subtrahiere 1
20
  brcc  disp_nn_1    ;wiederholen, solange positiv
21
;  subi  TEMP1, -1    ;Addiere 1
22
  rcall  display_write    ;Ziffer schreiben
23
24
  ret        ;zurück

von Ano N. (oorim)


Lesenswert?

@ Sven:
Danke soweit. Das ich den ADC Wert in die einzelnen Stellen zerlegen 
muss wenn ich es als ASCII Wert darstellen möchte ist klar. Wie ist dann 
eine andere frage, das hast du ja ziemlich beantwortet. Wenn ich aber 
nur den ADC Wert ausgeben will, so wie wir es gemacht haben, ist es dan 
von nöten zu Mitteln oder kann man sich den "aufwand" sparen und einfach 
immer ausgeben? Und stimmt meine Anahme das bei einer Frequenz von 
128kHz eine Wandlung 1/128k*sec braucht?

Das ganze System ist der Atmega 128 auf dem STK500+501. Woher die 
Spannung für die ADC Messung kommt weis ich ehrlich gesagt nicht, wir 
haben ein Poti am STK hängen über das wir die Spannung einstellen 
können.

spess53 wrote:
> Hi
>
> Wenn du dich auf das hier beziehst:
>
> Int_to_ASCII:
>
>     push    ZL                      ; Register sichern
>     ....
>     ldi     ZL,low(Tabelle*2)       ; Zeiger auf Tabelle
>     ldi     ZH,high(Tabelle*2)
>
> dann findest du den Tabellenzugriff inden letzten beiden Zeilen.
> Innerhalb des Programms wird mit 'lpm xyz,Z+' auf die Tabelle
> zugegriffen.
>
> MfG Spess


Danke auch dir das habe ich glatt übersehen schäm. Mit Zeigern haben 
wir (noch?) nichts gemacht/machen müssen/erklärt bekommen. Nur das es 
diese gibt ... Danke für den hinweis ich schau mir den Code noch mal an.

von spess53 (Gast)


Angehängte Dateien:

Lesenswert?

Hi

>Und stimmt meine Anahme das bei einer Frequenz von 128kHz eine Wandlung 
>1/128k*sec braucht?

Nein. Werte siehe Anhang. Die genaue Berechnung steht im Datenblatt.

MfG Spess

von Ano N. (oorim)


Lesenswert?

spess53 wrote:
> Hi
>
>>Und stimmt meine Anahme das bei einer Frequenz von 128kHz eine Wandlung
>>1/128k*sec braucht?
>
> Nein. Werte siehe Anhang. Die genaue Berechnung steht im Datenblatt.
>
> MfG Spess

Okay danke. Ich meine da auch mal was gesehen zu haben... 
Mittelwertbildung un zwingend Pflicht oder nur bei der Auswertung als 
Spannungswert?

von spess53 (Gast)


Lesenswert?

Hi

>Mittelwertbildung un zwingend Pflicht oder nur bei der Auswertung als
>Spannungswert?

Mach doch erst mal die ASCII-Ausgabe. Wenn das dann zappelt kann man 
immer noch eine Mittelwertbildung machen.

MfG Spess

von Ano N. (oorim)


Lesenswert?

Naja worauf die ASCII Ausgabe? Auf die LEDs? Ansonsten hab ich ich die 
möglichkeit experimente zu machen weil wir die Boards bislang nur im 
Labor haben :( (mir fehlt noch der USB Programmer für daheim...)

von Sven (Gast)


Lesenswert?

>> nur den ADC Wert ausgeben will, so wie wir es gemacht haben, ist es dan
>> von nöten zu Mitteln oder kann man sich den "aufwand" sparen und einfach
>> immer ausgeben?

Das kommt auf Deine Signalquelle und die gewünschte Anzeige an. Bei Poti 
an kurzer Leitung und nur 8 bit (Highbyte) würde ich nicht mitteln. 
Machst Du eine Spannungsmessung an unbekannter Quelle oder eine Messung 
mit langen, ungeschirmten Messleitungen, kann es nötig sein zu mitteln, 
4 mal, 8 mal, 16 mal, 256 mal. Ich hatte schon eine Messung von 
minimalen Photoströmen, da haben wir systembedingt über 1024 oder so 
Werte gemittelt, weil das Signal so verrauscht war.

>> Und stimmt meine Anahme das bei einer Frequenz von
>> 128kHz eine Wandlung 1/128k*sec braucht?

Nö, müßten 13/128ksec sein, weil der ADC 13 ADC-Takte (nicht Quarztakte) 
braucht für eine Wandlung. Steht irgendwo ausführlich im Datenblatt.

>> Das ganze System ist der Atmega 128 auf dem STK500+501. Woher die
>> Spannung für die ADC Messung kommt weis ich ehrlich gesagt nicht, wir
>> haben ein Poti am STK hängen über das wir die Spannung einstellen
>> können.

Naja, dann wird die schon einigermaßen stabil sein. Da sollte also 
höchstens das LSB (10te Bit) schwanken, wenn die Leitungen kurz sind und 
das Poti nicht zu hochohmig ist (10-20k).

>> Danke auch dir das habe ich glatt übersehen schäm. Mit Zeigern haben
>> wir (noch?) nichts gemacht/machen müssen/erklärt bekommen. Nur das es
>> diese gibt ... Danke für den hinweis ich schau mir den Code noch mal an.

Eine Tabelle brauchst Du für ASCII-Umrechnung eigentlich nicht, die wird 
bei 7-Segment-Darstellung interessant.

von Ano N. (oorim)


Lesenswert?

Jup im Datenblatt sollte was stehen, ich eriner mich dunkel. Irgendwas 
war da ... muss ich noch mal nachschauen.

Gut... das mit dem Mitteln von Messwerten bei schlechten Quellen ist mir 
bewusst - hab ich auch schon mehrmals gemacht - aber in wie weit ich das 
hier einsetzen muss ist mir jetzt erst richtig klar danke.

Ob ich die Tabelle brauche oder nicht ist eine andere Frage, ich habe 
mich nur auf das Tutorial bezogen wo sie verwendet wird. Die Formel um 
aus dem ADC Wert dann die Spanung auszurechen hab ich nich mehr ganz im 
Kopf ... ich glaube es war Ux=Z/2^n * Uref (Z=Aktueller Zählerstand, 2^n 
gesamte Zählerbreite, Uref Referenzspannung). Das müsste man dan nach 
ASCII Wandeln und hätte seinen Spanungswert :) Naja bis dahin dauert es 
noch und ich denke meine eigenen Projekte lasse ich auf C laufen, damit 
komm ich bisher besser klar ...

Grüße

von eProfi (Gast)


Lesenswert?

Beitrag "ADC-Wert z.B. in Spannung umrechnen und dezimal ausgeben mittels Tabellen, auch Linearisieren"

Ist zwar in C, aber das Prinzip ist genau so in asm realisierbar.

Meinst Du das mit den Tabellen?
Wenn gewünscht, erkläre ich es auch noch genauer.

von spess53 (Gast)


Lesenswert?

Hi

>Ist zwar in C, aber das Prinzip ist genau so in asm realisierbar.

Aber in der Form für den vorleigenden Fall total 'oversized'. Eine 
Dezimal- + ASCII-Umwandlung dauert in Assembler für den Wertebereich, 
geschätzt, weniger als 30µs (@ 4,...MHz). Der mögliche 
Geschwindigkeitsgewinn deiner Variante rechtfertigt die mindestens 
20-fache Codegrösse auf keinen Fall.

MfG Spess

von Ano N. (oorim)


Lesenswert?

Macht doch einfach beide mal jeweils eien vorschlag - einma mit, einma 
ohne Tabelle. Würd mich doch mal interessieren jetzt :)

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.