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
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ß
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ß
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
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 !!!
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
> 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.