PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Uhr zeigt Sonderzeichen???



TobiasBlome
24.12.2007, 13:40
Hallo,
in meinem Program ist unter anderem eine Uhr mit Sekundenanzeige. Zum test gebe ich die Uhrzeit jede Sekunde über RS232 und LCD aus! Über RS232 läuft alles - auf dem LCD kommen regelmäßig merkwürdige Zeichen- hier mal die Sekundenanzeige:
01
02
03
04
05
06
07
08
09
0:
0;
0<
0=
0>
0?
10
11
und dann läuft die Uhr weiter bis:
18
19
1:
1;
1<
1=
1>
1?
20
21 und so weiter...

Hat da jemand eine Erklärung für?

vielen Dank schon mal, Tobias

---schnipp---
'Timer
Dim Stunden As Byte
Dim Minuten As Byte
Dim Sekunden As Byte
Dim Sekunden_alt As Byte 'um Veränderungen zu merken

Stunden = Makebcd(stunden) 'in BCD wegen der Formatierung 00:00:00
Minuten = Makebcd(minuten)
Sekunden = Makebcd(sekunden)
...
Locate 1 , 1
Lcd "Uhrzeit: " ; Bcd(stunden) ; ":" ; Bcd(minuten) ; ":" ; Bcd(sekunden)
---schnipp---




'Konfiguration µC:

$regfile = "m8def.dat" 'AT-Mega8
$crystal = 3686400 'Quarz: 3.6864 MHz
$baud = 9600 'Baudrate der UART: 9600 Baud


'Analogmessung
Config Adc = Single , Prescaler = Auto , Reference = Avcc

'TIMER
On Timer1 Ontimer1overflow 'Timer1-Interruptroutine deklarieren
Config Timer1 = Timer , Prescale = 1024 '3686400Hz/1024=3600Hz
Enable Timer1
Timer1 = 61935 'Sofort Timer1-Überlauf (Bei 16 Bit: 65535+1=0)
Enable Interrupts


'-------------------------------------------------------------------------------
'Ein- Ausgänge:

Ddrb = &B111111 '1 Ausgang, 0 Eingang = Pin PB5-0 als Ausgang
Ddrc = &B0000000 '1 Ausgang, 0 Eingang = Pin PC6-0 als Eingang


'-------------------------------------------------------------------------------
'LCD konfiguration
Config Lcd = 20 * 4 'LCD größe
Config Lcdpin = Pin , Db4 = Portd.2 , Db5 = Portd.3 , Db6 = Portd.4 , Db7 = Portd.5 , Rs = Portd.6 , E = Portd.7

Cursor Off Noblink


'-------------------------------------------------------------------------------
' Variablen
Dim Analog_in0 As Word '=0-1023 vom Analogeingang



'Timer
Dim Stunden As Byte
Dim Minuten As Byte
Dim Sekunden As Byte
Dim Sekunden_alt As Byte 'um Veränderungen zu merken

Stunden = Makebcd(stunden) 'in BCD wegen der Formatierung 00:00:00
Minuten = Makebcd(minuten)
Sekunden = Makebcd(sekunden)


'Speicherplätze
Dim Zähler As Word 'zum Werte hochzählen
Dim Merker As Bit 'Werte speichern: damit nur um 1 hochgezählt wird
Dim Wert(470) As Word 'speichern des eigendlichen Wertes (470Werte?)

'Umrechnung in Liter
Dim Liter As Integer
Dim Liter1 As Single




'-------------------------------------------------------------------------------
'Programm:
'-------------------------------------------------------------------------------

Zähler = 0 'damit mit Wert1 angefangen wird und nicht mit Wert0 (0 könnte Fehler geben)
Merker = 0 'Werte speichern: damit nur um 1 hochgezählt wird

Do

Start Adc 'Starte analog Messung

'-------------------------------------------------------------------------------
'Analogeingänge Auslesen:
Analog_in0 = Getadc(0) 'Wert aus Analogeingang0 laden


'-------------------------------------------------------------------------------
'Merker zurücksetzen
If Minuten = 1 Then 'damit jeder Wert nur einmal gespeichert wird
Merker = 0 'Hilfsmerker wird beim speichern gesetzt und hier zurückgesetzt
End If

'---
If Minuten = 16 Then
Merker = 0
End If

'---
If Minuten = 31 Then
Merker = 0
End If

'---
If Minuten = 46 Then
Merker = 0
End If

'-------------------------------------------------------------------------------
'Analogwert umrechnen in Liter
Liter1 = Analog_in0 * 4.80938416422287
Liter = Liter1 - 984


'-------------------------------------------------------------------------------
'Werte Speichern alle 15 min:
If Minuten = 0 And Merker = 0 Then 'nur speichern, wenn hilfsmerker bereits zurückgesetzt wurde
Incr Zähler 'Zähler für die nächste Speichervariable hochzählen
Toggle Portb.2 'Led bei Speicherung umschalten
Wert(zähler) = Liter 'umgerechneten Analogwert in Speicher (WertX) übertragen
Merker = 1 'Hilfsmerker setzen
Print "Zähler: " ; Zähler ; " = " ; Wert(zähler) 'aktuellen Zähler mit Wert anzeigen
End If

'---
If Minuten = 15 And Merker = 0 Then 'nur speichern, wenn hilfsmerker bereits zurückgesetzt wurde
Incr Zähler 'Zähler für die nächste Speichervariable hochzählen
Toggle Portb.2 'Led bei Speicherung umschalten
Wert(zähler) = Liter 'umgerechneten Analogwert in Speicher (WertX) übertragen
Merker = 1 'Hilfsmerker setzen
Print "Zähler: " ; Zähler ; " = " ; Wert(zähler) 'aktuellen Zähler mit Wert anzeigen
End If

'---
If Minuten = 30 And Merker = 0 Then 'nur speichern, wenn hilfsmerker bereits zurückgesetzt wurde
Incr Zähler 'Zähler für die nächste Speichervariable hochzählen
Toggle Portb.2 'Led bei Speicherung umschalten
Wert(zähler) = Liter 'umgerechneten Analogwert in Speicher (WertX) übertragen
Merker = 1 'Hilfsmerker setzen
Print "Zähler: " ; Zähler ; " = " ; Wert(zähler) 'aktuellen Zähler mit Wert anzeigen
End If

'---
If Minuten = 45 And Merker = 0 Then 'nur speichern, wenn hilfsmerker bereits zurückgesetzt wurde
Incr Zähler 'Zähler für die nächste Speichervariable hochzählen
Toggle Portb.2 'Led bei Speicherung umschalten
Wert(zähler) = Liter 'umgerechneten Analogwert in Speicher (WertX) übertragen
Merker = 1 'Hilfsmerker setzen
Print "Zähler: " ; Zähler ; " = " ; Wert(zähler) 'aktuellen Zähler mit Wert anzeigen
End If


'-------------------------------------------------------------------------------
'Werte über Rs232 Senden:
If Pinc.3 = 0 Then 'Wenn Taster gedrückt
Portb.3 = 1 'Led "EIN" Daten werden gesendet
For Zähler = 1 To 470 Step 1 'Zähler hochzählen um jede Variable (WertX) zu senden
Print "Wert " ; Zähler ; ": " ; Wert(zähler) 'WertX senden
Waitms 2 'kurze Warte
Next 'wiederholen, bis alle Variablen gesendet wurden
Zähler = 1 'Zähler auf 1 zurücksetzen
Else 'wenn alle Variablen gesendet wurden
Portb.3 = 0 'Led "AUS" kein Daten Senden
End If




'-------------------------------------------------------------------------------

'-------------------------------------------------------------------------------
'UHR einstellen:

'Minuten +
'If Pind.3 = 1 And Minuten <= 59 Then
'Minuten = Minuten + 1
'Waitms 300
'End If

'Stunden+
'If Pinc.2 = 1 And Stunden <= 23 Then
'Stunden = Stunden + 1
'Waitms 300
'End If

Gosub Ausgabe

Loop



'-------------------------------------------------------------------------------
'Sprungmarken
'-------------------------------------------------------------------------------

'Uhrzeit erstellen
Ontimer1overflow: 'Timer1-Interruptroutine
'Nächster Überlauf soll in einer Sekunde sein:
Timer1 = 61936 'Überlauf nach 65535, also: 65535+1-3600=61936

Incr Sekunden

If Sekunden >= 60 Then
Sekunden = 0
Incr Minuten
End If

If Minuten >= 60 Then
Minuten = 0
Incr Stunden
End If

If Stunden >= 24 Then
Stunden = 0
End If

Toggle Portb.0 'blink LED zum testen im Sekundentakt



Return


Ausgabe:

'LCD AUSGABE:
If Sekunden_alt <> Sekunden Then

Cls 'Display löschen (IMMER ERST LCD LÖSCHEN UND DANN POSITION ANGEBEN!!!)
Locate 1 , 1
Lcd "Uhrzeit: " ; Bcd(stunden) ; ":" ; Bcd(minuten) ; ":" ; Bcd(sekunden)

Locate 2 , 1
Lcd "Merker doppelt: " + Str(merker) ;

Locate 3 , 1
Lcd "Wert " + Str(zähler) ; ":" + Str(wert(zähler)) ;

Locate 4 , 1
Lcd "Liter: " + Str(liter) ;


'RS232 AUSGABE:
'Infos nur über RS232 senden, wenn nicht gerade die gespeicherten Daten gesendet werden
If Portb.3 = 0 Then 'WENN Led "AUS" also keine Daten gesendet werden
Print "Zeit: " ; Stunden ; " : " ; Minuten ; " : " ; Sekunden ; " Uhr" 'Uhrzeit senden
Print "Analog_in0: " ; Analog_in0 'Analog Eingangswert senden
Print "Liter: " ; Liter 'umgerechneter Analogwert
End If

Sekunden_alt = Sekunden
End If



Return ' wichtig

TobiasBlome
24.12.2007, 13:41
ach so, der selbe Fehler ist auch bei minuten und stunden

Tobias

linux_80
24.12.2007, 13:55
Hi,

lass bei der Ausgabe mal da BCD() weg, das ist kein BCD, deshalb gehts über RS232 !
BCD geht ja nur von 0-9, wenn der Wert doch grösser wird, gibts Sonderzeichen, bzw. die Zeichen die bei ASCII nach "9" kommen.

TobiasBlome
24.12.2007, 14:12
Hi,
ja du hast recht!
Wenn ich das so mache geht es(habe die erste Minute mit verfolgt):
Lcd "Uhrzeit: " ; + Str(stunden) ; ":" ; + Str(minuten) ; ":" ; + Str(sekunden)

aber was ist denn an BCD falsch? Und der Befehl MakeBCD ist ja immer noch im Programm...

Sekunden = Makebcd(sekunden)

Tobias

TobiasBlome
24.12.2007, 14:15
Hi,

BCD geht ja nur von 0-9, wenn der Wert doch grösser wird, gibts Sonderzeichen, bzw. die Zeichen die bei ASCII nach "9" kommen.

mmhhhh - aber eigendlich kann der Wert doch nicht größer werden oder


'Uhrzeit erstellen
Ontimer1overflow: 'Timer1-Interruptroutine
'Nächster Überlauf soll in einer Sekunde sein:
Timer1 = 61936 'Überlauf nach 65535, also: 65535+1-3600=61936

Incr Sekunden

If Sekunden >= 60 Then
Sekunden = 0
Incr Minuten
End If

If Minuten >= 60 Then
Minuten = 0
Incr Stunden
End If

If Stunden >= 24 Then
Stunden = 0
End If

Toggle Portb.0 'blink LED zum testen im Sekundentakt



Return

linux_80
24.12.2007, 14:33
Hallo schau mal as BCD überhaupt ist:
http://de.wikipedia.org/wiki/Binary_Coded_Decimal
Bei 8 Bit passen also 2 Stellen in ein Byte.

Und auch in der Bascom-Hilfe steht was dazu.

Dein MakeBCD nutz hier ja garnix, weil es nur einmal am Anfang steht.
Aber warum zweimal hinundherwandeln, kostet doch nur Zeit und Programmplatz ? Du hast es doch sowieso schon im richtigen Format.
Und das Str brauchst Du an dieser Stelle auch nicht, einfach nur die Variable angeben, den Rest macht Bascom schon.
Str kann man nur brauchen, wenn Du das in eine andere String-Variable legen willst.

TobiasBlome
24.12.2007, 14:41
naja, weil ich gerne eine "führende" 0 haben wollte - deshalb BCD also 01 Sekunden

aber ich werde mal lesen.

Tobias

linux_80
24.12.2007, 15:45
Dazu gäbs die Funktion fusing, evtl. auch format.

Ich mach das einfach mit einer If-Abfrage, weil mir das günstiger erscheint in Sachen Resourcen:


If Zahl < 10 then
Print "0";
end If
Print Zahl

TobiasBlome
24.12.2007, 22:51
ok ja, aber wie geht es mit LCD?
Lcd "Uhrzeit: " ; + Str(stunden) ; ":" ; + Str(minuten) ; ":" ; + Str(sekunden)

Tobias

Gento
24.12.2007, 23:51
Diese Aufgabe ist 100% biologisch zu lösen.
Genau :Selbst nachdenken und die Hilfe lesen.

Gento

Diese Nachricht ist 100% biologisch abbaubar.

TobiasBlome
25.12.2007, 13:22
@Gento
danke für diesen ausfühlichen und hilfreichen Beitrag

frohe Weihnachten

Tobias

PicNick
25.12.2007, 14:39
...Diese Nachricht ist 100% biologisch abbaubar..

Das will ich auch stark hoffen :evil:

TobiasBlome
25.12.2007, 15:00
Hallo,
anscheinend verstehen alle (ausser mir) wie ich den Code von linux_80
von der seriellen Print ausgabe auf meine LCD-Ausgabe umändern muss, aber bei mir ist der Groschen wohl noch nicht gefallen :cry:
Kann bitte jemand so nett sein und mich mit der Nase drauf stroßen?

Also ich verstehe das so:
ich habe eine Zahl die ich ausgeben möchte. Zuerst überprüfe ich ob die Zahl einstellig ist oder nicht. Wenn sie einstellig ist schreibe ich eine 0 und direkt danach die eigendliche Zahl, weil ich ja bei Print alles hintereinander weg schreiben kann.

Aber bei der LCD-Ausgabe muss ich doch sagen, ab welcher Position ich schreiben möchte. Also die 0 (wenn sie denn fehlt) kommt auf die 1. Stelle. Dann kommt die Zahl auf die 2. Stelle. Wenn die Zahl aber 2 Stellen hat muss sie ja nicht auf die 2. Stelle sondern auf die 1. Stelle und hier liegt mein Problem - also müsste ich zusätzlich für jede Zahl abfragen ob 1 oder mehr stellen und wenn ja, führende 0 und auf die 2. Stelle schreiben und wenn keine führende 0 dann auf die 1. Stelle schreiben?

Tobias

linux_80
25.12.2007, 15:12
erstmal ein Tipp für insider: :mrgreen:

Print^H^H^H^H^HLcd

Mit Lcd wird doch an der Stelle ausgegeben, an der der Cursor steht.
Deswegen einfach ein paar Lcd-Befehle hintereinander bzw. untereinander. Es muss ja nicht immer mit Locate die Position extra angegeben werden.

Es wäre auch mal gut in die Hilfe von Bascom zum LCD-Befehl zu schauen, da steht auch der entscheidende Tipp zu Print und LCD.

TobiasBlome
25.12.2007, 16:16
@linux_80
vielen dank das du als einziger hier mir vernünftig weitergeholfen hast. Aber ich habe es nun ander gelöst ;-) und nun geht es!

Uhr / Uhrzeit im richtigem Format: 00:00:00

für alle die das selbe Problem haben:
man braucht kein BCD format oder mit Stellen basteln - es geht ganz einfach!

mit dem Time Befehl:


Dim Sekunden As Byte , Minuten As Byte , Stunden As Byte
Dim Uhr As String * 8 'zum konvertieren in 00:00:00
Config Clock = Soft

Do
Uhr = Time(sekunden) 'konvertierung der Uhrzeit
Loop

'Uhr routiene über timer oder so abrufen
'oder für Spezies nur wenn sich der wert der Sekunde geändert hat
Print "Uhrzeit" ; Uhr
Cls 'Display löschen (IMMER ERST LCD LÖSCHEN UND DANN POSITION ANGEBEN!!!)
Locate 1 , 1
Lcd "Uhrzeit: " ; Uhr


Alle anderen können gerne mal suchen z.B.

www.google.de
oder in der Bascomhilfe
oder...