Guten Morgen, wir möchten uns erst einmal vorstellen. Wir sind Schüler auf dem Technischen Gymnasium in Sigmaringen und müssen ein Projekt in Informationstechnik durchführen, dessen Teil die Programmierung eines 80c51 Microcontrollers ist. Die Programmierung soll in Assambler erfolgen. Sachziel: Realisierung eines Programms zur Messung einer anliegenden Spannung und Ausgabe auf einem LCD Display. Die Spannung soll von 0-5V in 0,1V Schritten angezeigt werden. Unsere Problematik ist, dass wir die Kombination des LCD Displays mit dem AD/DA-Wandler nicht realisiert bekommen. Im Unterricht wurden solche Problemstellungen nicht hinreichend behandelt, somit haben wir keine Ahnung, wie das gehen soll! Wir bitten um möglichst schnelle Hilfe, da es sich nur um eine Teilaufgabe handelt und der Abgabetermin immer näher rückt. Anbei haben wir die uns zur Verfügung gestellten Mittel hochgeladen. Es handelt sich dabei um Datensätze für den ADDA-Wanndler und das LCD-Display. Viele Grüße David und Renè
"Unsere Problematik ist, dass wir die Kombination des LCD Displays mit dem AD/DA-Wandler nicht realisiert bekommen." Hm... also Ihr habt Probleme vom Anfang bis zum Ende? Wo genau liegt denn das Problem? Wisst Ihr nicht wie Ihr die Analogwerte einlesen sollt, wisst Ihr nicht wie man Text auf dem LCD ausgeben kann oder was? Fehlen die Grundlagen um aus dem Ergebnis der A/D-Wandlung einen Spannungswert zu errechnen - oder wollt Ihr einfach nur die Hausaufgaben gemacht bekommen?
Ehrlichgesagt, ja, wir haben Probleme vom Anfang bis zum Ende. Ein paar Grundlagen sind schon vorhanden, aber wir haben in der Schule noch nie etwas mit AD-Wandlern oder LCD Display gemacht. Wir haben nur so einfache Dinge, wie Zähler, Ausgabe auf Segment-Anzeigen oder Lauflichter programmiert.. Wir programmieren Assambler erst seit diesem Jahr und sind noch nicht wirklich fit, desshalb bitten wir hier um Hilfe.
Sorry, ich kann kein ASM, aber theoretisch würde ich es so angehen. Zuerst würde ich mal einen Timer akivieren und den halt durchlaufen lassen. Wenn der mir einen Interrupt erzeugt,setzt den Timer zurück und startet die AD-Wandlung und warte bis diese abgeschlossen ist(da gibts ein Flag das du nur abfragen musst ob es gesetzt ist). Wenn die Wandlung abgeschlossen ist, dann sollen die Daten ans LCD ausgegeben werden. Es ist vl sinnvoll, wenn du in der Interrut-routine ein Flag setzt, welches du dann im Main abfragst und danach die AD-Wandlung und die Ausgabe aufs LCD machst(danach das Flag zurücksetzen) Du musst halt nur den Timer-Überlauf so gross machen, dass die AD-Wandlung und die Ausgabe ans LCD fertig sind ehe der Interrupt kommt.(Üblich sind glaube ich 2 mal pro Sekunde messen).
na denn schaut doch mal im Codebereich nach 3fach Strom Spannungsanzeige von mir. Da könnt Ihe jede Menge davon nutzen. Und Schaltpläne waren auch bei. Nix fertiges für Euch aber genug um was draus zu machen. So denn los gehts
"Das Mikrocontroller Kochbuch" von Andreas Roth... Dann gliedert Ihr Eure Aufgabe in Teilaufgaben auf und schon ist das Problem gelöst.
Vielleicht könnte dir folgende Seite etwas helfen bei den Grundlagen zum AD-Wandler. http://www.humerboard.at/navi/f_anwendung.htm
Ich verstehe nicht, wieso ihr da nicht weiterkommt. Im IT.zip sind ein paar Word-Dateien, die die Funktionsweise und Ansteuerung des AD-Wandlers und des LCDs sogar mit Beispielen beschreiben. Dort steht sogar, dass fuer die I2C-Hardware Bibliotheken zur Verfuegung stehen und keine Detailwissen um das Hardwareprotokoll zwischen den Chips noetig ist. Mit dem Beispiel code kann man doch schon die Werte vom AD-Wandler abholen und mit dem LCD-Beispiel Text ausgeben. Ihr muesst also nur noch in einer Schleife die AD-Wandler Werte abholen, in Text umwandeln und ans LCD schicken.
Wie Daz schon sagte, es ist doch sowieso alles dabei. Vielleicht solltet Ihr einfach mal genauer lesen, z.B. das hier "ausAnalog-Digital-Umsetzung8252.doc": "Weder die Funktion des Busses noch die Funktion des ICs muss man verstehen, da fertige Unterprogramme zur Verfügung stehen."
moin moin, das programmieren fängt beim verstehen an. Und da hat man euch wohl nicht viel beigebracht. Oder doch? Die Aufgabe ist doch ganz einfach: 0. Einrichten das AD-Wandlers und der Anzeige 1. Wert von AD-Wandler holen 2. Wert zur Anzeige bringen 3. weiter bei 1. Das ist das das ganze Programm. Nun schreibt mal zu den einzelnen Punkten was noch zu beachten und zu tun ist dazu. Nur mit Worten, noch ganz ohne eine Programmiersprache. Wenn diese Beschreibung fertig ist und alle Möglichkeiten erfasst, habt Ihr einen PAP (ProgrammAblaufPlan) und der wird dann in eine Programmiersprache umgesetzt. Mit Gruß Pieter
Vielen Dank schonmal für die zahlreichen Antworten. Wir wissen, dass uns eigentlich schon fast alles gegeben ist, allerdings liegt unser Problem darin die Informationen zu verstehen und umzusetzen. Wo im AD-Wandler Beispielprogramm steht der Wert, den wir an das LCD bringen müssen? an Pieter: Was genau verstehst du unter "0. Einrichten das AD-Wandlers und der Anzeige"? Wie würdest du den PAP aufteilen? Gruß David und Rene
Also hab das jetzt gefunden. Der Digitale Wert wird da ja an P2 (Auf unserer Platine sind das LEDs) ausgegeben. Ist das richtig, dass wir jetzt eigentlich nur den Wert nicht an P2, sondern auf das LCD Display übergeben müssen? Und diesen Wert dann noch dem entsprechenden Text (0,1V; 0,2V; ....) zuweisen? Gruß David Und Rene
Naja "zuweisen" wäre wohl auch eine Möglichkeit, aber ich würde es versuchen zu rechnen. Wenn der AD-Wandler 8Bit hat dann ist ein AD-Wert von 255 ($FF) 5.0V, ein Wert von 0 ($00) 0.0V. Der Rest liegt irgendwo dazwischen.
moin moin, als Anzeige soll per LCD erfolgen, diese muss zuerst initialisiert werden. Dazu sollte es in der beiliegenden Software so etwas wie InitLCD geben. Auch beim ADU kenn eventuell etwas einzustellen sein. Der PAP um fragen erweitert: 0.1 InitLCD 0.2 InitADU 1. Wert vom ADU holen -muss und wie wird der ADU gestartet? -wie feststellen ob ADU fertig (Signal oder Zeit)? -wie Wert auslesen? -wo Wert speichen wenn notwendig? 2. Wert zur Anzeige bringen -muss eine Umwandlung erfolgen, wenn ja wie (z. B. binär -> dezimal? ) 3. Sringe zu 1. Diese Fragen mit den beiliegenden DOCs beantworten und aus den Fragen Anmerkungen mit dem wie realisieren machen. Immer schön stückjenweisen. Mit Gruß Pieter
Wenn ich auch noch meinen Senf dazugeben darf: Ich bin ein Verfechter der 'Schritt-Für-Schritt' Methode. Wenn du weder vom ADC noch vom LCD Ahnung hast, dann würde ich die beiden Bereiche einfach mal trennen. Anstatt sich um die komplette Aufgabenstellung zu sorgen, definiert euch mal 2 eigene Ziele: * Wie kann man am LCD was ausgeben * Wie kann ich vom ADC was einlesen So und jetzt kümmert ihr euch momentatn nur um das LCD. Euer Ziel ist es, dass am LCD ein Text eurer Wahl ('Hallo Welt' ist ein beliebter Text) einfach nur angezeigt wird. Sonst nichts. Wichtig: nicht einfach nur sagen das sei simpel denn da existiert ja vielleicht in Beispiel. Tut es. Nehmt die konkrete Hardware, schreibt das Program, verbindet es mit der vorgefertigten Bibliothek die die eigentliche Ausgabe macht und lasst es laufen! Ist die Ausgabe soweit erledigt, dann legt ihr die einfach mal beiseite und kümmert euch um den ADC. Sieviel ich gelesen habe, gibt es da ein Beispiel, dass den ADC Wert auf LED's ausgibt. Super. Gebt das mal ein und lasst es laufen. Wieder: nur das Vorgefertigte übernehmen, was auch im Endprogram enthalten sein wird: also die eigentliche Einleseroutine. Das drumherum selber schreiben, auch wenn es bereits ein fix&fertiges Beispiel dazu gibt. So. Jetzt seid ihr hoffentlich in dem Zustand, dass ihr versteht wie das LCD angesteuert werden muss und wie man vom ADC Werte bekommt. Als nächstes verbindet man die beiden Einzelteile. Also wird ein neues Programm geschrieben, in dem beide Welten zusammengeführt werden. Wieder: Macht euch die Dinge so einfach wie möglich! Vergesst erst mal, dass ihr Volt anzeigen wollt. Das erste Ziel sollte sein, einfach nur den Zahlenwert vom ADC, und zwar so wie ihn der ADC liefert auf dem LCD anzuzeigen. Nicht mehr! Ihr werdet dabei zum Beispiel feststellen, dass ihr den Zahlenwert in eine Zeichenkette verwandeln müsst. Das Erkennen dass so eine Funktion notwendig ist und deren Implementierung haben schon so manchen Neuling in den Wahnsinn getrieben. Der nächste Schritt wäre dann, das ganze in eine Schleife zu packen. Ob das jetzt eine tatsächliche SChleife ist, oder die Wiederholung über Interrupts realisiert werden, ist fürs erste erst mal nebensächlich. Wichtig ist nur, dass wenn sich die Eingangsspannung am ADC ändert, sich auch der angezeigte Zahlenwert am LCD ändert. Erst dann, wenn das alles läuft, wird der Zahlenwert vom ADC in eine Spannung umgerechnet Der nächste Schritt .... Uuuups es gibt keinen nächsten Schritt mehr. Die Aufgabenstellung wurde gelöst. Also: Nicht alles auf einmal machen. In kleinen Schritten arbeiten Wenn man von etwas keine Ahnung hat, dann ein eigenes Testprogramm dafür aufsetzen, indem man nur diesen Teilaspekt abklärt. In kleinen Schritten arbeiten Nicht davor zurückschrecken, auch mal ein Beispiel abzutippen anstatt es einfach nur zu assemblieren. Beim Aptippen fallen einem hunderte Dinge auf, die man sonst nie gesehen hätte In kleinen Schritten arbeiten Vorgegebene Beispiele analysieren, wie sie arbeiten, damit rumspielen und auch mal verändern Hab ich schon gesagt? - In kleinen Schritten arbeiten
Ihr wart uns eine große Hilfe. Hab das jetzt, wie Karl Heinz geschrieben hat, in kleinen Schritten gemacht. Erstmal mit dem LCD bisschen rumprobiert, dann mit dem Wandler. Jetzt bin ich mittlerweile so weit, dass ich das, was vom Wandler kommt auf dem Display ausgeben kann. Nur die Spannung stimmt noch nicht ganz, aber das ist jetzt kein großes Problem mehr. Ich hab grad mehr das Problem, dass das Programm (RIDE IDE), das wir von der Schule bekommen haben nur eine Shareware version ist. Dadurch ist die Größe des codes etwas beschränkt und ich schaffe es nicht darunter zu bleiben. Aber vielleicht kann man da einfach die Dinge, die nicht aus der Datei vom Wandler und Display benötigt werden, löschen. Sollte reichen. Vielen Dank nochmal. Gruß Dave und Ray
Also angeblich liegt das doch nicht an "Ride IDE", sondern an unserem Programm. Es kommt der Fehler: Error 130: Code space overlap at adress: 0000 Was genau bedeutet dieser Fehler und wie kann ich ihn beheben? Ich denke,d ass zwei Programme auf die "adresse 0000" (?) gleichzeitig zugreifen wollen. Wie kann ich das verhindern? Gruß
CSEG weiter nach hinten verschieben? Ansonsten dürften Interrupt-Einsprung-Adressen überschrieben werden.
Leider sagen mir CSEG und Interrupt-Einsprung-Adressen nicht viel. Könntest du das bitte auch für Schüler übersetzen? ^^
Wenn Du keine Start-Adresse in Deinem Quellcode definierst, wird Dein Programm ab 0000H geflasht. Da in diesem niedrigen Bereich (keine Ahnung bei 8051) auch die Interrupteinsprungadressen liegen, wird bei Auslösen eines Interrupts wild in das Programm gesprungen und unkontrolliertes Verhalten ist garantiert. Du solltest testweise vor dem Hauptprogramm mal .ORG 0x0100 einbauen. Bei AVR könnte es z.B. so aussehen: .CSEG .ORG 0x0000 rjmp main .ORG 0x0001 rjmp int0_handler .ORG 0x0005 rjmp timer1_handler .ORG 0x0006 rjmp timer0_handler .ORG 0x0020 main: bei 0x0000 wird nur der Sprung nach main veranlasst. Anschließend werden die Ziele für 3 Interrupts definiert und dann beginnt main ab 0x0020. Dürfte beim 8051er sehr ähnlich sein. Probier zur Sicherheit 0x0100.
Hi, wir sind inzwischen so weit, dass wir nur noch den Wert vom Potentiometer (0-255) auf 0,1 - 5,0V umrechnen müssen. Das stellte sich allerdings als riesen Problem raus. Zuerst versuchten wir die Stelle vor dem Komma und die danach seperat anzuzeigen. Das haben wir dann aber nach ner Weile aufgegeben. Dann kam uns die Idee den Wert vom Wandler einfach durch 5,1 zu dividieren. 255/5,1 = 50 Zustände (0,1-5,0V) Wie dividiert man durch 5,1 oder auch nur durch 5 in Assambler? Durch 2 ist ja kein Problem.. Einfach mit RR die Bits nach rechts durchschieben. Oder fällt euch noch eine ganz andere Möglichkeit ein?# Anbei liegt unser Hauptprogramm. Hoffe ihr kommt damit klar. Gruß
Na, dann sucht mal nach div, das kann der 8x51.
Hallo! Hier mal ne Seite, die für Anfänger recht interessant sein kann: http://www.erikbuchmann.de/ Und der dort vorgestellte Code-Generator für 8051er (z.B. LCD-Treiber) http://wwwiti.cs.uni-magdeburg.de/~buchmann/privat/generator.htm Das ZIP-File, was du beigestellt hast, is eh sehr hilfreich. AD-DA Wandler sollte ja gar kein Problem sein und LCD auch nicht so wirklich. Es hilft oft viel, einfach nach den Beizeichungne der Bauteile + 8051 zu googlen. Gib eh recht viel Code dafür. mfg Weichinger Klaus
Divisionen kann man auch Subtraktion und Schleifen erzeugen...
Jungs, nicht durch 5,x Dividieren !!! Subtrahiert einfache ganze Volts !!!! Bei 8 Bit und 5 Volt Vref habt ihr 20mV pro Step. Wieviele Steps braucht man für 1 Volt ???? Genau , die zieht Ihr vom Wandlerwert ab und zählt die Anzahl der ganzen Volts mit. Dann denn Rest aus ner Tabelle lesen. zB Rest ist 3h also 0,06V. oder Rest ist 30h macht na....0,96Volt. Damit könnt Ihr die Ergebnisse wuderbar runden und müßt Euch nicht mit der Mittelwertbildung rumschlagen..... so mache ich das jedenfalls. Wie gesagt Codesammlung...3fach Anzeige Und ... alles klar ???
moin moin, ein 8Bit-ADU hat doch 256 Zustände. Da gibt es noch einen Denkfehler. Die Umrechnung ist also so: Uref / 256 * Wert_ADU. Da Uref in diesem Falle 5V ist also so : 5/256*Uref. Durch einfaches Umformen der Gleichung erhält man: 5*Wert_ADU / 256 = (Wert_ADU+Wert_ADU+Wert_ADU+Wert_ADU+Wert_ADU)/256 Da Wert_ADU ein 2Byt-Wert ist, ist die Division /256 das höherwertige Byt. Ist letztendlich nur der Ladebefehl. Bleibt als Aufgabe nur die 2Byt Addition in Assembler. Mit Gruß Pieter
Hallo Pieter....the Error is my !! wie Recht Du doch hast... natürlich 256 Zustände.... wären die Jungs aber auch drauf gekommen oder nicht ???? Denken schadet doch nicht.... ÜBRIGENS.... ist ne Mail für Dich da... PS.: Der ADU Wert ist bei 8 Bit ein EIN Byte WERT !!!! Oder ist Byt = Bit ??? Machs nicht so kompliziert. Das ist was für uns ...... Die Jung lernen noch. Der Unterschied macht aber nur 100uV aus... Ich denke für nen Schulprojekt mehr als ausreichen.... mit Fehler !!!
256 Zustände sind doch gerade 0-255. also bei 5V -> 255. Dann muss es doch heißen 5*Wert_ADU / 255, oder nicht?
ich habs geahnt........und nichts gesagt !!!! :- ))
NACHTRAG.... Jungs wie ich schrieb, Schulprojekt !!!! Wir reden von 100 uV !!!!!!!!! Laßt es sein !
Wenn man 256 benutzt, muß man mit 16Bit rechnen, wenn man 255 benutzt, braucht man nur 8...
deswegen schrieb ich "Bei 8 Bit und 5 Volt Vref habt ihr 20mV pro Step." also ist bei 0FFh Feierabend. Nix 16 Bit. Allerhöchstenfalls 8 Bit Plus Signum !!! jetzt geh ins Bett... Stephan
moin moin, der ADU liefert natürlich 1 Byt. Um das Ergebnis der Multiplikation mit 5 zu speichern braucht man 2 Byt. Nun mein Schnellschuss: Division durch 256 bringt das Ergebnis als gebrochene Zahl. Beispiel: 2,34V -> ADU liefert 120 120*5 = 600 -> 258H, die 2 ist 2, V 600 div 256 -> 2 600 mod 256 -> 88 (Divisionsrest) 88*100 -> 8800 -> 2260H 8800 div 256 -> 22H = 34D In Assembler ist das dann so: mov a, Wert_ADU ;120 mov b,#5 mul ab ;b=2H , a=58H xch a, b ;das ist div 256! add a, #'0' ;umwandlung in Ziffer call ausgabe_char ;2 ausgeben mov a, #'.' call ausgabe_char ;. ausgeben ;b hat noch den Wert 58H! mov a, #100 mul ab ;a=60H , b=22H mov a,b call ausgabe_dezimal ; 22H -> 34 So sollte die Umrechnung und Ausgabe funktionieren. @David und Renè So ein ähnliches Prog schreibe ich zur Zeit auch, nur auf 3 Rechner verteilt.Labornetzteil, am PC wird Spannung und Strom eingestellt, der sendet das per COM an einen 8051, der macht die Anzeige und Umsetzung auf SPI an einen potentialgetrennten 8051 und der steuert AD und DA Wandler. @Stephan Hatte auf arbeit heute keine Zeit, sonst hätte ich das gif gemehlt. Mit Gruß Pieter
@Pieter, Netzteil...pc gesteuert .... geht standalone ??? Will meins umbauen, deswegen 3fach Anzeige..... Interessant..... Code...beeindruckend.......aber für Schüler ??? Deswegen mein 1 Voltabziehschleifenvorschlag... GEILES WORT !!! ist für die Jungs einfacher zu verstehen.... Kein 16 Bit Wert, keine MUL....völlig EASY. Also bis denne und guck in Deine Post, da wartet was mit signierten 12 Bit .
Wir sind dann gestern Mittag komplett fertig geworden. Ich habe den Vorschlag von Pieter benutzt für die Umrechnung. Ist mir echt ein Rätsel, wie man auf so eine Rechnung kommt. Vielen Dank nochmal.. David und Rene
jaja sowas kann Pieter und noch bessere Sachen, da muß auch ich manchmal überlegen... :-)
> call ausgabe_dezimal ; 22H -> 34 > > So sollte die Umrechnung und Ausgabe funktionieren. Stellt aber sicher, dass bei einem Wert von sagen wir mal 2, die führende 0 auch wirklich mit ausgegeben wird. Ansonsten wird euch ein Wert von 3.09 als 3.9 ausgegeben und das ist ganz was anderes.
moin moin,
>> Ist mir echt ein Rätsel, wie man auf so eine Rechnung kommt.
Bin schreib-faul ;-))
Mit Gruß
Pieter
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.