hallo, bin grad beim probieren des adc vom mega128 den gemessenen wert wird im terminal program ausgegeben, wenn ich 5volt am adc0 anlege dann ist ja max=1023 sind den 5volt, wie muss ich das jetzt umändern das er mir nicht 1023 anzeigt sondern 5volt. vielleicht könnte mir jemand von euch ein bischen weiterhelfen danke mfg kay
Kay B. wrote: > hallo, > bin grad beim probieren des adc vom mega128 den gemessenen wert wird im > terminal program ausgegeben, > wenn ich 5volt am adc0 anlege dann ist ja max=1023 sind den 5volt, > wie muss ich das jetzt umändern das er mir nicht 1023 anzeigt sondern > 5volt. Leute, das ist aber jetzt übelst. DREISATZ!
Meinst du einen Dreisatz?! 1023 <=> 5V => 1V <=> 1023 / 5 => um einen gemessenen Wert A (z.B. 644) in eine Spannung B zu konvertieren rechnest du B = A * 5 / 1023 Bei A = 644 wäre B = 3,15V. Schöne Grüße, Alex
@ Kay B. (newbie) >wie muss ich das jetzt umändern das er mir nicht 1023 anzeigt sondern >5volt. Festkommaarithmetik MfG Falk P.S. Wenn du deinen Quelltest als *.asm anhängst wird es noch besser.
hallo Alex, entschuldige vielleicht ne dumme frage, aber wie muss ich das nun in mein code umändern, => um einen gemessenen Wert A (z.B. 644) in eine Spannung B zu konvertieren rechnest du B = A * 5 / 1023 @Falk Festkommaarithmetik,,, das ist in c geschrieben oder? bin der sprache C nicht mächtig leider kann ich die formeln mit meinen browser nicht lesen mfg kay
@ Kay B. (newbie) >=> um einen gemessenen Wert A (z.B. 644) in eine Spannung B zu >konvertieren rechnest du >B = A * 5 / 1023 Genau. >Festkommaarithmetik,,, das ist in c geschrieben oder? bin der sprache C >nicht mächtig Und? Die Rechnung ist unabhängig von der Programmiersprache. >leider kann ich die formeln mit meinen browser nicht lesen ??? MFG Falk
Hi An deiner Stelle würde ich die 2,56V interne Spannungsreferenz benutzen. Da hast du erstmal eine Auflösung von 2,5mV/Bit. Die Eingangsspannung must du natürlich auf die Hälfte teilen. Damit kommst du auf einen ADC-Wert von 1000 bei 5V. Damit wird das Rechnen wesentlich leichter. MfG Spess
Hm.. Nehmen wir mal an, dein ergebnis steht in ADCH:ADCL (rechtsorientiert) Also 0..1023 Dann mache folgendes: Addiere zu der Variablen einfach 1/4 nochmal dazu: (pseudocode) temp1 = r17:r16; temp1 = ADC; temp1 = temp1 + (temp1>>2); (evtl runden) jetz hast du im MSB die Spannungszahl vor dem Komma! Also wenn ADC=1023 => temp1= 0x04FE (runden) dieses highbyte von temp1 gibst du aus, anschließend ein Komma. Dann nimmst du das LSB (also die unteren acht bit von temp1, hier 0xFE) diesen multiplizerst du mit 10, im MSB ist jetzt die erste Kommastelle, (MSB=0x09EC) => 9 ausgeben das LSB wieder mit 10 multiplizieren, (10x 0xEC = 0x0938) im MSB ist jetzt die zweite Kommastelle.. (MSB=09, ausgeben) 0x38 mal 10 = 0x0x0230, 2 ausgeben, 0x30 mal 10 = 0x01E0, 1 ausgeben, 0xE0 mal 10 = 0x08C0, 8 ausgeben, 0xC0 mal 10 = 0x0780, 7 ausgeben, 0x80 mal 10 = 0x0500, 5 ausgeben, .. ergibt: 4,9921875 ( ~ 5*1023/1024, Rundung bei *1,25) Achtung: Die Genauigkeit wird nur vorgegaukelt das geht super der Algorithmus.. Programmieren kannst dus selbst..
@ spess53 (Gast)
>ADC-Wert von 1000 bei 5V. Damit wird das Rechnen wesentlich leichter.
Ohje!!! Und das nur, weil EINE EINZIGE Multiplikation zuviel ist.
MFG
Falk
Hi @Falk Nicht die Multiplikation, sondern die Division durch 1023. Oder ist es für dich illegitim Software durch Nutzung der Hardwareressourcen zu vereinfachen. Diese Referenzspannung ist genau dazu vorhanden. MfG Spess
>Division durch 1023
1024!
Und das ist nicht sooooooo schwer: LOW(var>>2)
Oder das ganz weglassen.... ;-)
@ spess53 (Gast) >Nicht die Multiplikation, sondern die Division durch 1023. Oder ist es Auch DU solltest dir den Artikel Festkommaarithmetik mal in Ruhe zu Gemüte führen. Speziell http://www.mikrocontroller.net/articles/Festkommaarithmetik#ADC_allgemein MfG Falk P.S. Und die Referenzspannung ist selten 2,56V, die Toleranzen sind da bisweilen erheblich. Und wenn man kalibrieren will, muss man in der Software ein wenig rechnen. Tut aber nicht wirklich weh. MFG Falk
hallo, so habs jetzt mal probiert aber es haut nicht hin bekomm das nicht richtig umgesetzt. vielleicht könnte nochmal einer drübersehen. mfg kay
Hi Ich gehe davon aus, Kay nicht nur die 5V sondern auch mal eine andere Spannung mit einer Auflösung <1V messen will. Zum anderen ist die Messung einer Spannung=Referenzspannung sowieso nicht das Grüne vom Ei. MfG Spess
Hi @Matthias Kannst du dein Programm mal etwas erläutern. Wenn ich das nachvollziehe, machst du erst eine Multiplikation mit 1,25 und danach eine mit 5. Macht 6,25. Für ADC=1023 ergibt das 6390 ?!?! MfG spess P.S. 'clc/ror' lässt sich durch 'lsr' ersetzen
@ spess53 (Gast): Ich hab mir den Alghorithmus mal in nem Mikroprozessorpraktikum ausgdacht, die aufgabe war dort etwa so: ein ADC-Wert 8bit, soll eine Spannung von 0..5V darstellen. Also wie hier, nur nicht 10bit, sondern 8bit. (auf 8bit bezogen jetzt:) Ich habe mir da überlegt, dass der maximalwert 255, der ja mit 1/256mal5V gewichtet ist, ja nur mit fünf multipliziert (skaliert) werden muss, um im MSB (8-15.bit) eine Zahl zwischn 0..4 zu bekommen.(255*5=1020=0x04FB) somit ist das MSB die Stelle vor dem Komma: 4,... Volt da ja jetzt das komplette LSB wohl offensichtlich die Nachkommastelle (0..0,99999..V) beinhalten muss, kann ich diese doch einfach mit 10multiplizieren, es entsteht im MSB eine Zahl 0...9. Das ist die erste Nachkommastelle: (10dez* 0xFB=0x09CE) MSB=9, LSB=0xCE => 4,9...V Das 0xCE wieder mit 10mal nehmen: (10dez* 0xCE=0x080C) MSB=8, LSB=0x0C => 4,98...V ... (10dez* 0x0C=0x0078) MSB=0, LSB=0x78 => 4,980...V ... (10dez* 0x78=0x04B0) MSB=4, LSB=0xB0 => 4,9804...V .. (10dez* 0xB0=0x06E0) MSB=6, LSB=0xE0 => 4,98046..V ... (sollte irgendwann abgebrochen werden ,-) PS: 5V*255/256 = 4,98046875V Da in obigen beispiel der Wertebereich 4mal so groß war (1024statt256), dann halt nicht mal5, sondern mal 5/4=1,25.... Noch Fragen? PS: >'clc/ror' lässt sich durch 'lsr' ersetzen lsr ist ohne beachtung des carry-flags, das will ich aber 'rüber'schieben >enn ich das nachvollziehe, machst du erst eine Multiplikation mit 1,25 >und danach eine mit 5. Macht 6,25. Für ADC=1023 ergibt das 6390 ?!?! Nein, nur mit 1,25, im Programm hat sich ein Schusselfehler eingeschlichen: Die Fünf ist hier Unsinn...
1 | temp1H = r17 |
2 | temp1L = r16 |
3 | temp2H = r19 |
4 | temp2L = r18 |
5 | faktor = r20 |
6 | counter = r21 |
7 | ascii = r22 |
8 | |
9 | ;------- werte holen |
10 | mov r17, adch |
11 | mov r16, adcl |
12 | ;------- temp puffer |
13 | movw temp2L, temp1L |
14 | ;------- teile durch vier |
15 | clc ; clear carry flag |
16 | ror temp2H |
17 | ror temp2L |
18 | clc |
19 | ror temp2H |
20 | ror temp2L |
21 | ;------- zusammenrechnen |
22 | add temp2L, temp1L |
23 | adc temp2H, temp1H ; in temp2 steht jetzt 1,25*adc |
24 | ;------- ausgabe highbyte |
25 | mov ascii, -0x30 ; ascii für null |
26 | subi temp2H, ascii |
27 | UDR = temp2H ; über uart senden |
28 | UDR = ',' ; komma senden, warten auf udre einfügen |
29 | ;------- lowbyte mal zehn, |
30 | ldi faktor, 10 |
31 | ldi counter, 5 ; azahl nachkommastellen |
32 | loop: |
33 | mul temp2L, faktor |
34 | subi r0, ascii |
35 | UDR = r0 ; über uart senden, warten auf udre einfügen |
36 | mov temp2L, r1 |
37 | ;------ genug stellen ausgegeben? |
38 | DEC counter |
39 | BRNE loop; |
40 | ;------- nu fertsch ;-) |
Was haltet ihr von dem Algorithmus?
Matthias L. wrote:
> Was haltet ihr von dem Algorithmus?
Hört sich schlüssig an. Wenn das so funktioniert, Hut ab, ziemlich
Tricky.
Hier ist die Lösung aus besagtem Praktikum: Siehe pdf Seite 5: Routine "Analogwert in String umwandeln" AN_TO_STRING: ... Die hier gezeigte Lösung hat allerdings noch eine Vornullenunterdrückung (fall U<1V), sowie ein Autoranging: U>=1V => Anzeige: 1.234V U<1V => Anzeige: 234mV bzw 98mV, nicht 098mV Das Programm hier war aber für so nen 80C500 irgendwas ;-/
hallo, erstmal danke , aber bei mir bekomme ich es nicht zum laufen mfg kay
Kay B. wrote:
> aber bei mir bekomme ich es nicht zum laufen
Der gelieferte Code ist als unfertiges Modell zu betrachten. Dir ist
hoffentlich klar, daß da noch etliche Sachen fehlen, wie z.B.
Wandlerinitialisierung und das warten auf UDRE?
Du solltest das stückweise machen: erstmal nimmst du den adc wert (den du bisher ausgibst) und tust ihn mit 1,25 multiplizieren, das gibst du erstmal aus. Dann machst du schritt für schritt weiter
Hi So sieht das natürlich besser aus. Allerdings kommst du bei ADC=1023 nicht auf 5,00. movw temp2L, temp1L ;------- teile durch vier adiw temp2L,5 ---->könnte helfen clc ; clear carry flag ror temp2H MfG Spess P.S. clc - Löscht Carry-Flag (Cy=0) ror - Schiebt Register+Bit0=Cy lsr - Schiebt Register+Bit0=0 Wo ist da der Unterschied?
>>llerdings kommst du bei ADC=1023 nicht auf 5,00.
Sollst du auch nicht, weil das ja dann nur 1023/1024stel von 5V sind...
der Wertebereich geht ja von 0...5V-1Ulsb
mit Ulsb = 5V/1024..
weil 0..1023 sind 1024 Stufen...
ADC=0 => Uadc>= 0,0000000V
ADC=1 => Uadc>= 4,8828125mV
ADC=1023 => Uadc>= 4,995117188V
Hi Warum soll ich nicht bei 5V auch 5V herausbekommen. Wenn das nicht geht, stimmt irgendwas nicht. MfG Spess
@ spess53 (Gast):
Nein. Dann hast du das Prinzip eines ADC nicht (komplett) verstanden:
Ich vereinfache mal:
Referenzspannung: 8V
Auflösung: 8Stufen: (3bit)
Eingangsspannung ADC-Wert
0,00000000 - 0,9999999... 0
1,00000000 - 1,9999999... 1
2,00000000 - 2,9999999... 2
3,00000000 - 3,9999999... 3
4,00000000 - 4,9999999... 4
5,00000000 - 5,9999999... 5
6,00000000 - 6,9999999... 6
>7,00000000 7
So arbeitet ein ADC!
Er teilt die Referenzspannung in (hier) 8gleiche Teile, diese beginnen
IMMER bei Null und enden bei 2^(bit-auflösung)-1
beachte die MINUS EINS!!!
Somit sind die (hier 3bit) Auflösung ausgeschöpft, und mehr kann nicht
dargestellt werden...
hallo, so jetzt geht es,aber warum wird jetzt zuviel augegeben. vielleicht könnte mir einer nochmal kurz helfen mfg kay
hallo, es wird immer 1,5-2 zuviel angezeigt, könntet ihr mir vielleicht nochmal helfen mfg kay
hallo, vielleicht könnte mir nochmal einer weiterhelfen. bei gemessenen 5Volt wird 6.15 angezeigt woran liegt das sitze schon tage dran aber bekomme das nicht richtig hin. mfg kay
Kay B. wrote: > hallo, > > vielleicht könnte mir nochmal einer weiterhelfen. Ich versuche es mal... > > bei gemessenen 5Volt wird 6.15 angezeigt woran liegt das > sitze schon tage dran aber bekomme das nicht richtig hin. Da ich keinen Mega128 habe (meine Projekte arbeiten mit kleineren AVRs, ich mag nicht mit Kanonen auf Spatzen schießen), kann ich es natürlich nicht testen. Daher keine Gewähr für die Richtigkeit. Zuerst einige Hinweise, die nichts mit dem Fehler zu tun haben: - Die von mir genutzten "kleinen AVRs" haben nicht nur 16 Register, sondern 32. Ich hoffe, das ist beim Mega128 auch so. Da die meisten Registerzugriffe ohne Konstanten erfolgen, lassen sich die unteren 16 Register auch benutzen. ;-) - Du definierst 5 Register (r23-r27), die Du gar nicht benutzt. - Du nutzt eines der tempX-Register für die Addition von 0 mit Carry. Dazu reicht ein unteres Register, das man sinnvollerweise auch noch "null" nennt, völlig aus. Vorteil: Der Code erklärt sich selbst. - Du sicherst Register auf Stack, die gar nicht gesichert werden müssen. - Du nutzt (als temporär gekennzeichnete) Register (temp4, temp3, temp2) als globale Variablen zum Aufsummieren der 256 Messwerte. Das ist schlechter Stil, wenn man eine Variable "temp" nennt, dann muss sie auch temporär verwendbar sein. Sprechende Namen wie "adwh", "adwl" oder "adwn" (AD-Wert- High, Low, Nachkomma) verhindern Missverständnisse, die aktuell eingelesenen Messwerte jeder Runde sind dagegen "temporär" und können in temp-Registern Platz finden. Den eigentlichen Fehler vermute ich hier: - Du Summierst 256 ADC-Messungen in den Registern temp2, temp3 und temp4. Dabei ist temp4 das hochwertige Byte, temp3 das niederwertige Byte und temp2 die (nur für die Rundung berücksichtigte) Nachkommastelle. Dein 16-Bit-Ergebnis steht also in temp4:temp3. - Du zerelegst in "number16:" eine 16-Bit-Zahl und schickst die einzelnen Ziffern über UART an den PC. Du zerlegst aber nicht (wie gewollt) temp4:temp3, sondern temp3:temp2. Vernünftige Registernamen hätten das Missverständnis verhindert. Dazu kommt noch etwas Unsinn beim Push und Pop der auszugebenden Register. - Du erwartest bei 5V angelegter Messspannung Zahlenwerte von etwa 5 oder 5,00. Ich sehe in Deinem Code aber nirgends eine Skalierung. Die Zahlenwerte, die Du bei Beseitigung des anderen Fehlers erwarten kannst, sind 00000 bis 01023. Fazit: Das Abschreiben von Tutorial-Beispiel-Codes bringt nichts, solange Du sie nicht verstehst. Mein Vorschlag: Nimm zum Lernen einen kleinen AVR wie den Mega8, der ist übersichtlicher und wird von vielen Leuten hier verwendet, wodurch sich vermutlich mehr Helfer finden. Außerdem sind viele Teile des Tutorials für den Mega8 geschrieben. Falls Du ihn dieses Jahr noch brauchst, kannst Du Dir gerne einen oder zwei bei mir abholen. Ich hätte auch noch ein funkelniegelnagelneues blitzeblaues 4x40-LCD für Dich... ;-) ...
@ Kay B. (newbie) >bei gemessenen 5Volt wird 6.15 angezeigt woran liegt das >sitze schon tage dran aber bekomme das nicht richtig hin. Schau mal hier, ich hab das Tutorial etwas aufgebohrt. AVR-Tutorial: ADC MFG Falk
hallo, das erweiterte adc-beispiel habe ich mal ausprobiert das geht allerdings sende ich auf uart1. wenn nun vielleicht andere sachen noch zuerledigen sind (dann sind ja nicht mehr genügend register vorhanden) zb. ausgabe auf dem lcd. hallo hannes, mega8 habe ich hier auch ein paar rumliegen . mfg kay
Kay B. wrote: > wenn nun vielleicht andere sachen noch zuerledigen sind Dann kommt man mit dem Stil im Tutorial nicht weit, da an allen Ecken und Kanten gewartet wird anstatt andere Dinge zu erledigen. > (dann sind ja > nicht mehr genügend register vorhanden) Nööö, es wurde (außer zur Multiplikation r0 und r1) noch kein einziges unteres Register verwendet. Und RAM ist auch noch jede Menge frei. Wenn man das Beispiel etwas aufräumt, dann sind auch genügend Register frei. > zb. ausgabe auf dem lcd. Nööö, auch dazu reichen die Register noch massig. > > > > > hallo hannes, > > mega8 habe ich hier auch ein paar rumliegen . Und warum benutzt Du dann für sooo triviale Dinge Deinen Mega128? Lass ihn doch liegen bis Du etwas mehr Durchblick hast und mach' die Tutorial-Beiträge mit einem Mega8. Es wäre doch schade drum, wenn er bei solch trivialen Experimenten durch ein Missgeschick beschädigt würde. > > mfg kay ...
hallo, erstmal danke für die hilfe von euch. aber ich krieg das einfach nicht hin. mfg kay
@ Kay B. (newbie) >erstmal danke für die hilfe von euch. >aber ich krieg das einfach nicht hin. WAS willst du denn überhaupt machen? Dein Problem mit der ADC-Ausgabe ist doch scheinbar nun gelöst. MFG Falk
hallo, die ausgabe auf'n rechner funktioniert ja so wie tutorial, nun wollte ich versuchen statt die ausgabe zum pc aufs display zubekommen daran haberts gewaltig. mfg kay
@ Kay B. (newbie) >daran haberts gewaltig. Tja, vor den Erfolg haben die Götter den Schweiss gesetzt. Aber auch hierfür gibt es Tutorials. AVR-Tutorial: LCD Kleiner Tip. Der String ist schon fertig. Er muss nur auf das LCD statt den UART ausgegeben werden. Was nicht wirklich ein Problem ist. MFG Falk
Ich habe die Vermutung, dass Kay Probleme hat, die Ressourcen eigenständig zu verteilen/verwalten. Das Tutorial nutzt unbekümmert obere Register, wo auch untere Register reichen würden, nun fehlen ihm die Register für die LCD-Routinen. Vielleicht dringt Kay ja beim "Verstehen" der Zusammenhänge nicht tief genug in die Materie ein? Mein Tip an Kay: Kleiner überschaubarer AVR, kleine überschaubare Aufgaben, bei der Lösung der Aufgabe jedes Bit versuchen zu verstehen. Das Zusammenkopieren von fremden Quelltexten und Verändern dieser Quelltexte nach Versuch und Irrtum führt in eine Sackgasse. ...
@ Hannes Lux (hannes) >Mein Tip an Kay: Kleiner überschaubarer AVR, kleine überschaubare >Aufgaben, bei der Lösung der Aufgabe jedes Bit versuchen zu verstehen. >Das Zusammenkopieren von fremden Quelltexten und Verändern dieser >Quelltexte nach Versuch und Irrtum führt in eine Sackgasse. Amen. Das sollte man 1:1 in den noch leeren Artikel Copy&Paste Programmierung übernehmen. Ich bin mal so frei. MFg Falk
hallo, erstmal danke für die hilfe,habs mal mit einen mega8 versucht aber da komm ich auch nicht weiter, den adc wert aufs dispaly darzustellen. danke nochmals für die hilfe. mfg kay
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.