Projekt: Luftdruckmessung
Aufgabenstellung war die Messung des Luftdrucks, wobei das vom Sensor erhaltene Signal temperaturkompensiert werden sollte. Die dazu notwendige Temperatur, wurde dabei über den I2C - Bus erhalten. Der ermittelte Wert des aktuellen Luftdrucks, sowie die Werte für den je aufgetretenen maximalen bzw. minimalen Druck, sollten über den I2C - Bus auf 3 4 - stelligen 7 - Segment LED Anzeigen dargestellt werden.
Das erste Problem, war die Temperaturkompensation, wobei man aus den erhaltenen Datenblättern das Verhalten des Drucksensors (MPX 700) bei verschiedenen Temperaturen feststellen konnte. In diesem Diagramm war der Verlauf der ausgegebenen Spannung über dem steigenden Luftdruck dargestellt. Man erkannte außerdem, dass der Drucksensor in einem Temperaturbereich von - 40°C bis +125°C einsetzbar war. Da der gesamte Temperaturbereich ausgenützt werden sollte, aber nur die Steigungen der Kennlinien von - 40°C, +25°C und 125°C gegeben waren, war es nötig sich in Hinsicht auf die Programmierung einen Korrektur - faktor zu errechnen.
Dazu war es nötig die Steigungen der drei gegebenen Kennlinien zu berechnen, wozu man die Länge der Spannungsänderung ins Verhältnis mit der Länge der Druckänderung brachte. In den Datenblättern wird sehr oft mit der Einheit PSI gerechnet, und nicht wie üblich mit der allgemein gebräuchlicheren Einheit Pascal. Am Rande sei noch die Umrechnung erwähnt, sie beträgt:
1.0 kPa = 0.145 PSI
k... Steigung der Kennlinie
Δx..Wert der Spannungsänderung in mV
Δy..Wert der Druckänderung in PSI bzw. kPa
Es ergab sich für:
+25°C: - 40°C: +125°C:
- eine Steigung von:
k = 30mV / 50 PSI = 0.5 mV/PSI k = 0,75 mV/PSI k = 0.43 mV/PSI
Weiters wurde die maximale Temperaturänderung berechnet:
ΔT = Tmax - Tmin = 125°C - ( - 40°C) = 165°C
Die maximale Änderung der Steigung betrug damit:
Δk = kmax - kmin = 0,75 - 0,43 = 0,32 mV/PSI
kmax... Steigung bei - 40°C
kmin.... Steigung bei +125°C
Bringt man nun diese beiden Werte ins Verhältnis, so erhält man den Korrekturfaktor
Will man nun z.B. die Steigung der Kennlinie bei +35°C ermitteln, so berechnet sich diese nach:
k35 = k25 - 10. kkorr = 0,5 - 10. 0,0019 = 0,481 mV/PSI
Demnach würde die Steigung der Kennlinie bei 35°C etwa 0,481 mV/PSI betragen. Diese Überlegungen ermöglichen erst die später kommende Programmierung.
Nachfolgend wurde jedoch die Peripherie rund um den Druckmeßsensor behandelt, wobei dieser nur Spannungen von 0 bis 100mV ausgeben kann, und so für eine sinnvolle Messung mit dem ADC nicht in Frage kommt. (Mögliche Messung mit ADC von 0 - 5V ) Die Schluß - folgerung war einen nichtinvertierenden Verstärker zu verwenden, der den oben erwähnten Spannungsbereich abdeckt, ihn dabei jedoch um den Faktor 50 verstärkt. Um letzteren Schritt zu gewährleisten, wurde deshalb nachfolgende Dimensionierung durchgeführt:
Verstärkerschaltung:
V = 50 -> 49. R1 = R2
R1 = 49 kΩ, R2 = 1kΩ
Da es keinen 49k Widerstand gibt, dieser Wert für das Erreichen einer Verstärkung von 50 aber in diesem Fall wichtig ist, wurde die Schaltung mit einem 47k Widerstand und einem 2k2 Widerstand in Serie dazu versehen. Ganz wichtig für die Funktion der Schaltung, waren die Filterkondensatoren gegen GND sowohl bei der + Versorgung, als auch bei der - Ver - sorgung des OPV’s, da ansonsten Störungen auftraten. Die Größe der Kondensatoren wurde mit 33n angenommen.
Ein weiteres Problem stellte die Signalverarbeitung des Sensors dar, da dieses sich aus zwei Signalen, dem vom + Output und dem vom - Output, zusammensetzte. Daher war es nötig eine Subtraktion der beiden Signale durchzuführen, um das gewünschte Sensorsignal zu er - halten. Hierfür wurde eine Subtraktionsschaltung verwendet, die mittels zweier OPV’s arbeeitete. Die Beschaltung der OPV’s erfolgte einheitlich mit 10k, da die Verstärkung von 50 sowieseo schon von der vorher besprochenen Schaltung übernommen wurde.
Subtrahierschaltung:
Die Subtrahierschaltung funktionierte wie erwartet und lieferte die gewünschte Sensorspannung im Bereich von 0 - 100mV. Direkt an diese Schaltung, wurde die Verstärkerschaltung angeschlossen, sodass man an deren Ausgang wie gefordert die 0 - 5Volt erhielt, welche für die Messung mittels ADC benötigt wurde.
Die Referenzspannung für den ADC (5,12V) erhält man über den μP - Kit, da die Ausgangs - spannung des Drucksensors aber von seiner Versorgespannung abhängt, war es nötig einen eigenen Referenzspannungsregler für 3 Volt in die Meßschaltung aufzunehmen. Der Sensor war zwar von +3V - +6V Versorgespannung zu betreiben, doch waren die dargestellten Kennlinien im Datenblatt für drei Volt ausgelegt, da dies die typische Versorgespannung war. Der Referenzspannungsregler sollte nun ausgehend von den 10 Volt Versorgespannung, die 3 Volt für die den Drucksensor liefern. Dabei wurden im wesentlichen die Daten des Referenz - spannungsreglers vom Kitt übernommen, die einzige Ausnahme stellte der Wert des Potentiometers dar, welcher von 10k auf 50k vergrößert wurde.
Schaltung des Referenzspannungsreglers:
Diese Anforderungen an die Peripherie zur Messung mit dem Drucksensor wurden gestellt, und konnten auch bewerkstelligt werden.
Weitere Anforderungen an die Pheripherie, wurden durch die benötigte Ausgabe über I2C - Bus gestellt, welche über 3 4 - stellige 7 - Segment Anzeigen erfolgen sollte. Diese Anzeigen müssen jede für sich von einem Treiberbaustein namens IDSAA1064 gesteuert werden. Daher wurden für die Messung 3 Bausteine der Serie SAA1064 benötigt und 6 Bausteine der Serie LB - 5310, welche jeweils in sich zwei BCD7 Segmente vereinigen. Das System des SAA1064
beruht darauf, dass über die SCL, SDA Pins Signale über I2C - Bus an den Baustein geliefert werden. Der Baustein selbst kann die Signale für je zwei BCD7 - Anzeigen auf einmal über die MUX - Pins steuern, wobei die zwei Transistoren, von den Signalen die von den MUX - Pins kommen durchgeschalten werden.
Da wie gesagt eine Anzeige für Minimal -, Maximal - und Normalwert vorhanden sein sollte, war es nötig dem Baustein über den Adresspin eine eigene Adresse zuzuordnen damit er nacher vom I2C - Bus auch angesprochen werden konnte. Dafür gab es mehre Möglichkeiten nämlich die Plusversorgung, sprich +5 Volt, was einer Adresse von 76h für das Lesen und 77h für das Beschreiben vom Baustein entspricht.
Analog kann für die Spannungen:
Adr(lesen) Adr(schreiben)
VEE 70h 71h
3/8 VCC 72h 73h
5/8 VCC 74h 75h
VCC 76h 77h
Für die Schaltung wurden daher die Adresspins der einzelnen Bausteine mit VCC, 3/8 VCC und VEE beschalten. Um das Verhältnis 3/8 VCC zu realisieren, war es nötig einen Spannungsteiler mit dem Widerständen 330E zu 820E aufzubauen und an ihm die 3/8 VCC Spannung abzu - nehmen. Eine eigene Beschaltung der einzelnen Segmente der BCD7 Anzeige mit Vorwiderständen, konnte entfallen. Für diese Schaltung, wurde als Test ein eigenes Programm geschrieben, welches einen bestimmten Wert auf der Anzeige erscheinen lassen sollte. Dieses Programm wurde nachher in das Hauptprogramm eingefügt.
Die Spannungsversorgung des SAA1064 betrug +5V bzw. GND, welche wieder über einen Filterkondensator vom Wert 33n ‘entstört’ wurde. Außerdem war es nötig einen externen Kondensator vom Wert 3n3 an den Pin Cext anzuschließen um eine Funktion zu erreichen.
Testprogramm zur Wertdarstellung über die 7 - Segmentanzeigen:
$include (80c552.def)
ok bit 07h
save data 31h
anz_byte data 32h
sla_adr data 34h
zd data 35h
org 8000h
JMP INIT
org 802Bh
MOV save,A
MOV a,s1sta
RR A
RR A
MOV DPTR,#TABELLE
JMP @A+DPTR
org 8100h
; * * * * * * * * * *
; * INITALISIERUNG *
; * * * * * * * * * *
INIT:
SETB ES1 ; Serielles Interrupt - Enable setzen
SETB EA ; Generelles Interrupt - Enable
SETB Ex0
SETB IT0 ; Flankentriggerung
SETB P1.6
SETB P1.7
CLR ok
MOV zd,#04h
MOV anz_byte,#06h
MOV R0,#51h
MOV @R0,#32h
INC R0
MOV @R0,#31h
INC R0
MOV @R0,#32h
INC R0
MOV @R0,#39h
MOV S1CON,#01000111b ; 75kHz, Enable
LCALL SETDISPLAY
MAIN:
JMP MAIN
; * * * * * * * * * * * * * *
; * DARSTELLUNG AUF DISPLAY *
; * * * * * * * * * * * * * *
SETDISPLAY:
MOV sla_adr,#076h ;Display - Adresse fr Schreiben
MOV R0,#04Fh
MOV @R0,#00h ;Instruction Byte
INC R0 ;50h
MOV @R0,#01000111b ;Control Register Initialisieren
INC R0
UMSETZUNG:
MOV A,@R0
CJNE A,#30h,w1
MOV @R0,#00111111b ;0
JMP wend
w1: CJNE A,#31h,w2
MOV @R0,#00110000b ;1
JMP wend
w2: CJNE A,#32h,w3
MOV @R0,#01101101b ;2
JMP wend
w3: CJNE A,#33h,w4
MOV @R0,#01111001b ;3
JMP wend
w4: CJNE A,#34h,w5
MOV @R0,#01110010b ;4
JMP wend
w5: CJNE A,#35h,w6
MOV @R0,#01011011b ;5
JMP wend
w6: CJNE A,#36h,w7
MOV @R0,#01011111b ;6
JMP wend
w7: CJNE A,#37h,w8
MOV @R0,#00110001b ;7
JMP wend
w8: CJNE A,#38h,w9
MOV @R0,#01111111b ;8
JMP wend
w9:
MOV @R0,#01111011b ;9
JMP wend
wend:
INC R0
DJNZ zd,long
MOV zd,#04h
MOV R0,#04Fh
SETB sta ; Start
WARTE:
JNB ok,WARTE
CLR ok
RET
long: LJMP UMSETZUNG
; * * * * * *
; * TABELLE *
; * * * * * *
TABELLE:
AJMP stat_00
AJMP stat_08
AJMP stat_10
AJMP stat_18
AJMP stat_20
AJMP stat_28
AJMP stat_30
AJMP stat_38
; * * * * * *
; * I2C - BUS *
; * * * * * *
stat_00:
JMP i2c_end
stat_08:
MOV S1DAT,sla_adr
CLR sta
CLR SI
CLR sto
JMP i2c_end
stat_10:
JMP i2c_end
stat_18: ; SLA+W transmitted, ACK received
MOV S1DAT,@R0 ; 1. Datenbyte @R0
CLR sta
CLR SI
CLR sto
JMP i2c_end
stat_20: ; SLA+W transmitted, NOT ACK received
clr sta
setb sto
clr si
JMP i2c_end
stat_28: ; S1DAT transmitted, ACK received
send:
DJNZ anz_byte,WEITER
CLR STA
CLR SI
SETB sto
SETB ok
JMP i2c_end
WEITER:
INC R0
MOV S1DAT,@R0
CLR sta
CLR SI
JMP i2c_end
stat_30: ; S1DAT transmitted, NOT ACK received
CLR sta
CLR si
SETB sto
SETB ok
JMP i2c_end
stat_38:
JMP i2c_end
i2c_end:
MOV A,save
RETI
END
Da die Schaltung durch den Aufbau auf Laborsteckbrett nicht richtig funktionierte, wurde sie auf Lochrasterplatte mit Hilfe von Lötzinn und Fädelstift erneut aufgebaut. Durch diesen Aufbau waren keine Wackelkontakte mehr möglich, und der Wert, der im Programm eingestellt wurde, konnte ohne weitere Probleme auf der Anzeige ausgegeben werden.
Aufbau des Hauptprogramms:
$include (80c552.def)
; * * * * * * * * * * * * * * *
; * DEFINITION DER VARIABLEN *
; * * * * * * * * * * * * * * *
S1 data 30h
S2 data 31h
out code 273ch
; * * * * * * * * * * *
; * INTERRUPTVEKTOREN *
; * * * * * * * * * * *
org 8000h
LJMP INIT
org 8053h
LJMP MESSUNG
org 8100h
; * * * * * * * * * *
; * INITIALISIERUNG *
; * * * * * * * * * *
INIT:
MOV A,#00h ;
MOV B,#00h ;
MOV S1,#00h ; Variablen und Akku 0 setzen
MOV S2,#00h ;
MOV S3,#00h ;
MOV IEN0,#0C0h ;EA, EAD im Interrupt - Enable - Register 0 setzen
MOV ADCON,#08h ;MUX auf Eingang 0 und ADC setzen
HAUPT:
JMP HAUPT
; * * * * * * * * * * *
; * MESSUNG ÃœBER ADC *
; * * * * * * * * * * *
MESSUNG:
MOV a,#' '
LCALL 273ch
MOV a,#' '
LCALL 273ch
; MOV a,#' '
; LCALL 273ch
; MOV a,#' '
; LCALL 273ch
MOV R6,#00h ;Register R6 0 setzen
MOV R7,#00h ;Register R7 0 setzen
;Umwandlungen Temperaturkompensation
MOV A,ADCH ;ADCH auslesen
LCALL hex_byte_out
MOV A,#'*'
LCALL char_out
MOV B,#03h ;Wert 3 ins B - Register schreiben
DIV AB ;ADCH durch 3 dividieren
MOV s1,A ;ADCH/3 in S1 speichern
MOV A,B ;Rest der Division in Akku schreiben
MOV B,#38h
MUL AB ;Divisionsrest mit 56d (38h) multiplizieren
MOV s2,B ;Divisionsrest*56, šberlauf in S2 abspeichern
MOV A,s1
MOV B,#0EH ;ADCH/3 mit 14d (0Eh) multiplizieren
MUL AB
MOV R6,B ;den Multiplikationsüberlauf in R6 abspeichern
MOV R0,s2
ADD A,R0 ;Divisionsrest*56 Ãœberlauf + ADCH/3*14
MOV R7,A
CLR C
SUBB A,#0E0h ;Subtraktion von R7 233d (E9h)
MOV R7,A ;Ergebnis wird in das R7 Register geschrieben
JC ERSTE ;gibt es einen Ãœberlauf - in ERSTE springen
JNC AUS ;gibt es keinen Ãœberlauf - in AUSGABE springen
ERSTE:
MOV A,R6 ;R6 in AKKU laden
SUBB A,#01h ;von R6 ein šberlaufbit abziehen
MOV R6,A ;in R6 zurückschreiben
AUS:
MOV A,R6
LCALL Hex_Byte_Out
MOV A,R7
LCALL Hex_Byte_Out
LCALL DOUT
LCALL CLRSCR
MOV ADCON,#08h
RETI
; * * * * * * * * * * * * * * * * * * * * *
; * UMWANDLUNG VON HEXADEZIMAL IN DEZIMAL *
; * * * * * * * * * * * * * * * * * * * *
$include (out1.inc)
; * * * * * * * * * * * * * * *
; * LÖSCHUNG DES BILDSCHIRMES *
; * * * * * * * * * * * * * * *
CLRSCR:
MOV a,#1Bh
LCALL 273ch
MOV a,#5Bh
LCALL 273ch
MOV a,#48h
LCALL 273ch
MOV a,#1Bh
LCALL 273ch
MOV a,#5Bh
LCALL 273ch
MOV a,#4Ah
LCALL 273ch
RET
END
2162 Worte in "deutsch" als "hilfreich" bewertet