Larzarus
30.12.2007, 14:12
Hallo,
hier im nachfolgenden Programm wird eine Zeit eingestellt die rückwärts läuft.
Bei null wird in eine Subroutine gesprungen und dort soll später ein servo angesteuert werden.
Danach wird die Uhr wieder von vorne laufen gelassen.
Und das im Loop.
Das problem ist nur wenn die Uhr ca. 5-10 mal durchgelaufen ist erscheinen auf dem LCD, komische zeichen.
00:00:01
M00:00:0013 so in der art
Dann dauert es noch 3-5 durchläufe und der Controller macht einen Reset.
Leider weiß ich nicht weiter und finde den Fehler nicht.
MFG
$regfile = "m8def.dat" 'Controller : ATMEGA8 (Atmel)
$crystal = 7372800 '@ 7.2738 MHz
Setclock Alias Pinb.1 'Button 1
H Alias Pinb.2 'Button 2
M Alias Pinb.3 'Button 3
S Alias Pinb.4 'Button 4
Config Lcd = 16 * 2 '20 x 4 (Spalten x Zeilen)
'Config Lcdpin = Pin , E = Portb.5 , Rs = Portb.0 , Db7 = Portb.4 , Db6 = Portb.3 , Db5 = Portb.2 , Db4 = Portb.1
Config Lcdpin = Pin , E = Portb.0 , Rs = Portb.1 , Db7 = Portb.5 , Db6 = Portb.4 , Db5 = Portb.3 , Db4 = Portb.2 'Belegung am MEGA8
Config Lcdbus = 4 '4-Bit Bus
Config Lcdmode = Port '4-Bit Bus
Config Portb = Output 'Portb in Ausgabe Modus (Display)
Cls 'RAM des Displays selektieren
Portb = 63 'Pullups von Portb anschalten
Config Timer1 = Timer , Prescale = 1 'Timer1 konfigurieren
On Timer1 Timer1_isr 'Bei Überlauf in ISR springen
Enable Interrupts 'Timer1 ist ein Interrupt also Interrupts einschalten
Const Inter1 = 500 '1.Intervall für hochzählen
Const Inter2 = 250 '2.Intervall für hochzählen
Const Hi = 4 'Konstante zum Einstellen der Umschaltzeit des Intervalls
Const Mi = 9 'Konstante zum Einstellen der Umschaltzeit des Intervalls
Const Si = 9 'Konstante zum Einstellen der Umschaltzeit des Intervalls
Dim Intervall As Word 'Intervallzeit für hochzählen
Dim Mseconds As Word 'Millisekunden
Dim Seconds As Byte 'Sekunden
Dim Seconds1 As Byte
Dim Minutes As Byte
Dim Minutes1 As Byte 'Minuten
Dim Hours As Byte
Dim Hours1 As Byte 'Stunden
Dim Temp As Byte 'Zusätzliche Variable für das Umschalten des Intervalls
Dim Flag1 As Boolean 'Flag für den Spezialfall sek=9..0 (s.u.)
Dim Setbutton As Boolean '1.Button
Dim Hb As Boolean '2.Button
Dim Mb As Boolean '3.Button
Dim Sb As Boolean '4.Button
'+--------------+
'|Initialisieren|
'+--------------+
Do 'DO-Schleife (Anfang)
Locate 1 , 1 'Spalte 1 und Zeile 1 des Displays
Lcd "Bitte Einstellen!" 'Displayausgabe für den Benutzer
Waitms 50 '50 Millisekunden Warten um Flimmern zu vermeiden
Gosub Buttons 'zur Subroutine für die Buttonabfage springen
Cls 'Display löschen
Loop Until Setbutton = 1 'DO-Schleife (Ende wenn Button 1 gedrückt)
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds 'Anzeige: 0:0:0
'+----------+
'|Einstellen|
'+----------+
Do
'+-------+
'|Stunden|
'+-------+
Gosub Buttons 'Buttonabfrage
Intervall = Inter1 'Erstes Intervall auswählen (lang)
While Hb = 1 And Setbutton = 1 'Wenn beide Buttons gedrückt, dann folgendes ausführen
Incr Hours 'Stunden erhöhen
Incr Temp 'Temporäres Byte erhöhen, wichtig für die Intervallumschaltung
If Temp > Hi Then Intervall = Inter2 'Intervallumschaltung
If Hours > 23 Then Hours = 0 'Nach 23 wieder auf 0 springen
Locate 1 , 1 'Display: 1.Spalte, 1.Zeile
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds 'Aktuelle eingestellte Zeit anzeigen
Waitms Intervall 'Das Intervall abwarten
Gosub Buttons 'Buttonabfrage
Wend 'Ende der Schleife
'+-------+
'|Minuten|
'+-------+
Gosub Buttons
Intervall = Inter1
While Mb = 1 And Setbutton = 1
Incr Minutes
If Minutes > Mi Then Intervall = Inter2
If Minutes > 59 Then Minutes = 0
Locate 1 , 1
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds
Waitms Intervall
Gosub Buttons
Wend
'+--------+
'|Sekunden|
'+--------+
Gosub Buttons
Intervall = Inter1
While Sb = 1 And Setbutton = 1
Incr Seconds
If Seconds > Si Then Intervall = Inter2
If Seconds > 59 Then Seconds = 0
Locate 1 , 1
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds
Waitms Intervall
Gosub Buttons
Wend
Gosub Buttons
Loop Until Setbutton = 0 'Ende der Schleife
'+------------+
'|Startabfrage|
'+------------+
Do
Locate 1 , 1 'Display: 1.Spalte, 1.Zeile
Lcd "Bitte starten!" 'Ausgabe für Benutzer
Waitms 50 'Flimmern vermeiden
Gosub Buttons 'Buttonabfrage
Loop Until Setbutton = 1 'Dies solange ausführen bis Startknopf gedrückt
Seconds1 = Seconds
Minutes1 = Minutes
Hours1 = Hours
'+-----+
'|Start|
'+-----+
Wiederholung:
Seconds = Seconds1
Minutes = Minutes1
Hours = Hours1
Cls 'Display: löschen
Enable Timer1 'Timer1 erst hier starten, da sonst die 1 Sekunde nicht richtig gezählt wird
Do
'+-------------+
'|Millisekunden|
'+-------------+
If Mseconds >= 1000 Then
Decr Seconds
Mseconds = 0
End If
'+-----------+
'|Spezialfall|
'+-----------+
If Seconds = 9 Then
If Flag1 = 0 Then
Cls
Flag1 = 1
End If
End If
'+--------+
'|Sekunden|
'+--------+
If Seconds = 255 Then
Decr Minutes
Seconds = 59
Flag1 = 0
End If
'+-------+
'|Minuten|
'+-------+
If Minutes = 255 Then
Decr Hours
Minutes = 59
End If
'+-------+
'|Stunden|
'+-------+
If Hours = 255 Then
Hours = 23
Minutes = 59
Seconds = 59
End If
'+--------------------------+
'|Anzeige der Aktuellen Zeit|
'| führende Nullen anzeigen |
'+--------------------------+
Locate 1 , 1
If Hours > 9 Then Lcd Hours
If Hours < 10 Then Lcd "0" ; Hours
Lcd ":"
If Minutes > 9 Then Lcd Minutes
If Minutes < 10 Then Lcd "0" ; Minutes
Lcd ":"
If Seconds > 9 Then Lcd Seconds
If Seconds < 10 Then Lcd "0" ; Seconds
If Hours = 0 And Minutes = 0 And Seconds = 0 Then Gosub Fertig 'Wenn Timervorgang beendet, dann in Subroutine springen
Loop
'+-----------+
'|Subroutinen|
'+-----------+
Timer1_isr: 'Interrupt Service Routine für den Timer1
Timer1 = 59000 'Reloadwert ~ 59000
Mseconds = Mseconds + 1 'Millisekunden erhöhen...
Return '...und zurückspringen
'+---------------------------------+
'|Subroutinen für die Buttonabfrage|
'+---------------------------------+
Setc1:
Setbutton = 1
Return
Hours1:
Hb = 1
Return
Minutes1:
Mb = 1
Return
Seconds1:
Sb = 1
Return
'-------------------------------------------------
Setc2:
Setbutton = 0
Return
Hours2:
Hb = 0
Return
Minutes2:
Mb = 0
Return
Seconds2:
Sb = 0
Return
'+-------------------------------------------------+
'|Buttonabfrage mit Software-Entprellung der Tasten|
'+-------------------------------------------------+
Buttons:
Config Portb = Input
Portb = 63
Debounce Setclock , 0 , Setc1 , Sub
Debounce H , 0 , Hours1 , Sub
Debounce M , 0 , Minutes1 , Sub
Debounce S , 0 , Seconds1 , Sub
'-----------------------------------------------
Debounce Setclock , 1 , Setc2 , Sub
Debounce H , 1 , Hours2 , Sub
Debounce M , 1 , Minutes2 , Sub
Debounce S , 1 , Seconds2 , Sub
Config Portb = Output
Return
'+-------------------------------------------------------------+
'|Subroutine wird ausgeführt, wenn der Timervorgang beendet ist|
'+-------------------------------------------------------------+
Fertig:
Cls
Goto Wiederholung
Return
hier im nachfolgenden Programm wird eine Zeit eingestellt die rückwärts läuft.
Bei null wird in eine Subroutine gesprungen und dort soll später ein servo angesteuert werden.
Danach wird die Uhr wieder von vorne laufen gelassen.
Und das im Loop.
Das problem ist nur wenn die Uhr ca. 5-10 mal durchgelaufen ist erscheinen auf dem LCD, komische zeichen.
00:00:01
M00:00:0013 so in der art
Dann dauert es noch 3-5 durchläufe und der Controller macht einen Reset.
Leider weiß ich nicht weiter und finde den Fehler nicht.
MFG
$regfile = "m8def.dat" 'Controller : ATMEGA8 (Atmel)
$crystal = 7372800 '@ 7.2738 MHz
Setclock Alias Pinb.1 'Button 1
H Alias Pinb.2 'Button 2
M Alias Pinb.3 'Button 3
S Alias Pinb.4 'Button 4
Config Lcd = 16 * 2 '20 x 4 (Spalten x Zeilen)
'Config Lcdpin = Pin , E = Portb.5 , Rs = Portb.0 , Db7 = Portb.4 , Db6 = Portb.3 , Db5 = Portb.2 , Db4 = Portb.1
Config Lcdpin = Pin , E = Portb.0 , Rs = Portb.1 , Db7 = Portb.5 , Db6 = Portb.4 , Db5 = Portb.3 , Db4 = Portb.2 'Belegung am MEGA8
Config Lcdbus = 4 '4-Bit Bus
Config Lcdmode = Port '4-Bit Bus
Config Portb = Output 'Portb in Ausgabe Modus (Display)
Cls 'RAM des Displays selektieren
Portb = 63 'Pullups von Portb anschalten
Config Timer1 = Timer , Prescale = 1 'Timer1 konfigurieren
On Timer1 Timer1_isr 'Bei Überlauf in ISR springen
Enable Interrupts 'Timer1 ist ein Interrupt also Interrupts einschalten
Const Inter1 = 500 '1.Intervall für hochzählen
Const Inter2 = 250 '2.Intervall für hochzählen
Const Hi = 4 'Konstante zum Einstellen der Umschaltzeit des Intervalls
Const Mi = 9 'Konstante zum Einstellen der Umschaltzeit des Intervalls
Const Si = 9 'Konstante zum Einstellen der Umschaltzeit des Intervalls
Dim Intervall As Word 'Intervallzeit für hochzählen
Dim Mseconds As Word 'Millisekunden
Dim Seconds As Byte 'Sekunden
Dim Seconds1 As Byte
Dim Minutes As Byte
Dim Minutes1 As Byte 'Minuten
Dim Hours As Byte
Dim Hours1 As Byte 'Stunden
Dim Temp As Byte 'Zusätzliche Variable für das Umschalten des Intervalls
Dim Flag1 As Boolean 'Flag für den Spezialfall sek=9..0 (s.u.)
Dim Setbutton As Boolean '1.Button
Dim Hb As Boolean '2.Button
Dim Mb As Boolean '3.Button
Dim Sb As Boolean '4.Button
'+--------------+
'|Initialisieren|
'+--------------+
Do 'DO-Schleife (Anfang)
Locate 1 , 1 'Spalte 1 und Zeile 1 des Displays
Lcd "Bitte Einstellen!" 'Displayausgabe für den Benutzer
Waitms 50 '50 Millisekunden Warten um Flimmern zu vermeiden
Gosub Buttons 'zur Subroutine für die Buttonabfage springen
Cls 'Display löschen
Loop Until Setbutton = 1 'DO-Schleife (Ende wenn Button 1 gedrückt)
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds 'Anzeige: 0:0:0
'+----------+
'|Einstellen|
'+----------+
Do
'+-------+
'|Stunden|
'+-------+
Gosub Buttons 'Buttonabfrage
Intervall = Inter1 'Erstes Intervall auswählen (lang)
While Hb = 1 And Setbutton = 1 'Wenn beide Buttons gedrückt, dann folgendes ausführen
Incr Hours 'Stunden erhöhen
Incr Temp 'Temporäres Byte erhöhen, wichtig für die Intervallumschaltung
If Temp > Hi Then Intervall = Inter2 'Intervallumschaltung
If Hours > 23 Then Hours = 0 'Nach 23 wieder auf 0 springen
Locate 1 , 1 'Display: 1.Spalte, 1.Zeile
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds 'Aktuelle eingestellte Zeit anzeigen
Waitms Intervall 'Das Intervall abwarten
Gosub Buttons 'Buttonabfrage
Wend 'Ende der Schleife
'+-------+
'|Minuten|
'+-------+
Gosub Buttons
Intervall = Inter1
While Mb = 1 And Setbutton = 1
Incr Minutes
If Minutes > Mi Then Intervall = Inter2
If Minutes > 59 Then Minutes = 0
Locate 1 , 1
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds
Waitms Intervall
Gosub Buttons
Wend
'+--------+
'|Sekunden|
'+--------+
Gosub Buttons
Intervall = Inter1
While Sb = 1 And Setbutton = 1
Incr Seconds
If Seconds > Si Then Intervall = Inter2
If Seconds > 59 Then Seconds = 0
Locate 1 , 1
Lcd Hours ; ":" ; Minutes ; ":" ; Seconds
Waitms Intervall
Gosub Buttons
Wend
Gosub Buttons
Loop Until Setbutton = 0 'Ende der Schleife
'+------------+
'|Startabfrage|
'+------------+
Do
Locate 1 , 1 'Display: 1.Spalte, 1.Zeile
Lcd "Bitte starten!" 'Ausgabe für Benutzer
Waitms 50 'Flimmern vermeiden
Gosub Buttons 'Buttonabfrage
Loop Until Setbutton = 1 'Dies solange ausführen bis Startknopf gedrückt
Seconds1 = Seconds
Minutes1 = Minutes
Hours1 = Hours
'+-----+
'|Start|
'+-----+
Wiederholung:
Seconds = Seconds1
Minutes = Minutes1
Hours = Hours1
Cls 'Display: löschen
Enable Timer1 'Timer1 erst hier starten, da sonst die 1 Sekunde nicht richtig gezählt wird
Do
'+-------------+
'|Millisekunden|
'+-------------+
If Mseconds >= 1000 Then
Decr Seconds
Mseconds = 0
End If
'+-----------+
'|Spezialfall|
'+-----------+
If Seconds = 9 Then
If Flag1 = 0 Then
Cls
Flag1 = 1
End If
End If
'+--------+
'|Sekunden|
'+--------+
If Seconds = 255 Then
Decr Minutes
Seconds = 59
Flag1 = 0
End If
'+-------+
'|Minuten|
'+-------+
If Minutes = 255 Then
Decr Hours
Minutes = 59
End If
'+-------+
'|Stunden|
'+-------+
If Hours = 255 Then
Hours = 23
Minutes = 59
Seconds = 59
End If
'+--------------------------+
'|Anzeige der Aktuellen Zeit|
'| führende Nullen anzeigen |
'+--------------------------+
Locate 1 , 1
If Hours > 9 Then Lcd Hours
If Hours < 10 Then Lcd "0" ; Hours
Lcd ":"
If Minutes > 9 Then Lcd Minutes
If Minutes < 10 Then Lcd "0" ; Minutes
Lcd ":"
If Seconds > 9 Then Lcd Seconds
If Seconds < 10 Then Lcd "0" ; Seconds
If Hours = 0 And Minutes = 0 And Seconds = 0 Then Gosub Fertig 'Wenn Timervorgang beendet, dann in Subroutine springen
Loop
'+-----------+
'|Subroutinen|
'+-----------+
Timer1_isr: 'Interrupt Service Routine für den Timer1
Timer1 = 59000 'Reloadwert ~ 59000
Mseconds = Mseconds + 1 'Millisekunden erhöhen...
Return '...und zurückspringen
'+---------------------------------+
'|Subroutinen für die Buttonabfrage|
'+---------------------------------+
Setc1:
Setbutton = 1
Return
Hours1:
Hb = 1
Return
Minutes1:
Mb = 1
Return
Seconds1:
Sb = 1
Return
'-------------------------------------------------
Setc2:
Setbutton = 0
Return
Hours2:
Hb = 0
Return
Minutes2:
Mb = 0
Return
Seconds2:
Sb = 0
Return
'+-------------------------------------------------+
'|Buttonabfrage mit Software-Entprellung der Tasten|
'+-------------------------------------------------+
Buttons:
Config Portb = Input
Portb = 63
Debounce Setclock , 0 , Setc1 , Sub
Debounce H , 0 , Hours1 , Sub
Debounce M , 0 , Minutes1 , Sub
Debounce S , 0 , Seconds1 , Sub
'-----------------------------------------------
Debounce Setclock , 1 , Setc2 , Sub
Debounce H , 1 , Hours2 , Sub
Debounce M , 1 , Minutes2 , Sub
Debounce S , 1 , Seconds2 , Sub
Config Portb = Output
Return
'+-------------------------------------------------------------+
'|Subroutine wird ausgeführt, wenn der Timervorgang beendet ist|
'+-------------------------------------------------------------+
Fertig:
Cls
Goto Wiederholung
Return