Hallo Leute,
ich hab vollgendes Problem Ich muss für meine schule ein Strommessgerät
entwickeln. Jetzt muss ich den Betrag vom Ad-wandler was an Ain 0
anliegt auf die Lcd bringen aber in einer Kommazahl. Bedeutet ja der
Betrag in Ain0 wir durch 256 geteilt und der wert in den Akku
gespeichert. Dieses muss ich dann nehmen ihn für eine Look uptable
nehmen und den vorkommaWert suchen, diesen danna uf die lcd bringen.
Dachach den Wert in eine andere Tabelle nehmen und den Nachkommastellen
Wert suchen und auf die lcd beringen.
Vorgabe ist ein Messbereich von 0-5V also hab die looUp schon 5:256 und
dann die werte in die lookups geschrieben. Nund hab und keien idee wie
ich den rest umsetzten soll
Teile uns doch mal mit, auf was für einem Mikrocontroller du arbeitest.
Dann könnten wir dir vielleicht helfen. Bei einigen µCs gibt es bereits
Funktionen, die die Funktionalität bereitstellen.
> Bedeutet ja der Betrag in Ain0 wir durch 256 geteilt und der> wert in den Akku gespeichert. Dieses muss ich dann nehmen> ihn für eine Look uptable nehmen und den vorkommaWert suchen,> diesen danna uf die lcd bringen.> Dachach den Wert in eine andere Tabelle nehmen und den> Nachkommastellen Wert suchen und auf die lcd beringen.
Machs nicht so komplizert.
Mach dir EINE Lookup Tabelle in der du zb das 100-fache des Wertes
speicherst (als Vorkomma + 2 Nachkommastellen) und während der Ausgabe
schummelst du vor die letzten beiden auszugebenden Stellen einen
Dezimalpunkt ein.
Und so wird dann aus 439, die du aus der Tabelle bekommst, auf der
Anzeige ein "4.39"
(aber aufpassen mit führenden 0-en. Aus 29 muss an der Ausgabe 0.29
werden, wenn deine Ausgaberoutinen führende 0-en unterdrückt)
Manuel schrieb:> Haben ein ATMEL 895131A
Das ist schön - schade nur, das der gar keinen AD Wandler hat. Und hilft
auch nicht weiter, wenn du Pinkte einbauen willst. Und ausserdem wissen
wir ja nicht einmal, in welcher Programmiersprache ihr da rumwurschtelt.
Beitrag "Einheitlicher Umgang mit faulen Schülern etc.?"
Wie der hat kein Ad-Wandler hab auch den falschen gepostet.
Hier nochmal der neue: Atmel 89C5131A-UM
Hier mal wie wiet ich bisher bin:
Teste noch herum
;-----------------------------------------------------------------------
;Auswahl zwischen Spannungsbereich 0-10V, 0-5V
mov a,90h ;Wert von P1.0(90h) in akku
mov r1,a ;Akku in r1
mov a,91h ;Wert von P1.1(91h) in akku
mov r2,a ;Akku in r2
cjne r1,#1,Auswahl ;Vergleiche r1 mit Konstanten 1
lcall Ain0 ;Abfrage Wert an Ain0
mov DPTR,#tabelle10V1 ;Lookup Tablle einfügen
movc a,@a+DPTR ;Wert aus Tabelle 10V1 holen
mov r4,a
lcall r4
lcall Ain0
mov DPTR,#tabelle10V2
movc a,@a+DPTR
lcall dezaus ;Ausgabe Wert ind Dezimal von Ain0 (Ad-Wandler)
Auswahl: cjne r2,#1,Auswahl
lcall Ain0 ;Abfrage Wert an Ain0
mov DPTR,#tabelle5V1 ;Lookup Tablle einfügen
movc a,@a+DPTR ;Wert aus Tabelle 5V1 holen
mov r4,a
mov DPTR,#tabelle5V2
movc a,@a+DPTR
lcall dezaus ;Ausgabe Wert ind Dezimal von Ain0 (Ad-Wandler)
Na gut,
zumindest scheint es so als ob du dich bemühst. Dann legen wir mal los
ein bisschen zu helfen. Allerdings möchtest du doch wissen, wie du die
Ausgabe des '.' oder ',' realisierst. Gerade die Funktion "dezaus" die
das machen soll fehlt in deinem Beitrag. Bitte nachliefern. Am besten
den kompletten Code posten.
Gruß lowlevel
dezaus fehlt immer noch
Aber ich fürchte, selbst mit der Kentnis dieser Funktion wird das
nichts. Solange du nicht mit 16 Bit Werten hantieren kannst, ist das
vergebliche Liebesmühe.
Zu deinen Tabellen.
Ich weiß nicht, ob du das schon mal gehört hast. Aber dein µC ist ein
kleiner Computer! Der kann rechnen! Du kannst natürlich eine Division
durch eine Tabelle ersetzen. Sinnvoll ist das aber nicht. Sinnvoll wäre
es, zu lernen, wie man in Assembler eine 16 Bit Division durchführt.
Manuel schrieb:> wo fehlt denn dieser befehl
nicht 'er fehlt'.
Sondern hier
1
lcall dezaus ;Ausgabe Wert ind Dezimal von Ain0 (Ad-Wandler)
wird ein Unterprogramm aufgerufen, welches offenbar die Ausgabe macht.
Da es aber zu prüfen gilt, ob und wie man da während der Ausgabe einen
'.' in die Ausgabe an der entsprechenden Stelle einschmuggeln kann, wird
man sich wohl ansehen müssen, wie denn diese Ausgabefunktion eigentlich
arbeitet.
Nun versteh ich von deinem µC nicht viel. Was ich aber verstehe ist,
dass du dich bei deinem ganzen Programm mehr oder weniger auf 8 Bit
Arithmetik eingeschworen hast. Und solange das so ist, wird das auch
nichts werden mit dieser vorgschlagenen Strategie. Du musst zumindest
soweit in deinen Fähigkeiten sein, dass dich 16 Bit Arithmetik
(Addieren, Subtrahieren, Multiplizieren, Dividieren) nicht vor unlösbare
Probleme stellt. Wie willst du denn je vernünftig deinen µC zu
Rechenaufgaben heranziehen, wenn du nicht wenigstens im Zahlenraum 0 bis
65-tausend problemlos einfache Berechnungen machen kannst? Du kannst
dich nicht ewig mit 8-Bit Tabellen aus der Affäre ziehen, zumal das dann
wieder andere Probleme (eben durch den beschränkten Zahlenraum) nach
sich zieht.
Karl Heinz Buchegger schrieb:> Mach dir EINE Lookup Tabelle
Nein!! Mach dir bitte KEINE Lookup-Tabelle.
O Herr, lass Hirn regnen.
das elendige Thema, daß die Leute in ihrer Beschränktheit immerzu
glauben, daß ein Ergebnis eines ADC's eine Integerzahl darstellen würde,
hatten wir doch schon so unsäglich oft. Anschließend kommt immer die
Frage "Wie kann ich aus den Integerzahlen 0..255 ein Ergebnis 0.0 Volt
bis 4.999 Volt machen?"
Ich versuch's mal in diskreten Erkenntnis-Stufen:
1. Erkenntnis: Das, was ein ADC ausspuckt, sind Bits - und keine
Spannungswerte.
2. Erkenntnis: Diese Bits haben üblicherweise (aber nicht immer) eine
Wertigkeits-Reihenfolge untereinander, also es gibt ein "dickstes"
sprich höchstwertigstes Bit (das MSB) und die anderen Bits haben einen
kleineren Wert. Daß das immer ne Zweierpotenz sein muß, ist falsch. Es
gibt auch BCD-ADC's (die in den Taschen-Multimetern) und es gibt welche,
die Gray-Code ausspucken.
3. Erkenntnis: Niemand hat gesagt, daß ein bestimmtes Bit einen
bestimmten Wert (z.B. 1 Volt) hat. Wer es nicht glauben will, der hängt
vor den ADC einen Spannungsteiler oder ändert die Referenzspannung und
schon bedeutet das Bit ne andere Eingangsspannung. Wir sehen also, daß
die Wertigkeiten aller Bits von der Eingangsbeschaltung und der Referenz
abhängt.
4. Wenn wir aus den Bits, die aus dem ADC kommen, eine ZAHL bilden
wollen, dann müssen wir den Bits jeweils eine Wertigkeit zuweisen. Wir
könnten (für das Beispiel aus dem Threadbeginn) z.B. dem MSB den Wert
0.5 zuweisen, dem nächsten den Wert 0.25, den dritten 0,125 usw.
Alle so zugeordneten Bits bilden dann eine echt gebrochene Zahl von 0
bis 0.99606299212, die wir großzügig zu 0.996 runden. Was haben wir nun
davon? Nun, wir multiplizieren später einen Faktor, der unsere Referenz
und einen Spannungsteiler usw. enthält und schon haben wir unser
Ergebnis in Volt.
5. Erkenntnis: Wenn ich eine echt gebrochene Zahl mit 10 multipliziere,
bekomme ich vor dem Dezimalpunkt die erste Stelle und danach den Rest.
Also ich hab 0.3745 und multipliziere:
0.345 * 10 --> 3.745
Nun kann ich den ganzen Teil abtrennen und ausgeben und rechne mit dem
Rest weiter:
0.745 * 10 --> 7.45
Wieder ganzen Teil abtrennen und mit dem Rest weitermachen:
0.45 * 10 --> 4.5
usw. bis ich genug Stellen habe.
6. ne Nachüberlegung:
Mein o.g. Faktor sei hier 5, weil ich einen ADC hab, der von 0 bis knapp
5 Volt "geht". (genauer: 5 * 0.99606299212 --> ca. 4.98 Volt)
Ich müßte also 5 * ADCwert rechnen und dann hätte ich schon als erstes
Ergebnis meinen ganzen Teil, den ich abtrennen kann. Der Rest ist ja
wieder kleiner als 1 und damit geht die Rechnung so:
1. Schritt: ADC*5, ganzen Teil abtrennen
2. Schritt: Rest*10, ganzen Teil abtrennen
3. Schritt: Rest*10, ganzen Teil abtrennen
das reicht, zu mehr taugen 8 Bit nicht.
7. Was braucht man zum Rechnen?
Nun man kann das Ganze mit nem Integer, also einer 16 Bit Zahl rechnen.
Die niederwertigen Bits 0..7 stellen unseren gebrochenen Teil dar und
die höherwertigen Bits den ganzen Teil. Geht auch bequem mit 2 Bytes und
Beachten des Carry zu rechnen.
8. Wie multipliziert man mit 10, wenn man keinen Befehl dazu hat?
Zahl* 10 geht auch als ((Zahl << 2) + Zahl) << 1), also 2 Shifts und
eine Addition.
So. Den konkreten Quellcode schreibt sich unser Manuel nun selbst,
nachdem er das hier verstanden hat.
W.S.
W.S. schrieb:> Karl Heinz Buchegger schrieb:>> Mach dir EINE Lookup Tabelle>> Nein!! Mach dir bitte KEINE Lookup-Tabelle.
Zu diesem Zeitpunkt wusste ich noch nicht, dass seine
Umrechnungsfunktion eine simple lineare Gleichung ist. Hätte ja auch
etwas Komplexeres sein können. Damit, dass er eine
Multiplikation/Division in Form einer Tabelle abbildet, damit hatte ich
nun wirklich nicht gerechnet.
Wird wohl eh etwas knapp mit dem Speicher. Was ich bisher von den
Funktionen gesehen habe würde ich auf ein ganz spezielles Board tippen
(wird in BaWü an vielen Schulen eingesetzt). Da wird in der Schule dann
RIDE genutzt das in der kostenlosen Version nur 4k Code erzeugt.
adda.a51 und lcdhilf.a51 brauchen so 600Bytes, die Tabelle knallt mit 2k
rein...
Wie wäre es denn, vom Digitalwert (Akku) so oft 51 (1V) abzuziehen, bis
das Ergebnis negativ wird. Damit ist die Vorkommastelle bekannt. Der
verbleibende Rest ist eine Zahl zwischen 0 und 50. dafür könnte man dann
zur Not eine Tabelle anlegen. Wenn man etwas krumm mit Ulsb = 5V /255
rechnet kommt man auch auf genau 51Bit pro Volt.
Die Ausgabe des Dezimalpunktes erledigt ein
mov a, #'.'
call charaus
In C könnte man das als Zweizeiler schreiben (der dann aber auch die 4k
vollmüllt)
tschuessle
Bernhard
>> 5. Erkenntnis: Wenn ich eine echt gebrochene Zahl mit 10 multipliziere,> bekomme ich vor dem Dezimalpunkt die erste Stelle und danach den Rest.> Also ich hab 0.3745 und multipliziere:> 0.345 * 10 --> 3.745> Nun kann ich den ganzen Teil abtrennen und ausgeben und rechne mit dem> Rest weiter:> 0.745 * 10 --> 7.45> Wieder ganzen Teil abtrennen und mit dem Rest weitermachen:> 0.45 * 10 --> 4.5> usw. bis ich genug Stellen habe.>> 6. ne Nachüberlegung:> Mein o.g. Faktor sei hier 5, weil ich einen ADC hab, der von 0 bis knapp> 5 Volt "geht". (genauer: 5 * 0.99606299212 --> ca. 4.98 Volt)> Ich müßte also 5 * ADCwert rechnen und dann hätte ich schon als erstes> Ergebnis meinen ganzen Teil, den ich abtrennen kann. Der Rest ist ja> wieder kleiner als 1 und damit geht die Rechnung so:> 1. Schritt: ADC*5, ganzen Teil abtrennen> 2. Schritt: Rest*10, ganzen Teil abtrennen> 3. Schritt: Rest*10, ganzen Teil abtrennen> das reicht, zu mehr taugen 8 Bit nicht.
ich habe es in gro´Zügen verstanden aber leider keine idee wie ich dies
in asabler umsetzten soll
wie ichd as trennne hinbekommen soll und alles
Tut mir leid fange gerade an mit dieser sprache und alles umzugehen
Machen wir's in Assembler:
Also, du hast beispielsweise eine Zahl wie 3.1415 und selbige so in ein
16 Bit Register (das du z.B. KarlHeinz nennst) gepackt, daß der (dazu
gedachte) Dezimalpunkt genau zwischen Bit 7 und Bit 8 steht. Dann belegt
der ganze Teil die Bits 8..15 und der gebrochene Teil die Bits 7..0.
Wenn dein uC keine 16 Bit Register hat, dann nimmst du eben 2
Achtbit-Register und benenne sie z.B. KarlHi und KarlLo. Klaro?
Wie kriegst du nun den ganzen Teil zur Ausgabe?
Bei 16 Bit:
- Lade KarlHeinz in ein anderes Register (Otto), also Otto = KarlHeinz;
- dann Otto rechtsverschieben Otto = Otto shiftrechts 8 Bit. Damit
fliegt der gebrochene teil aus Otto heraus und der Rest ist deine Stelle
0..9, aus der du nur noch ein Char machen mußt durch Addieren von 48 (=
30h = '0'), also GibAus(Otto+'0');
- dann schmeiß den ganzen Teil aus Karlheinz heraus:
KarlHeinz = KarlHeinz AND 255; (255 = FFh = 0000000011111111 binär)
Bei 2x 8 Bit ist es einfacher:
KarlHi ist bereits der ganze Teil, den du mit GibAus(KarlHi+'0') direkt
ausgeben kannst.
Anschließend schmeißt du den ganzen Teil heraus, indem du KarlHi = 0;
schreibst, also dieses Register mit 0 lädtst.
Ist doch extrem easy, oder?
W.S.
W.S. schrieb:> Machen wir's in Assembler:
Ich denke sein Hauptproblem wird sein, dass er noch keine 16 Bit
Arithmetikroutinen hat, mit denen er den ADC Wert entsprechend einer
Formel in den Anzeigewert umrechnen kann. Leider versteh ich von diesem
Assembler nichts, daher kann ich ihm da auch nicht weiterhelfen, wie man
diese Dinge da am vernünftigsten aufbaut.
PS: Nettes Namenswahl
Karl Heinz Buchegger schrieb:> keine 16 Bit Arithmetikroutinen hat
Das dürfte die meisten (Berufs-)Schüler aber auch deren Lehrer
überfordern. Daher ist die naheliegende Lösung so wie oben von mir
beschrieben. Alternativ könnte man nach der mehrfachen Subtraktion noch
versuchen die 1/10V-Schritte durch Subtraktion zu erledigen, aber das
geht im 8-Bit-Zahlenraum auch nur ungenau, wenn die Ulsb 19,53mV/Bit
entspricht.
@Manuel: arbeitest du mit dem Board hier?
http://www.ces.karlsruhe.de/bubbers/index.php/controller
Da gibt es einen Trimmer für Uref. Wenn man jetzt 4,1V (genauer 4,096V)
einstellt, dann entspricht Ulsb = 16mV/Bit. Damit lässt ich wesentlich
einfacher rechnen. Noch einfacher ist es bei 2,56V, dann ist Ulsb =
10mV/Bit und eine Spannung (bis 2,55V) entspricht genau dem Digitalwert
in 10mV-Schritten. Nachteil ist der reduzierte Eingangsspannungsbereich.
tschuessle
Bernhard
Bernhard Spitzer schrieb:> Karl Heinz Buchegger schrieb:>> keine 16 Bit Arithmetikroutinen hat> Das dürfte die meisten (Berufs-)Schüler aber auch deren Lehrer> überfordern. Daher ist die naheliegende Lösung so wie oben von mir> beschrieben.
Du verstehst mich nicht, worauf ich hinaus will.
Deine Ausgaberoutine ist ja super. Gut erklärt und auch für ihn
umsetzbar. Das Problem ist: wo kommt der Wert her, den er ausgeben will.
Zwischen dem, was er vom ADC bekommt und dem was er auf die Anzeige
zaubern will, liegt ein Zwischenschritt. Wie berechnet er sich die (zb.)
8.8 Fixpunktzahl, die er dann schön ausgeben kann?
Bernhard Spitzer schrieb:> @Manuel: arbeitest du mit dem Board hier?> http://www.ces.karlsruhe.de/bubbers/index.php/controller> Da gibt es einen Trimmer für Uref. Wenn man jetzt 4,1V (genauer 4,096V)> einstellt, dann entspricht Ulsb = 16mV/Bit. Damit lässt ich wesentlich> einfacher rechnen. Noch einfacher ist es bei 2,56V, dann ist Ulsb => 10mV/Bit und eine Spannung (bis 2,55V) entspricht genau dem Digitalwert> in 10mV-Schritten. Nachteil ist der reduzierte Eingangsspannungsbereich.>> tschuessle> Bernhard
Ja, genau mit diesem arbeiten wir.
Welcher Trimmer? Ich muss an das board noch ein spannungsteiler dran
hängen wiel ich die eingäne bei Ani0 nehme mit 5v und Masse
Bernhard Spitzer schrieb:> Wie wäre es denn, vom Digitalwert (Akku) so oft 51 (1V) abzuziehen, bis> das Ergebnis negativ wird. Damit ist die Vorkommastelle bekannt. Der> verbleibende Rest ist eine Zahl zwischen 0 und 50. dafür könnte man dann> zur Not eine Tabelle anlegen. Wenn man etwas krumm mit Ulsb = 5V /255> rechnet kommt man auch auf genau 51Bit pro Volt.> Die Ausgabe des Dezimalpunktes erledigt ein> mov a, #'.'> call charaus
oki aber wie gebe ich das alles aus. ich habe ja dann die Kommastelle
0-50Bit entpricht evtl 0.2V wie bekomm ich nun die vorkommastelle?
Wenn ich ein Signal habe mit 168 Würde es ja 3,.. geben Muss ich dann ne
verzeigung machen, die Abfraget ob der wert größer 51 ist und dann
wieder abzieht und dann ein register z.b hochzählt?
Würde bedeuten, ich habe r=3 Tablle:25Bit=0,5V
Wie füge ich dies zusammen mit einem Punkt.
Manuel schrieb:>> Die Ausgabe des Dezimalpunktes erledigt ein>> mov a, #'.'>> call charaus>> Würde bedeuten, ich habe r=3 Tablle:25Bit=0,5V>> Wie füge ich dies zusammen mit einem Punkt.
Die letzte Frage wurde bereits beantwortet, bevor Du sie gestellt hast.
Ansonsten stellst Du aus mehreren Variabeln (Speicherstellen von 7Fh
abwärts eigenen sich da gut) deinen Zahlenwert zusammen.
z.B. Vorkomma EQU 07Fh
Nachkomma_Zehntel EQU 07Eh
Nachkomma_Hundertstel EQU 07Dh
Ausgabe erfoglt dann Ziffernweise mit
mov a, Vorkomma
call charaus
mov a, #'.'
call charaus
mov a, Nachkomma_Zehntel
undsoweiterundsofort...
Nachdem Du Dir Gedanken gemacht hast, wie deine gewünschte physikalische
Größe (Du willst doch Strom messen - redest aber nur von Spannungen.
Also wie groß ist der Messwiderstand?) vom Digitalwert abhängt, kannst
Du (zuerst mal auf Papier) die Formel Phy_Größe = m * Digitalwert + b
aufstellen. Überprüfung mit 2 konkreten Digitalwerten sollte erfolgen.
Da krumme Faktoren und Überläufe in Assembler nicht gut umsetzbar sind,
rechnest Du Dir die Digitalwerte z.B. für 1A, 2A, 3A usw. aus. Dann
misst Du den Analogkanal und vergleichst auf die Schwellen. Damit ist
die Vorkommastelle klar. Wenn also 1A z.B. 51 entspricht, dann so:
1
call ain0 ; im Akku steht jetzt der Digitalwert
2
cjne a,#51,Vergleich2 ; Wenn Akku gleich 51, dann 1.00A
3
mov Vorkomma, #1
4
mov Nachkomma_Zehner, #0 ; und so weiter
5
jmp Anzeigen
6
7
Vergleich2: ; jetzt das Carry prüfen. Wenn gesetzt ist der Akku unter 51, sonst drüber
8
jc Unter51
9
Ueber51: ; 51 abziehen, dann weitere Vergleiche mit den übrigen Werten
10
11
Unter51:
12
mov Vorkomma, #0
13
;Nachkommastellen aus Wertetabellen mit indir. Adressierung auslesen
und das ganze für alle weiteren berechneten Digitalwerte. Ist zwar
nervig, aber immer das gleiche Schema.
@Karl Heinz: Eigentlich sollte der Lehrer sowas vorher mal im Unterricht
vorgestellt haben. Für ASM-Anfänger ist sowas eine recht harte Nuss.
Mehr als das obige will ich aber nicht mehr vorgeben. Erst soll er mal
eigenen Code posten. (die nächste Frage zum Thema hat er als MA ja schon
gestellt).
tschuessle
Bernhard
Karl Heinz Buchegger schrieb:> Zwischen dem, was er vom ADC bekommt und dem was er auf die Anzeige> zaubern will, liegt ein Zwischenschritt. Wie berechnet er sich die (zb.)> 8.8 Fixpunktzahl, die er dann schön ausgeben kann?
Er berechnet sie überhaupt nicht, sondern setzt den ganzen Teil auf
Null und lädt den gebrochenen Teil mit dem Ergebnis aus dem ADC. Das ist
alles.
Irgendwann verzweifle ich an euch allen!!
Also nochmal vom nochmal:
1. Wir lesen den 8 Bit großen (also 1 Byte umfassenden) ADC-Wert aus dem
ADC aus und laden ihn in ein Register oder eine Speichezelle, die ich
hier mit KarlLo bezeichne.
2. Wir nehmen irgendwoher ein zweites Register oder eine zweite
Speicherzelle, die ich hier KarlHi bezeichne. Dort schreiben wir ene
NULL hinein oder führen einen Löschbefehl aus (je nach verwendetem uC)
Also haben wir jetzt (mal pascalartig ausgedrückt):
var
KarlLo: byte;
KarlHi: byte;
Hilf : byte;
begin
KarlLo:= ADC_Resultat;
KarlHi:= 0;
Das ist der Anfang des Ganzen und der Ausgangspunkt für alles Weitere.
War das SOOO schwer?
jetzt mal ne Stegreif-Version für PIC:
MOVF KarlLo,W
MOVWF Hilf ; Hilf:= KarlLo;
BCF Carry ; Carry löschen, damit ne 0 reingeschoben wird
RLF Hilf,F ; 1x links verschieben über Carry
RLF KarlHi,F ; KarlHi:= KarlHi shl 1 und Carry ins LSB
RLF Hilf,F ; Carry sollte 0 sein, da KarlHi=0 war
RLF KarlHi,F ; dito, also alles bisher mal 4
MOVF Hilf,W
ADDWF KarlLo,F ; KarlLo:= KarlLo + Hilf;
BTFSC Carry
INCF KarlHi,F ; KarlHi:= KarlHi + Carry aud der Addition
Jetzt haben wir KarlHi.KarlLo mit 5 multipliziert.
MOVF KarlHi,W ; ganzen Teil abtrennen und ausgeben
ADDLW '0'
CALL GibZeichenAus
CLRF KarlHi
Für die nachfolgenden Schritte müssen wir mit 10 multiplizieren, also
kommt noch dazu
BCF Carry
RLF KarlLo,F
RLF KarlHi,F
und der Rest ist wie bei obigem Multiplizieren mit 5.
SO. Nochmal pascalartig das Ganze:
var
KarlHeinz: word;
begin
Karlheinz:= ADC_Resultat;
{ 1. Ziffer }
KarlHeinz:= Karlheinz * 5;
GibZeichenAus(chr(((Karlheinz shr 8) and 15) or '0'));
KarlHeinz:= KarlHeinz and 255;
GibZeichenAus('.');
{ 1. Ziffer }
KarlHeinz:= Karlheinz * 10;
GibZeichenAus(chr(((Karlheinz shr 8) and 15) or '0'));
KarlHeinz:= KarlHeinz and 255;
{ 2. Ziffer }
KarlHeinz:= Karlheinz * 10;
GibZeichenAus(chr(((Karlheinz shr 8) and 15) or '0'));
KarlHeinz:= KarlHeinz and 255;
Also Leute, ich bin ja nun längst nicht mehr der Allerjüngste und
Schnellste im Denken, aber ich sehe mit einigem Erschrecken, wie
begriffsstutzig ihr jungen Spunde so seid. Lernt doch um Himmelswillen
zuerst das logische Denken, bevor ihr euch ans Programmieren macht.
Es ist wirklich viel viel wichtiger, logisch und strategisch denken zu
können, als irgendeine Programmiersprache gelernt oder den Umgang mit
irgendeiner IDE/Toolchain geübt zu haben. Die obigen Vorschläge, an der
Refrenz zu drehen, eine Tabelle zu basteln oder sonstwie das eigentliche
Problem nicht zu lösen sondern zu umschleichen, sind allesamt OBERMURKS,
der nur daraus rührt, daß die Schreiber eben noch nicht zu denken
gelernt haben. Deshalb empfehle ich hier mal ein steinaltes Buch, das
sich zwar auf den ebenso steinalten Z80 bezieht, aber an Aktualität
nichts eingebüßt hat:
Lampe, B./Jorke, G./Wengel, H., Algorithmen der - Wiley Online Library
(http://www.hood.de/angebot/45547775/lampe-jorke-wengel-algorithmen-der-mikrorechentechnik.htm)
Lest das und lernt damit, Algorithmen zu verstehen und zu begreifen, wie
man Probleme angeht und löst. Daß im Buch als Hardware der alte Z80
herangezogen wurde, ist gut, denn das verhindert, daß Unbedarfte das
Buch lediglich als ein Kochbuch für Copy&Paste ansehen. Stattdessen
sieht man sich genötigt, den Sinn zu begreifen um die Algorithmen für
heutige uC zu formulieren.
W.S.
W.S. schrieb:> Karl Heinz Buchegger schrieb:>> Zwischen dem, was er vom ADC bekommt und dem was er auf die Anzeige>> zaubern will, liegt ein Zwischenschritt. Wie berechnet er sich die (zb.)>> 8.8 Fixpunktzahl, die er dann schön ausgeben kann?>> Er berechnet sie überhaupt nicht, sondern setzt den ganzen Teil auf> Null und lädt den gebrochenen Teil mit dem Ergebnis aus dem ADC. Das ist> alles.
Echt?
Und das berechnet dann den Strom durch den Shunt, wenn er die Spannung
über dem Shunt misst?
Karl Heinz Buchegger schrieb:> Echt?
Es ist Sonntag, mieses Nieselwetter und ich war jetzt ne Weile im Garten
um den elenden Kirschbaum zu verschneiden - ergo, hab momentan keinen
Gefallen an solchen Bemerkungen. Also, du Moritator, wenn schon, dann
trag was Nützliches zum Thema bei.
W.S.
> Irgendwann verzweifle ich an euch allen!!> Lernt doch um Himmelswillen zuerst das logische Denken,> bevor ihr euch ans Programmieren macht.
Vielleicht doch noch mal das Eröffnungsposting lesen, wo die Reise
überhaupt hingehen soll. Die 5V sind nur Zwischenziel. Die endgültige
Reise geht zu einer Strommessung und da bleibt es nicht aus, dass der
Widerstand des Shunts in die Rechnung eingeht.
Oh, du KarlHeinz,
lies doch mal:
Manuel schrieb:> Vorgabe ist ein Messbereich von 0-5V also hab die looUp..
Darum drehte sich das Ganze: 0 bis 5 Volt. Über den Shunt und etwaige
weitere Bauteile vor dem ADC hat er sich nicht ausgelassen. Ist ja auch
seine Schulaufgabe.
Mir ist schon klar, daß man für andere Meßbereiche auch andere
Skalierungsfaktoren benötigt. Ich zitiere mich ausnahmsweise mal selber:
W.S. schrieb:> Wir sehen also, daß> die Wertigkeiten aller Bits von der Eingangsbeschaltung und der Referenz> abhängt.
Oder formal Resultat:= HardwareabhängigerFaktor * ADCErgebnis;
Jetzt haben wir das Umwandeln eines ADC-Ergebnisses in einen Text 0.00
bis 4.99 exemplarisch geübt und zwar ohne irgendwelche Tabellen, die
bei einem linearen Problem grundsätzlich überflüssig sind. Wer das
kapiert hat, sollte ab jetzt kein Problem haben, diesen Algorithmus auf
andere Bereiche umzusetzen. Allerdings ist dazu wenigstens einmal eine
Multiplikation nötig.
W.S. schrieb:> Oh, du KarlHeinz,>> lies doch mal:>> Manuel schrieb:>> Vorgabe ist ein Messbereich von 0-5V also hab die looUp..>> ich hab vollgendes Problem Ich muss für meine schule> ein Strommessgerät entwickeln.
!
> Darum drehte sich das Ganze: 0 bis 5 Volt.
Er misst im 5V Bereich seines ADC!
Das heißt aber nicht, dass auf seiner Anzeige zum Schluss ein Wert
zwischen 0 und 5 stehen soll. Schau dir die Tabellen an, die er bisher
benutzt hat.
Ich sag ja nicht, dass deine Ausgabefunktion schlecht ist. Überhaupt
nicht. Aber sie ist nur Teil seiner Lösung. Und ob er in der Lage ist,
die notwendigen Änderungen da mit einzuarbeiten .... wage ich zu
bezweifeln.