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
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