PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : ADC Ausgabe an 7-Segment-Display



Malte0815
09.03.2010, 18:27
Hallo,

nach langer Bascom-Pause hab ich mal wieder ein bisschen Zeit zum Programmieren gefunden. Bin im Prinzip noch Anfänger. Nun hab ich ein Problem bei der Ausgabe des ADC-Wertes auf ein 7-Segment-Display.
Es ist einfach nur ein Verständisproblem. Ich hab mich schon Ausgibig mit dem ADC Beschäftig aber ich komm einfach nicht auf die Lösung...
Ich hab ein Potentiometer (10K) und möchte für den Anfang einfach nur die gemessene Spannung des ADC als einfache Zahlen von 1-9 auf die Anzeige bringen (mein Gedanke - jedem der Zahlen einen Wertebereich zuordnen...Bsp. 1023/10, also für 0=0-102; 1=103-204 usw.).
Nun weiss ich überhaupt nicht, wie ich das in Bascom umsetzen soll.
Mein Versuch bei dem immer nur "8" angezeigt wird und beim drehen nichts passiert:

$regfile = "M8def.dat"
$crystal = 1000000

Config Portd = Output
Portd = 255


Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc


Dim Messung As Byte

Dim I As Byte

Dim X(10) As Byte

Restore Value_table

Do

Messung = Getadc(0)
If Messung < 100 Then
Portb = X(1)


Messung = Getadc(0)
If Messung > 100 Then
Portb = X(2)

End If
End If


Loop


End





Value_table:
' 0 1 2 3 4 5 6 7 8 9
Data &H3F , &H6 , &H05B , &H04F , &H066 , &H06D , &H07D , &H7 , &H7F , &H6F

for_ro
09.03.2010, 19:01
Hallo,
nach dem Restore Value_table musst du erst einmal die Werte in das X-Array einlesen. Am einfachsten in einer Schleife:

Dim I As Byte
...
Restore Value_table
For I = 1 to 10
Read X(I)
Next I

Malte0815
09.03.2010, 19:17
Hat leider nichts gebracht. Hatte vorher ein programm laufen wo die Ziffern von 0 bis 9 durchlaufen. Das hat super funktioniert also ist die Verdrahtung schonmal richtig :).

for_ro
09.03.2010, 20:08
Ist das denn richtig, dass du PortD als Output konfiguriert hast, aber PortB setzt?

Malte0815
09.03.2010, 20:29
Oh man. Natürlich;). Vielleicht sollte ich erstmal ne Pause machen. Jetzt wechseln beim drehen schonmal die 2 zahlen... Super. Aber wie stell ich es nun an, das ich alle 10 zahlen "durchdrehe"? Ich hab es schon mit 10 "if-then" versucht aber da spinnt die Anzeige total.

for_ro
09.03.2010, 20:46
Ich würde es ohne den ganzen If..Then Schnickschnack so machen:

Messung = Getadc(0) / 103 'dann kommen nur Zahlen von 0-9 raus
PortD = X(Messung + 1)

Malte0815
10.03.2010, 17:48
Super!! Jetzt klappt es... aber nur teilweise. Wenn ich mit "103" Teile wird komischerweise nur von null bis zwei angezeigt und das in einem spannngsbereich von ca. 1.2V, dann geht es wieder bei null los bis ich dann bei 5V hochgedreht habe. Hab mal ein bisschen mit dem Teiler rumprobiert- wenn ich z.B. 50 eingebe wird von null bis neun angezeigt aber der durchlauf erfolgt immer in 1.2V Abständen. So wie ich das jetzt verstanden habe wird doch eigentlich 1023/103 gerechnet, und somit hätte man 10 "Schritte" auf 5V???

for_ro
10.03.2010, 18:02
Wenn ich mit "103" Teile wird komischerweise nur von null bis zwei angezeigt
Klingt, als hättest du Messung als Byte deklariert.

Malte0815
10.03.2010, 19:01
Bin mal wieder beeindruckt wie schnell man den Fehler anhand einer ungefähren Fehlerbeschreibung finden kann. Klasse! Kann es leider erst morgen testen.

Malte0815
11.03.2010, 18:00
Die Schaltung und die Programmierung hauen jetzt super hin;). Vielen Dank erstmal für die Hilfe. Wiedermal jede Menge gelernt. Ich werd mich jetzt erstmal ans Muliplexen mit zwei Stellen und einer Kommastelle wagen...bis ich irgendwann mein Thermometer hinbekommen habe.

for_ro
11.03.2010, 18:28
Mach' die Umschalterei von Anfang an über einen Timer. Alles andere wirst du später bereuen.
Und denke daran, immer erst alles abzuschalten, bevor du neue Werte auf die Ports gibst. Sonst bekommst du die leidigen Geisterbilder.

Malte0815
12.03.2010, 13:06
Hab mich jetzt mal ein wenig mit dem multiplexen beschäftigt. Die Schaltung der gem. Anoden und den Transistoren funktioniert soweit. Leider hängt es wieder bei der Programmierung. Ich hab einen atmega8 mit 1Mhz Frequenz. Soweit ich es verstanden habe wird dem 8bit Timer automatisch ein 10bit prescaler also /1024 eingeschaltet. Stelle ich jetzt in der config einen prescaler 8 ein komm ich auf 122 Hz (richtig??). Mein eigentlches Problem ist die programmierung, um die beiden Ausgänge für die gem. Anoden an bzw. aus zu schalten. Ich komm nicht so richtig mit den variablen klar. Müssen jetzt die einzelnen Segmente abwechselnd oder jede einfach für sich ein/ausgeschaltet werden und wie sage ich jedem Ausgang das bei den Zehnern jetzt ne 1 und bei den Einern ne null angezeigt werden soll. Vielleicht kann mir jemand mal in Worten den Ablauf erklären?

for_ro
12.03.2010, 15:51
Deine 1MHz sind natürlich nicht so umwerfend schnell, aber es sollte trotzdem gehen.
Deine Angaben mit dem Prescaler habe ich nicht verstanden. Was ist ein 10bit prescaler?
Wenn du 2 Stellen umschalten willst und dies flimmerfrei mit 100Hz, dann muss deine ISR Frequenz folglich mindestens 200 Hz betragen.
Du kommst auf die richtigen Werte für Prescale und Anzahl Überläufe über diesen Zusammenhang:

Gewünschte Frequenz (bei dir 200) = $crystal / prescale / overflow_count
Bei 1MHz Crystal also z.B.
200 ~ 1.000.000 / 1024 / 5 oder
200 ~ 1.000.000 / 64 / 78
200 ~ 1.000.000 / 8 / 312

Da du einen 8-bit Timer benutzen willst, wird die letzte Version nicht mehr gehen, da der Timer nur bis 255 zählen kann.
Je kleiner der Prescale um so genauer kannst du den gewünschten Wert treffen. Das ist bei dir aber eher unerheblich.
In der Timer_isr schaltest du jetzt bei jedem Aufruf zwischen den beiden Ausgängen für die gemeinsamen Anoden um und legst den neuen Wert auf die Ausgänge für die Segmente. Wenn die alle an einem Port liegen, kannst du dies sehr einfach mit einem Befehl tun. So ähnlich wie oben also mit
PortD = Segmente(wert_der_stelle)

Malte0815
13.03.2010, 17:03
Die Info mit dem 10bit Prescaler hab ich aus nem Buch für Atmel-Programmierung. "....Timer0 ist ein 8-Bit-Timer mit einem vorgeschaltetem 10-Bit-Prescaler."
Das Schalten der Ausgänge für die Zehner/Einer hab ich so gelöst:

$regfile = "M8def.dat"
$crystal = 1000000

'--------Segmente---------------
Config Portd = Output
Portd = 1

'----------Anode Display---------
Config Portb = Output
Digit1 Alias Portb.1
Digit2 Alias Portb.2

Portb = 0

'---------AD-Wandler Config-------------
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'--------Timer Config----------------
Dim A As Byte 'Umschaltung einer/zehner


Config Timer0 = Timer , Prescale = 8
On Timer0 Timer_routine
Enable Timer0
Enable Interrupts




Dim Messung As Integer

Dim I As Byte

Dim X(10) As Byte

Restore Segmente

For I = 1 To 10
Read X(i)
Next I

Do

Messung = Getadc(0) / 103 'Wert vom ADC/103 in Variable speichern
Portd = X(messung + 1)

Loop


End


Timer_routine:

Incr A 'Variable um 1 erhöhen

Portb = A 'portb.1 /portb.2 an/aus schalten

Return










'---------------------------------------------------------------------------
Segmente:
'gemeinsame Anode:
' 0 1 2 3 4 5 6 7 8 9
'Data &H3F , &H6 , &H05B , &H04F , &H066 , &H06D , &H07D , &H7 , &H7F , &H6F
'gemeinsame kathode:
' 0 1 2 3 4 5 6 7 8 9
Data &H40 , &H79 , &H24 , &H30 , &H19 , &H12 , &H02 , &H78 , &H00 , &H10

Trotz viel Lesen und probieren ist es mir aber noch nicht gelungen z.B. eine "10" darzustellen. Ich hab ein Paar Beispiele mit "Select Case" gesehen, hab sie aber nicht verstanden? Ist das eine Möglichkeit die ich verwenden sollte?

for_ro
13.03.2010, 17:39
Sieht doch gar nicht so schlecht aus. Ich habe mal ein paar kleine Änderungen gemacht. Probier es mal aus.


$regfile = "M8def.dat"
$crystal = 1000000

'--------Segmente---------------
Config Portd = Output
Portd = 1

'----------Anode Display---------
Config Portb = Output
Digit1 Alias Portb.1
Digit2 Alias Portb.2

Portb = 0

'---------AD-Wandler Config-------------
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'--------Timer Config----------------
Dim A As Byte 'Umschaltung einer/zehner


Config Timer0 = Timer , Prescale = 8
On Timer0 Timer_routine
Enable Timer0
Enable Interrupts
A = 1



Dim Messung As Word
Dim Stelle(2) As Byte

Dim I As Byte

Dim X(10) As Byte

Restore Segmente

For I = 1 To 10
Read X(i)
Next I

Do

Messung = Getadc(0) / 11 'Wert vom ADC/11 (0-99) in Variable speichern
Stelle(1) =messung / 10 'Hinter dem Komma wird abgeschnitten, enthält also die Zehner
Incr Stelle(1) 'Damit die Werte von 1-10 gehen
Stelle(2)=messung mod 10 'gibt den Rest, also die Einer
Incr Stelle(2)

Loop


End


Timer_routine:
Portb.a = 0 'Vorherige Stelle ausschalten
Incr A
If A=3 Then A=1
Portd=X(Stelle(A)) 'Neue Segmente ausgeben
Portb.a = 1 'Neue Stelle einschalten
Return

Segmente:
'gemeinsame Anode:
' 0 1 2 3 4 5 6 7 8 9
'Data &H3F , &H6 , &H05B , &H04F , &H066 , &H06D , &H07D , &H7 , &H7F , &H6F
'gemeinsame kathode:
' 0 1 2 3 4 5 6 7 8 9
Data &H40 , &H79 , &H24 , &H30 , &H19 , &H12 , &H02 , &H78 , &H00 , &H10

Malte0815
13.03.2010, 17:50
super!!! Manchmal flackkern die Zahlen zwar ein bisschen aber ich denke das hängt mit der niedrigen Grundfrequenz des Atmegas zusammen?! Ich werd mich mal durch den Code wuseln um zu verstehen was du alles gemacht hast.
Vielen Dank :)

Malte0815
16.03.2010, 18:11
Nachdem ich mir meinen Atmega "Verfused" habe und ihn nach viel lesearbeit, mit nem tiny wieder flott gemacht habe, sitz ich nun vor dem nächsten Problem.

Es geht um die Berechnung des ADC-Wertes in eine Anzeigbare Temperatur.
Hab schon viel über die KTY-Reihe gelesen und wie diese linearisiert werden (darauf kommts mir erstmal nicht an).
Also ich verwende einen KTY81-120. Ich hab ihn über einen Spannungsteiler 1K am ADC-Pin angeschlossen. Nun hab ich mit meinem Multimeter eine Zimmertemperatur von 20 Grad gemessen. Dies wollte ich als Ausgangstemperatur nehmen. Am Sensor liegt also bei 20 Grad eine Spannung von 2,5 Volt an. Das entspricht einem ADC-Wert von 512. Der Widerstandbereich des KTY liegt bei 1721 Ohm (20 Grad = 1KOhm).
Ich krieg die Formel für die Umrechnung einfach nicht hin, obwohl es doch gar nicht so schwer sein kann???

@ for_ro
Kannst du mir den Befehl "mod" und den Code-Abschnitt (siehe unten) noch erklären? Hab in der Hilfe keine Erklärung gefunden.


If A = 3 Then A = 1
Portd = X(stelle(a))

Malte0815
20.03.2010, 17:33
Ich hab mir nun folgendes Programm erarbeitet:). Die Temperatur haut schonmal ganz gut hin. Allerdings hab ich es immer noch nicht hinbekommen eine weiter Stelle der 7-Segment-Anzeige anzusprechen. Hier soll einfach ein "°" angezeigt werden. Den Code in der Timer-Routine hab ich immer noch nicht ganz verstanden. Vielleicht kann mir jemand auf die Sprünge helfen.
$regfile = "M8def.dat"
$crystal = 4000000

'--------Segmente---------------
Config Portd = Output
Portd = 1

'----------Anode Display---------
Config Portb = Output
Digit1 Alias Portb.1
Digit2 Alias Portb.2
Digit3 Alias Portb.3
Portb = 0

'---------AD-Wandler Config-------------
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'--------Timer Config----------------
Dim A As Byte 'Umschaltung einer/zehner
A = 1

Config Timer0 = Timer , Prescale = 64
On Timer0 Timer_routine
Enable Timer0
Enable Interrupts




Dim Messung As Word
Dim Stelle(3) As Word


Dim I As Byte

Dim X(11) As Byte

Restore Segmente

For I = 1 To 10
Read X(i)
Next I

Do

Messung = Getadc(0) * 64
Messung = Messung / 101
Messung = Messung - 151
Stelle(1) = Messung / 10
Incr Stelle(1)
Stelle(2) = Messung Mod 10
Incr Stelle(2)




Loop


End


Timer_routine:



Portb.a = 0 'Vorherige Stelle ausschalten

Incr A 'Neue Segmente ausgeben
If A = 3 Then A = 1
Portd = X(stelle(a))

Portb.a = 1

Return

Segmente:
'gemeinsame Anode:
' 0 1 2 3 4 5 6 7 8 9
'Data &H3F , &H6 , &H05B , &H04F , &H066 , &H06D , &H07D , &H7 , &H7F , &H6F
'gemeinsame kathode:
' 0 1 2 3 4 5 6 7 8 9 Grad
Data &H40 , &H79 , &H24 , &H30 , &H19 , &H12 , &H02 , &H78 , &H00 , &H10 , &H63

for_ro
20.03.2010, 18:21
Hallo Malte0815,
ich hatte nicht gesehen, dass du mich schon einmal direkt gefragt hattest.
If A = 3 Then A = 1
Portd = X(stelle(a))

A ist die Stelle, die aktuell eingeschaltet ist, in Stelle(A) steht der aktuelle Wert, der ausgegeben werden soll.
In X(Stelle(A)) steht der entsprechende Segment-Wert für diese Ziffer.

Wenn du jetzt 3 Stellen hast, dann musst du A bis 4 laufen lassen, bevor es wieder auf ein gesetzt wird. Also
If A = 4 Then A = 1

Das Gradzeichen würde ich am Anfang einmal fest in Stelle(3) schreiben, dann brauchst du sonst nichts mehr zu ändern. Also hinter
For I = 1 To 10
Read X(i)
Next I

einfach noch
Read Stelle(3) oder direkt
Stelle(3) = &H63

Hier mal alles zusammen (mit noch etwas Kosmetik):


$regfile = "M8def.dat"
$crystal = 4000000

'--------Segmente---------------
Config Portd = Output
Portd = 0 'anfangs alles aus

'----------Anode Display---------
Config Portb = Output
Digit1 Alias Portb.1
Digit2 Alias Portb.2
Digit3 Alias Portb.3
Portb = 0 'auch hier alles aus

'---------AD-Wandler Config-------------
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'--------Timer Config----------------
Dim Stelle As Byte 'Umschaltung zehner/einer/grad_zeichen
Stelle = 1 'start mit Zehner

Config Timer0 = Timer , Prescale = 64
On Timer0 Timer_routine 'wird 4.000.000/64/256 ~ 244 mal pro Sekunde aufgerufen
Enable Timer0
Enable Interrupts

Dim Messung As Word
Dim Wert_stelle(3) As Byte
Dim I As Byte
Dim Temp As Word
Dim Segmente(11) As Byte

Restore Segment_daten

For I = 1 To 10
Read Segmente(i)
Next I
Wert_stelle(3) = &H63 '°fest auf Stelle 3

Do
Messung = Getadc(0) * 64
Messung = Messung / 101
Messung = Messung - 151
Messung = Messung
Temp = Messung / 10 'ganzahlige Division, also 47 / 10 = 4
Wert_stelle(1) = Temp + 1
Temp = Messung Mod 10 'Mod ergibt den Rest der Division, also bei 47 / 10 ist Mod = 7
Wert_stelle(2) = Temp + 1
Waitms 100 'hier vielleicht noch eine kleine Pause
Loop


End


Timer_routine:
Portb.stelle = 0 'Vorherige Stelle ausschalten
Portd = 0 'zusätzlich alle Segmente aus
Incr Stelle 'auf nächste Stelle umschalten
If Stelle = 4 Then Stelle = 1 'am Ende wieder zurück zur ersten Stelle
Portd = Segmente(wert_stelle(stelle)) 'Neue Segmente ausgeben
Portb.stelle = 1 'neue Stelle einschalten
Return

Segment_daten:
'gemeinsame Anode:
' 0 1 2 3 4 5 6 7 8 9
'Data &H3F , &H6 , &H05B , &H04F , &H066 , &H06D , &H07D , &H7 , &H7F , &H6F
'gemeinsame kathode:
' 0 1 2 3 4 5 6 7 8 9 Grad
Data &H40 , &H79 , &H24 , &H30 , &H19 , &H12 , &H02 , &H78 , &H00 , &H10 ', &H63

Malte0815
21.03.2010, 12:56
Hmm...ich bin nun schon den ganzen Morgen am probieren aber irgdwo steckt noch der Wurm drin.
Hab auch eben deinen überarbeiteten Code(danke für die Mühe O:)) probiert aber immer das selbe Phänomen.

Sobald ich bei" If Stelle = 3 Then Stelle = 1" die 3 durch eine 4 ersetze, leuchten bei beiden Digits alle segmente auf und die zu darstellenden Zahlen leuchten etwas heller durch. Beim dritten Digit leuchtet eine Mischung aus Zehnern und einern.
Anfangs dachte ich es hätte etwas mit der Frequenz zu tun aber mit Teiler 8 ist das selbe.
Wenn ich nun wieder 3 einsetze, werden Einer und Zehner wieder normal angezeigt und beim dritten Digit unverändert eine Mischung aus beiden Zahlen.

Ich versteh es nicht....wenn die Variable des Portb einfach um eins weiter zählen soll, kann sich doch bei der Darstellung nichts ändern, außer das die Frequenz ohne Anpassung niedriger wird, oder seh ich da was falsch?

for_ro
21.03.2010, 13:36
Kann es sein, dass du gar keine 1 auf den Port geben musst, damit die Stelle angeht, sondern eine 0? Wie sieht deine Beschaltung aus, die an PortB dran ist?
Wenn nur zwei Stellen da sind, dann ist das egal. Dann wären nur die Ziffern vertauscht. Bei drei Stellen würden dann aber immer zwei leuchten, was zu so einem Effekt führen würde.

Malte0815
21.03.2010, 13:55
Hab es gerade mal ausprobiert. Du hast wieder mal Recht ;). Die Basis meines Transistors wird gegen Minus geschaltet (ich mach schon sooo lange mit der Schaltung rum, dass ich das ganz vergessen habe). Das heißt jetzt ich muss PortB erst ein und dann aus schalten.....und die Kathoden von Portb.1 und Portb.2 vertauschen??

for_ro
21.03.2010, 14:01
Das heißt jetzt ich muss PortB erst ein und dann aus schalten.....und die Kathoden von Portb.1 und Portb.2 vertauschen??
Das erste ja. In der ISR erst PortB.Stelle = 1 und am Ende PortB.Stelle=0.
Die Anschlüsse von Portb.1 und .2 brauchst du nicht zu vertauschen, das kannst du im Programm ändern. Einfach da wo Wert_Stelle(1) gesetzt wird schreibst du nun Wert_stelle(2) und umgekehrt.

Malte0815
21.03.2010, 19:22
Endlich mal ein kleiner Erfolg. Hab nach langer Suche noch nen kleinen Fehler gefunden durch den bei der dritten Stelle(fürs grad) immer nur ne 8 angezeigt wurde. Bei ....
For I = 1 To 10
Read Segmente(i)....... muss die 10 noch durch ne 11 ersetzt werden da sonst ja das elfte Zeichen nicht gefunden wird.

Als nächstes werd ich mal versuchen nen fotowiderstand als Helligkeitsregelung einzubauen.

Malte0815
23.03.2010, 12:10
Nun ist es fast geschaft :). ein kleines Problem bleibt noch bei der Darstellung im negativen Bereich. Meine Überlegung war nun mit einer "If-Then-Abfrage" in eine Sub-Routine zu springen, und dann den Wert der Variable Temp einfach 2 mal zu addieren. doch irgendwie klappt das nicht.
Was passiert eigentlich mit einer Byte-Variable wenn ein negatives Ergebnis berechnet wird?
Den "Minus-Strich" steuere ich nun über einen 5. Transistor und Portb.0 indem ich an die Basis des Transistors für die "Minusstelle" gegen + schalte. Das funktioniert auch ganz gut:
Messung2 = Getadc(0)
If Messung2 < 237 Then Portb.0 = 1 'wenn getadc(0) kleiner als 237 (0°) dann minus an
If Messung2 > 237 Then Portb.0 = 0
Ich weiss natürlich jetzt nicht ob es sehr elegant ist, aber es funktioniert. Ich hab dadurch zwar bei ausgeschaltetem Minuszeichen einen Mehrverbrauch von 5mA aber das spielt eigentlich erstmal keine Rolle..

Doch nochmal zurück zum eigentlichen Problem:
Wie kann ich am besten die Programmierung für die Invertierung von z.B. -10° vornehmen? In ein Unterprogramm springen wenn getadc unterschritten wird? Ich hab es schon mit dem Rotate Befehl probiert aber es hat nicht geklappt.

for_ro
23.03.2010, 18:25
Es gibt da natürlich viele Wege zum Ziel.
Du könntest z.B. Messung als Integer deklarieren. Dann wird Messung < 0, falls der Getadc Wert <237 ist.
Dann überprüfst du, ob Messung < 0 ist und schaltest entsprechend PortB.0 auf 1, ansonsten auf 0.
Anschliessend multiplizierst du Messung mit -1, sodass Messung wieder positiv ist. Dann funktionieren die Stellen wieder wie gewohnt.

Malte0815
30.03.2010, 22:06
So. Hab mein Thermometer endlich fertig und es funktioniert (jippi). Vielen dank an for_ro für die tolle Unterstützung. Werd morgen noch den fertigen Code und ein paar Bilder uploaden, für alle (Anfänger) die vielleicht vor ähnlichen Problemen stehen werden.

Malte0815
01.04.2010, 17:51
Hier sind wie versprochen ein Bild und der fertige Code.
(Die Option vier Sensoren abzufragen und mit dem Taster durchzuschalten ist noch nicht ganz fertig aber sonst funktioniert es einwandfrei).

Schaltplan:
https://www.roboternetz.de/phpBB2/album_pic.php?pic_id=2485
Bild:
https://www.roboternetz.de/phpBB2/album_pic.php?pic_id=2484


$regfile = "M8def.dat"
$crystal = 4000000

'--------Segmente---------------
Config Portd = Output
Portd = 1 'anfangs alles aus

'----------Anode Display---------
Config Portb = Output
Digit1 Alias Portb.1
Digit2 Alias Portb.2
Digit3 Alias Portb.3
Digit4 Alias Portb.4
Dp Alias Portb.5
Portb = 1 'auch hier alles aus

'---------------Taster------------
Config Pind.7 = Input
Pind.7 = 1
'Taster Alias Pind.7

'---------AD-Wandler Config-------------
Config Adc = Single , Prescaler = Auto , Reference = Avcc
Start Adc

'--------Timer Config----------------
Dim Stelle As Byte 'Umschaltung zehner/einer/grad_zeichen
Stelle = 1 'start mit Zehner

Config Timer0 = Timer , Prescale = 64
On Timer0 Timer_routine 'wird 4.000.000/64/256 ~ 244 mal pro Sekunde aufgerufen
Enable Timer0
Enable Interrupts

'Declare Sub Naechste

Dim Messung As Integer
Dim Wert_stelle(4) As Byte 'Variable für die einzelnen Stellen im Array(3)
Dim I As Byte 'Variable für Ausgabe der einzelnen Zeichen
Dim Temp As Integer 'Variable für Temperatur nach Berechnung
Dim Segmente(12) As Byte 'Variable für einzelne Segmente jeder Ziffer
Dim Messung2 As Integer 'für Minuszeichen
Dim Messpunkt As Byte
Messpunkt = 0


Const Offset = 150.5
Restore Segment_daten 'Tabelle der Zeichen laden

For I = 1 To 12
Read Segmente(i)
Next I



Wert_stelle(3) = 11 '°fest auf Stelle 3
Wert_stelle(4) = 12 'minus fest auf Stelle 4



Do

'If Taster = 0 Then Gosub Naechste


Messung = Getadc(messpunkt) * 64 'Messung des ADC in Variable(Messung) speichern und mit 64 multiplizieren
Messung = Messung / 101 'Messung mit 101 dividieren
Messung = Messung - Offset
Temp = Messung / 10 'für direkte Temperaturanzeige 150 abziehen 'ganzahlige Division, also 47 / 10 = 4
Wert_stelle(1) = Temp + 1
Temp = Messung Mod 10 'Mod ergibt den Rest der Division, also bei 47 / 10 ist Mod = 7
Wert_stelle(2) = Temp + 1

Messung2 = Getadc(messpunkt)
If Messung2 < 237 Then Portb.0 = 1 'wenn getadc(0) kleiner als 237 (0°) dann minus an
If Messung2 > 237 Then Portb.0 = 0


Waitms 1000 'hier vielleicht noch eine kleine Pause - um pendeln zwischen 2 temperaturen zu reduzieren

Loop
End


Timer_routine:

Portb.stelle = 1 'Vorherige Stelle ausschalten
Portd = 1 'zusätzlich alle Segmente aus
Incr Stelle 'auf nächste Stelle umschalten
If Stelle = 5 Then Stelle = 1 'am Ende wieder zurück zur ersten Stelle
Portd = Segmente(wert_stelle(stelle)) 'Neue Segmente ausgeben
Portb.stelle = 0 'neue Stelle einschalten
Return

'Sub Naechste
'Incr Messpunkt
'If Messpunkt = 2 Then Messpunkt = 0
'End Sub



Segment_daten:
'gemeinsame Anode:
' 0 1 2 3 4 5 6 7 8 9
'Data &H3F , &H6 , &H05B , &H04F , &H066 , &H06D , &H07D , &H7 , &H7F , &H6F
'gemeinsame kathode:
' 0 1 2 3 4 5 6 7 8 9 grad minus
Data &H40 , &H79 , &H24 , &H30 , &H19 , &H12 , &H02 , &H78 , &H00 , &H10 , &B10011100 , &B1011