Hallo ich habe folgendes Problem: ich benutzte den ADC des PIC16F887. Dieser ADC hat eine Auflösung von 10 bit und speichert diese 10bit im Register ADRESH und ADRESL. Nun möchte mit diesen 10bit rechnen. Nur wie mache ich das ? Ich habe doch nur 8 bit breite Register. Angenommen es kommen aus dem ADC der Wert d'614' (b'1001100110') Dieser wert wird in ADRESH und ADRESL abgelegt. bit 0 - 7 befindet sich in ADRESL und bit 8-9 befinden sich in ADRESH. Nun hab ich ja im Register ADRESL den Decimalwert 102 und im Register ADRESH den decimalwert 2 2+102= 104 Das geht logischer weise nicht! Kann man evt 2 register zusammenfügen sodass ich ein 16 bit breites Register habe? dann wäre das rechnen kein problem mehr. Oder wie verwertet man 10 bit werte mit 8 bit breiten registern?
Wenn ein 8-Bit Register überläuft dann hat der entstehende Übertrag einen Wert von 256. In ADRESH steht die Anzahl der "Überläufe" von ADRESL...also: ADCwert = (ADRESH * 256) + ADRESL
:
Bearbeitet durch User
Chris B. schrieb: > Wenn ein 8-Bit Register überläuft dann hat der entstehende Übertrag > einen Wert von 256. In ADRESH steht die Anzahl der "Überläufe" von > ADRESL...also: > ADCwert = (ADRESH * 256) + ADRESL Okay das hab ich verstanden. Aber wenn ich die werte aus ADRESH und ADRESL in ein anderes Register schiebe. Zum Beispiel in 0x20 und 0x21 funktioniert das genauso?
Welchen Compiler nimmst du denn? Bei vielen kann man dann einfach einer 16bit variable den wert "ADRES" zuweisen ( ohne H oder L am Ende) Der Compiler macht das dann richtig
Gerald G. schrieb: > Welchen Compiler nimmst du denn? Naja MPLAB (oder was ist gemeint?) > Bei vielen kann man dann einfach einer 16bit variable den wert "ADRES" > zuweisen ( ohne H oder L am Ende) > Der Compiler macht das dann richtig Wie soll ich das verstehen? Besteht das Register aus aus 2 Registern?
Ingo schrieb: > Ich tippe auf asm, in C stellt sich solch eine Frage fast nicht Ne, ich nutze das Programm MPLAB und schreibe in Assembler.
Ich möchte gerne den wert 614 aus dem ADC mit 0,4883 multiplizieren. Die 614 befinden sich in ADRESH und ADRESL. Kann mir jemand da ein beispiel geben?
Anton B. schrieb: > Chris B. schrieb: > > Okay das hab ich verstanden. Aber wenn ich die werte aus ADRESH und > ADRESL in ein anderes Register schiebe. Zum Beispiel in 0x20 und 0x21 > funktioniert das genauso? Das obige Beispiel macht nur in einer Hochsprache Sinn. Um den 8 + 2 Bit ADC-Wert in Assembler weiterzuverarbeiten und z.B. eine Spannung auf einem LCD anzuzeigen, bedarf es noch einiges an Aufwand (Umwandlung in eine (gepackte) BCD-Zahl und dann weiter in einen String und und...)
>Das obige Beispiel macht nur in >einer Hochsprache Sinn.
c-hater fass!!!
Ingo schrieb: >>Das obige Beispiel macht nur in >einer Hochsprache Sinn. > c-hater fass!!! Die heutigen Assembler sind ja auch schon so neumodisches Klicki-Bunti-Zeugs. Wenn schon, dann gleich ordentlich: Handassemblierung auf toten Holz mit Graphitstift und Debugging mit Naturkautschuk. :-D
wir sollten die Dinger wieder abschaffen, Früher war eh alles bisser... Wenn ich so manche Kollegen sehe, kurz vor der Rente, keinen Durchblick mehr was stand der Technik ist, aber große Sprüche klopfen. Aber Hand am Ohr... Hört doch bitte mit diesem steinzeitmäßigem Verhalten auf! Heut zu Tage verfügt jeder PC, der nicht älter als 10 Jahre ist, um genug rechenpower um alle Tools zu stemmen...
Chris B. schrieb: > Anton B. schrieb: >> Chris B. schrieb: >> >> Okay das hab ich verstanden. Aber wenn ich die werte aus ADRESH und >> ADRESL in ein anderes Register schiebe. Zum Beispiel in 0x20 und 0x21 >> funktioniert das genauso? > > Das obige Beispiel macht nur in einer Hochsprache Sinn. > > Um den 8 + 2 Bit ADC-Wert in Assembler weiterzuverarbeiten und z.B. eine > Spannung auf einem LCD anzuzeigen, bedarf es noch einiges an Aufwand > (Umwandlung in eine (gepackte) BCD-Zahl und dann weiter in einen String > und und...) Alles klar. Das ist mir für mein erstes Projekt zu anstrengend. Da ich eh ein Temperatursensor benutze, der 10mv/k seine Ausgangsspannung ändert reicht auch eine Auflösung von 8 Bit. Muss ich ja nur umstellen.
Anton B. schrieb: > Chris B. schrieb: >> Anton B. schrieb: >>> Chris B. schrieb: >>> >>> Okay das hab ich verstanden. Aber wenn ich die werte aus ADRESH und >>> ADRESL in ein anderes Register schiebe. Zum Beispiel in 0x20 und 0x21 >>> funktioniert das genauso? >> >> Das obige Beispiel macht nur in einer Hochsprache Sinn. >> >> Um den 8 + 2 Bit ADC-Wert in Assembler weiterzuverarbeiten und z.B. eine >> Spannung auf einem LCD anzuzeigen, bedarf es noch einiges an Aufwand >> (Umwandlung in eine (gepackte) BCD-Zahl und dann weiter in einen String >> und und...) > > Alles klar. Das ist mir für mein erstes Projekt zu anstrengend. Da ich > eh ein Temperatursensor benutze, der 10mv/k seine Ausgangsspannung > ändert reicht auch eine Auflösung von 8 Bit. Muss ich ja nur umstellen. Hallo nochmal, Ich suche schon seit tagen nach einer Lösung wie ich den ADC sagen kann das er mir nur 8 bit rausgeben soll statt 10 bit. Habt ihr eine lösung?
Anton B. schrieb: > Ich suche schon seit tagen nach einer Lösung dann solltest du einfach mal ins Datenblatt schauen...
Justus Skorps schrieb: > Anton B. schrieb: >> Ich suche schon seit tagen nach einer Lösung > > dann solltest du einfach mal ins Datenblatt schauen... Das hab ich schon 3 mal durchgelesen... steht nichts drin
Anton B. schrieb: > Ich suche schon seit tagen nach einer Lösung wie ich den ADC sagen kann > das er mir nur 8 bit rausgeben soll statt 10 bit. Kleine Hilfe: er erzeugt nicht wirklich nur 8 Bit. Die Frage ist eher, wo die Bits in den Registern stehen und welchen Teil Du bei der Weiterverarbeitung ignorierst. Gruß Dietrich
Dietrich L. schrieb: > Anton B. schrieb: >> Ich suche schon seit tagen nach einer Lösung wie ich den ADC sagen kann >> das er mir nur 8 bit rausgeben soll statt 10 bit. > > Kleine Hilfe: er erzeugt nicht wirklich nur 8 Bit. Die Frage ist eher, > wo die Bits in den Registern stehen und welchen Teil Du bei der > Weiterverarbeitung ignorierst. > > Gruß Dietrich achso..... Jetzt machts klick! Danke ;)
Anton B. schrieb: > Ne, ich nutze das Programm MPLAB und schreibe in Assembler. Dann solltest du dringend lernen, wie man in Assembler breitere Datentypen realisiert. Speichern ist einfach, da nimmt man für 16Bit einfach zwei Bytes. Aber schon bei so simplen Sachen wie dem Addieren oder Subtrahieren wird's komplizierter, da muß man Übertrage zwischen den Bytes mitnehmen. Wenn du keinen Bock darauf hast, das zu lernen, nimm eine Hochsprache. Also alles, bloß nicht C. Das ist keine wirkliche Hochsprache. Du mußt fast genausoviel über den Schmutz in den Tiefen der Maschine wissen, als wenn du in Asm programmierst, hast aber längst nicht alle Freiheiten von Asm. C ist Dreck.
@c-hater Immer wieder köstlich deine Argumentation... Was empfiehlst du denn als waschechte Hochsprache für einen kleinen AVR mit 1k Flash?
Anton B. schrieb: > Ich möchte gerne den wert 614 aus dem ADC mit 0,4883 multiplizieren. Die > 614 befinden sich in ADRESH und ADRESL. > Kann mir jemand da ein beispiel geben? http://www.avr-projekte.de/rechnen.htm#Rechnen_mit_Festkomma_ Das Programmbeispiel ist zwar für AVR, trifft aber genau auf dein Problem zu.
Ingo schrieb: > Was empfiehlst du denn als waschechte Hochsprache für einen kleinen > AVR mit 1k Flash? OOASM ;-)
Ingo schrieb: > Immer wieder köstlich deine Argumentation... Was empfiehlst du denn als > waschechte Hochsprache für einen kleinen AVR mit 1k Flash? Keine. Alles unterhalb 8k (Code+konstante Daten) macht man natürlich immer in Assembler, ohne auch nur ansatzweise über eine Alternative nachzudenken. Im Bereich 16..64k wird man sinnvollerweise darüber nachdenken. Und manchmal entscheide sogar ich mich hier für C, auch wenn ich es hasse wie die Pest. Oberhalb von 64k braucht man wieder nicht mehr nachdenken, da ist Hochsprache (maximal mit Asm-Einschüben für zeitkritischen Kram) angesagt. Und dann natürlich eine richtige objektorientierte Hochsprache. Notfalls sogar C++, auch wenn ich das fast genauso hasse wie C. Da hängt viel zuviel C-Schmutz im Sprachkonzept...
Hier kann wohl keiner was! Besonders die klugsch... Sprachen-Schwafler! Eigentlich voll easy in ASM: (Leider kenne ich nur die AVR-Konventionen, beim PIC wird es aber nicht viel anders sein.) ADRESH und ADRESL in zwei Arbeitsregister kopieren, für die Multiplikation 0,4883 * 65536 = 32001 = 0x07D1 in zwei weitere Arbeitsregister laden. 16 * 16 Bit unsigned Multiplikationsroutine mit diesen Registern ausführen. (Findet man bestimmt auf intelligenteren Sites, für AVR wird man bei http://elm-chan.org/cc_e.html fündig.) Vom 4 Byte Resultat sind die 2 oberen Byte das Ergebnis. (Mit dem Verwerfen der unteren 2 Byte kürzt sich die Erweiterung um 65536 wieder raus.) Kriegt man das mit einem PIC nicht hin???
Hallo Ich habe es nach langerzeit nun hinbekommen Zahlen größer 8 bit zu multiplizieren. Nun stellt sich ein weiteres Problem ein. Da ich meine Zahl (616) gern mit 61 multiplizieren möchte, habe ich zuerst die Zahl mal 64 genommen ( 6 mal * 2) [Ergebniss=39424]. Nun muss ich diese Zahl 3 mal minus 616 nehmen um auf das richtige ergebniss [37576] zu kommen. Kennt ihr eine Lösung oder ein Link wo ich das nachschauen kann, wie ich Zahlen größer 8 bit Subtrahiere?
Anton B. schrieb: > Hallo > > > Ich habe es nach langerzeit nun hinbekommen Zahlen größer 8 bit zu > multiplizieren. Um ehrlich zu sein bezweifle ich das, wenn ich den Rest deines Postings betrachte. Was du rausgefunden hast ist, dass ein Linksverschieben um 1 Bit einer Multiplkation mit 2 entspricht und demenstprechend ein mehrmaliges Schieben einer Multiplikation mit einer entsprechenden 2-er Potenz (2, 4, 8, 16, etc.). Das ist aber von tatsächlicem Multiplizieren weit entfernt. Man kann diese Schiebe-Strategie verfolgen, durchaus. Aber wenn man tatsächlich Multiplizeren kann, dann bleibt es nicht aus, auch die einfache Aufgabe 'Addition/Subtraktion von 16 Bit Zahlen in 2 Registern' lösen zu können. Die Aufagbe ist deswegen einfach, weil die Prozessoren dafür eigene Instruktionen haben, die einen möglichen Übertrag von einer Operation in die nächste berücksichtigen können. > Kennt ihr eine Lösung oder ein Link wo ich das nachschauen kann, wie ich > Zahlen größer 8 bit Subtrahiere? Dein µC hat Instruktionen zum Addieren bzw. Subtrahieren. Die gibt es in der Version mit bzw. ohne Berücksichtigung des Carry Flags. Ein Blick in die Tabelle der vom µC unterstützen OPerationen bzw. Nachlesen wie sie funktionieren hilft da ungemein. Und ja. Das steht alles im Datenblatt des Prozessors bzw. in einem Dokument welches den 'Instruction Set' beschreibt. Gewöhn dich daran, dass du Unterlagen studieren musst, das wirst du noch oft und nach lange tun müssen. Das Carry Flag ist nichts anders als der Übertrag bzw. Unterlauf, den du auch so machst. Wenn du addierst, dann kann dein "Hardware-Addierer" (genannt Brain) das nur im Zahlenbereich 0 bis 9 tun. Willst du 2-stellige Zahlen addieren
1 | 24 |
2 | 28 |
3 | ----- |
dann rechnest du
1 | 8 plus 3 ergibt 12 |
die 2 schreibst du beim Ergebnis hin, die 1 (von den Zehnern) merkst du dir und rechnest ihn bei der restlichen Addition noch mit dazu
1 | 24 |
2 | 28 |
3 | 1 |
4 | ---- |
5 | 2 |
1 plus 2 plus 2 macht 5
1 | 24 |
2 | 28 |
3 | 1 |
4 | ---- |
5 | 52 |
Die Rolle die hier das 'die 1 merkst du dir' spielt, genau diese Rolle spielt im µC das sog. Carry Flag. UNd folgerichtig gibt es auch 2 Additionen, einmal ohne Einrechnung das Carry Flags (das hast du bei den Einern gebraucht) und einmal mit Einrechnung des Carry Flags (die Operation hast du bei den Zehnern gebraucht). Nicht anders funktioniert das, wenn du eine 16 Bit Zahl in 2 Registern addierst. Die 'kleinen Stellen' addierst du ohne Einrechnung des Carry, die 'grossen Stellen' addierst du mit der Operation, die auch das Carry Flag (welches von der vorhergehenden Operation je nachdem auf 0 oder 1 gesetzt wurde) berücksichtig. Und nicht anders funktioniert das bei der Subtraktion.
:
Bearbeitet durch User
In einem Punkt muss ich mich korrigieren: Der PIC hat anscheinend keine 2 verschiedenen Additionsbefehle http://www.sprut.de/electronic/pic/assemble/befehle.html d.h. das Carry Flag wird nicht automatisch mit eingerechnet, weil es keinen Befehl dafür gibt. Statt dessen muss man sich selbst darum kümmern. http://www.sprut.de/electronic/pic/math/math.htm
:
Bearbeitet durch User
Anton B. schrieb: > Hallo > > Kennt ihr eine Lösung oder ein Link wo ich das nachschauen kann, wie ich > Zahlen größer 8 bit Subtrahiere? Google mal nach AN617 von MICROCHIP (Fixed Point Arithmetik) Dort finden sich nicht nur eine Routine für simple 16 Bit Addition/Subtraktion sondern gleich eine ganze Bibliothek für 8x8, 8x16, 16x16, 24x16, 24x24, 32x16, 32x24 udn 32x32 Multiplikation (jeweils signed/unsigned) und das alles in die Gegenrichtung - sprich Division. (den ganzen Source gibt es auch als ZIP-File!) Man muss sich natürlich in die verwendtet Datenstruktur der Parameter einarbeiten, aber der Zeitaufwand lohnt falls man wirklich in Assembler aufwändigere Berechnungen in FP-Arithmetik machen will. btw: die Addition und Subtraktion findet sich ja zum Glück gleich auf Seite 2 oder 3..... ;-)
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.