Hallo,
ich soll eine Temperaturmessung mit einem PT100 an einem 80517 bei 12
Mhz realisieren.
Ich benutze den Internen ADC und die Umrechnung des 8bit Wertes in einen
Temperaturwert ist durch eine Sprungtabelle realisiert. Der geringste zu
erwartende Wert ist -20 C der einem ADC Wert von 0Dh entspricht.
Die AD-Wandlung soll (ungefähr) alle 2 Sekunden erfolgen. Dies
realisiere ich in dem ich mit dem Timer0 im Autoreload-Modus (mit 6
vorgeladen) zwei Variablen auf Null runterzählen lasse, so dass der
Timer 8000 mal durchlaufen wird, wodurch ich auf ungefähr 2 sekunden
komme.
Nach der Umrechnung des ADC-Wertes mache ich eine Abfrage nach der größe
des Wertes, da ich in zwei Variablen den minimal und maximal Wert
speichern will.
Leider kann ich das Programm erstmal nicht testen und würde gerne
weitere Meinungen hören, da es mein erstes größeres Programm ist.
Ich nutze µVision 4 und kann dort im Debuger auch sehen wie die
Variablen runtergezählt werden. Aber unter Peripherals kann ich nur die
Timer auswählen und kann deswegen den ADC nicht testen.
> Aber unter Peripherals kann ich nur die Timer auswählen und kann deswegen> den ADC nicht testen.
Dann hast du den falschen Controller in den Projektsettings, denn hier:
http://www.keil.com/dd/chip/2969.htm
steht, dass der ADC simuliert werden kann.
"Project -> Select Device for Target...", den passenden µC wählen, neu
compilieren/linken und gucken, ob der ADC dann im Simulator auftaucht.
Ralf
Stimmt vielen dank, jetzt kann ich auch die ADC kontrollieren und habe
einen Fehler gefunden.
Die Abfrage nach den minimal und maximal Werten funktioniert noch nicht
wie gewollt, da die negativen Zahlen als große Zahlen gedeutet werden.
Thomas Waage schrieb:> Die Abfrage nach den minimal und maximal Werten funktioniert noch nicht> wie gewollt, da die negativen Zahlen als große Zahlen gedeutet werden.
Thomas,
das kann ja nicht funktionieren, da du beim Vergleich mit maxim und
minim nur eine 'unsigned'-Auswertung machst (durch jc oder jnc).
Für eine vorzeichenbehaftete Auswertung muss noch das Overflow-Flag
berücksichtigt werde. Dazu ist aber das cjne nicht geeignet, da es nur
das Carry-Flag verändert.
Richtig funktioniert es nur bei Verwendung von subb.
Hier ein Beispielunterprogramm dazu (allerdings für 16-Bit-Zahlen):
; Integers vergleichen über Subtraktion X - Y.
; Parameter: R0 = Zeiger auf Quelle X.
; R1 = Zeiger auf Quelle Y.
; Resultat: C = Übertrag.
; OV = Überlauf für Zweierkomplement.
; F0 = Übertrag Zweierkomplement ( OV^N ).
; ACC = 0: X == Y (JZ).
; Register: B wird zerstört.
; Folgende Vergleichsmöglichkeiten bestehen:
; Unsigned: C==0 X >= Y BHS.
; C==1 X < Y BLO.
; ACC==0 X == Y BEQ.
; Signed: F0==0 X >= Y BGE.
; F0==1 X < Y BLT.
; ACC==0 X == Y BEQ.
IntCmp:
clr C
mov A,@R0
subb A,@R1
mov B,A
inc R0
inc R1
mov A,@R0
subb A,@R1
orl B,A
mov ACC.6,C ; C-Flag retten.
mov C,OV ; OV ^ N bilden.
jnb ACC.7,IntCmp1
cpl C
IntCmp1:
mov F0,C
mov C,ACC.6 ; C-Flag restaurieren.
mov A,B
dec R0
dec R1
ret
Ciao, Yagan
> Die Abfrage nach den minimal und maximal Werten funktioniert noch nicht> wie gewollt, da die negativen Zahlen als große Zahlen gedeutet werden.
Hm, kleiner Kurs in Zahleninterpretation von Computern/Controllern/etc.:
Die schnellste Methode für einen Computer/Controller, um mit Zahlen zu
rechnen, ist einerseits die Verwendung von Variablen, deren Größe nicht
über die Datenbreite des Computer/Controllers hinausgeht, wenn es nicht
sein muss, das heisst, ein 8-Bit Controller rechnet am schnellsten mit
8-Bit-Werten, ein 16-Bitter mit 16-Bit-Werten, usw. Computerprozessoren
unterstützen je nachdem Befehle, um kleinere Datenbreiten effektiv zu
verarbeiten, beispielsweise 8/16-Bit-Werte auf einem 32/64-Bitter.
Was ebenfalls hinzukommt, ist das Rechnen mit
vorzeichenlosen/-behafteten Werten. Ist eine Variable in einer
Hochsprache vorzeichenlos, kann es keinen negativen Wert geben. Ist sie
vorzeichenbehaftet, signalisiert ein gesetztes höchstwertigstes Bit eine
negative Zahl.
Das ist der Grund, warum sich die minimalen/maximalen Werte von
vorzeichenlosen/-behafteten Variablen um jeweils die Hälfte verschieben:
8 Bit:
VL: 0 bis 255 -> 00000000 ... 11111111
VB: -128 bis 127 00000000 ... 01111111 (positiver Bereich)
10000000 ... 11111111 (negativer Bereich)
16 Bit:
...
...
Da ich jetzt nicht weiss, WO und WIE du deine Werte anzeigt, heisst das
für dich, dass du für die Wertberechnung das höchstwertigste Bit für den
Wert ignorierst, aber wenn das Bit gesetzt ist, eins dazu addierst und
den negativen Wert hast.
Soweit klar? :)
Ralf
Ja hat mir schon viel geholfen, Danke.
Sobald dieser Teil des Programms funktioniert will ich das Programm um
eine LCD Ausgabe erweitern.
Aber ich werde zunächst versuchen die komplette minimal/maximal Abfrage
umzustricken auf subtraktions Befehle und das kann bei mir etwas dauern
:).
Bevor ich das Programm komplett ändere ist mir folgende Idee gekommen:
1
wandel:
2
clr C
3
mov a,adwert
4
subb a,#0dh
5
mov dptr, #tabelle
6
movc a,@a+dptr
7
mov aktuell,a
8
9
add a, #20
10
cjne a,maxim+20,wandeln2
11
jmp m2
12
wandeln2:
13
jc m2
14
subb a, #20
15
mov maxim,a
16
m2:
17
cjne a,minim+20,wandeln3
18
jmp m3
19
20
wandeln3:
21
jnc m3
22
subb a, #20
23
mov minim,a
24
m3:
25
ret
Durch das Addieren mit 20 komme ich ja aus den negativen Zahlen raus und
es müsste reichen wenn ich nur das Carry Flag abfrage. Leider
funktioniert es trotzdem nicht vorallem die minimal abfrage scheint gar
nichts zu machen.
Sieht jemand den oder die Fehler?
Thomas,
die Idee mit dem 20-Grad-Offset, damit der Temperaturwert positiv
bleibt, ist schon in Ordnung.
Nur die Schreibweise:
cjne a,maxim+20,wandeln2
cjne a,minim+20,wandeln3
ist nicht das, was du haben willst.
Es wird hier keine 20 zum Wert von maxim bzw. minim addiert, sondern
zur Adresse. Es ist besser, überall mit einem um 20 erhöhten Wert zu
arbeiten, und erst bei der Display-Ausgabe wieder 20 zu subtrahieren.
Der Vorschlag von Kelvin ist natürlich genial, hat aber den Nachteil,
dass der Temperaturwert nicht mehr in ein Byte passt.
Ciao, Yagan
Dir auch nochmal vielen dank.
Die min/max Abfrage habe ich inzwischen gelöst in dem ich jeweils eine
2. Variable angelegt habe, die den Offset enthält und anschließend mache
ich die Umwandlung.
Inzwischen arbeite ich an der LCD-Ausgabe, bzw. ich suche nach
Beispielen für die Initialisierung und Ausgabe bei einem 2x16 Display im
8 Bit Modus mit HD44780 und vorallem suche ich nach möglichkeiten die
Umrechnung der teilweise 3 Stelligen (wegen Vorzeichen) Dezimalzahl in
den Zeichensatz des Displays.
Falls da jemand was hat würde ich mich freuen.
Thomas
> ich suche nach Beispielen für die Initialisierung und Ausgabe bei einem> 2x16 Display im 8 Bit Modus mit HD44780
Also da wirst du mindestens hier im Forum zig-tausende Beiträge finden
:)
> und vorallem suche ich nach möglichkeiten die Umrechnung der teilweise 3> Stelligen (wegen Vorzeichen) Dezimalzahl in den Zeichensatz des Displays.
Basierend auf dem, was ich weiter oben über die interne Darstellung von
Zahlen (höchstwertigstes Bit = Vorzeichen) geschrieben habe:
Du nimmst eine Bitvariable, in die du das höchstwertigste Bit kopierst
und dann aus dem Wert löschst. In Abhängigkeit des Bits gibst du ein
Leer bzw. Minuszeichen aus.
Ist das Bit gesetzt, inkrementierst du den Wert um eins.
Dann teilst du ihn durch 10, das Ergebnis gibst du als Zehnerstelle aus,
den Rest als Einer. Falls du auch die Hunderter mit einbeziehen willst,
musst du halt anfangs erstmal durch 100 teilen.
Ist es das, was du gemeint hast?
Ralf