PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Programm Binäruhr



Baumschubser
29.05.2005, 10:50
Moin Moin,

ich habe mir ne Binäruhr auf eine 160x100mm Platine gebastelt und betreibe die Uhr mit einem AT Mega 8. Der Mega 8 steuert 3 450 ICs (dual Binär-Zähler), die wiederrum die LEDs direkt ansteuern.
Auf der Platine befinden sich zwei Taster. Der erste Taster hält auf Druck das normale Zählen an und wechselt bei weiterem Tastendruck von Stunden zu Minuten, von Minuten zu Sekunden, von Sekunden zum Normalbetrieb. Währenddessen kann man mit dem zweiten Taster die Uhr stellen.

Das Progamm, das ich schrieb, wirkt mir wesentlich zu lang und umständlich. Das liegt vielleicht daran, daß es mein erstes ist :)
Naja funktionieren tut es, aber zwei gefallen mir noch nicht:

Wenn die 1er-Sekundenanzeige den Wert 10 errreicht, muß Sie ja augenblicklich zurückgesetzt werden und die 10er Sekundenanzeige zählt um 1 hoch. Bei der 1er Anzeige ist für eine halbe Sekunde trotzdem die 10 zu erkennen.

Dann läuft die Uhr nicht genau auf 1Hz - ich habe ziemlich große Abweichungen, wenn ich das Ganze mit einer normalen Uhr vergleiche.
Ich nutze den internen 1Mhz Ozillator, der natürlich nicht genau 1Hz erreicht. Ich habe hier noch ein Uhrenquarz liegen, mit dem man die gewünschten 1Hz bestimmt realisieren kann - ich weiß nur noch nicht wie.

Ausserdem wäre es nicht schlecht, wenn das Programm automatisch zählt, wenn Taster, der zum Stellen benutzt wird, länger als beispielsweise 1 Sekunde gedrückt wird.

Ok jetzt zeig ich endlich den code (hoffentlich ausreichend kommentiert):



' ######################################
' ################## Binäruhr (groove version #####################
' ######################################


'Zuordnung Pins:

'Pin:
'28. PC5 - Taster Stellen
'6. PD4 - Taster Auswahl

'2. PD0 - Stunden2 Reset
'3. PD1 - Stunden2 Clock
'4. PD2 - Stunden1 Reset
'5. PD3 - Stunden1 Clock

'11. PD5 - Minuten2 Reset
'12. PD6 - Minuten2 Clock
'15. PB1 - Minuten1 Reset
'16. PB2 - Minuten1 Clock

'17. PB3 - Sekunden2 Reset
'18. PB4 - Sekunden2 Clock
'19. PB5 - Sekunden1 Reset
'23. PC0 - Sekunden1 Clock

$regfile = "m8def.dat"
$crystal = 1000000
Declare Sub Anhalten
Declare Sub Stellen

Ddrd = &B11101111
Portd = &B00010000
Ddrc = &B11011111
Portc = &B00100000
Ddrb = &B11111111
Portb = &B00000000

Dim S1 As Byte
Dim S2 As Byte
Dim M1 As Byte
Dim M2 As Byte
Dim H1 As Byte
Dim H2 As Byte
Dim X As Byte
Dim Y As Bit
Dim Stacht As Bit

S1 = 0
S2 = 0
M1 = 0
M2 = 0
H1 = 0
H2 = 0
X = 0
Y = 0
Stacht = 0

Do

Debounce Pind.4 , 0 , Anhalten , Sub 'entprellen
Debounce Pinc.5 , 0 , Stellen , Sub



'Start Reset:

If Stacht = 0 Then
Portd.0 = 1
Portd.2 = 1
Portd.5 = 1
Portb.1 = 1
Portb.3 = 1
Portb.5 = 1
Waitms 20
Portd.0 = 0
Portd.2 = 0
Portd.5 = 0
Portb.1 = 0
Portb.3 = 0
Portb.5 = 0
Stacht = 1
Else
End If

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

'Startbedingungen:

Select Case X
Case 0:
Goto Normal
Case 1 To 3:
Goto Stellmodus
Case 4:
X = 0
Goto Ende
Case Else
End Select

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

'Normalbetrieb:

Normal:

'Sekunden:

Waitms 500
Portb.4 = 1
Waitms 500
Portb.4 = 0 'takt jede sekunde
S2 = S2 + 1

If S2 = 10 Then 'wenn s2 = 10 dann reset sek2, set sek1
S1 = S1 + 1
S2 = 0
Portb.3 = 1
Portc.0 = 1
Waitms 10
Portb.3 = 0
Portc.0 = 0
Else
End If

'Minuten:

If S1 = 6 Then 'wenn sek1 = 6 dann reset sek1, set min2
M2 = M2 + 1
S1 = 0
Portb.5 = 1
Portd.6 = 1
Waitms 10
Portb.5 = 0
Portd.6 = 0
Else
End If

If M2 = 10 Then 'wenn min2 = 10 dann reset min2, set min1
M1 = M1 + 1
M2 = 0
Portd.5 = 1
Portb.2 = 1
Waitms 10
Portd.5 = 0
Portb.2 = 0
Else
End If

'Stunden:

If M1 = 6 Then 'wenn min1 = 6 dann reset min1, set h2
H2 = H2 + 1
M1 = 0
Portb.1 = 1
Portd.1 = 1
Waitms 10
Portb.1 = 0
Portd.1 = 0
Else
End If

If H2 = 10 Then 'wenn h2 = 10 dann reset h2, set h1
H1 = H1 + 1
H2 = 0
Portd.0 = 1
Portd.3 = 1
Waitms 10
Portd.0 = 0
Portd.3 = 0
Else
End If

If H1 = 2 And H2 = 4 Then 'wenn h1 = 2 und h2 = 4 dann reset h1,h2
H1 = 0
H2 = 0
Portd.2 = 1
Portd.0 = 1
Waitms 500
Portd.2 = 0
Portd.0 = 0
Else
End If
Goto Ende

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

'Uhrzeit einstellen:

Stellmodus:

'Stunden:

If X = 1 And Y = 1 Then 'wenn x=1 und taster gedrückt dann takt
H2 = H2 + 1
Portd.1 = 1
Waitms 10
Portd.1 = 0
Y = 0
Else
End If

If H2 = 10 Then 'wenn h2 = 10 dann reset h2, set h1
H1 = H1 + 1
H2 = 0
Portd.0 = 1
Portd.3 = 1
Waitms 10
Portd.0 = 0
Portd.3 = 0
Else
End If

If H1 = 2 And H2 = 4 Then 'wenn h1 = 2 und h2 = 4 dann reset h1,h2
H1 = 0
H2 = 0
Portd.2 = 1
Portd.0 = 1
Waitms 10
Portd.2 = 0
Portd.0 = 0
Else
End If

'Minuten:

If X = 2 And Y = 1 Then 'wenn x=2 und taster gedrückt dann takt
M2 = M2 + 1
Portd.6 = 1
Waitms 10
Portd.6 = 0
Y = 0
Else
End If

If M2 = 10 Then 'wenn min2 = 10 dann reset min2, set min1
M1 = M1 + 1
M2 = 0
Portd.5 = 1
Portb.2 = 1
Waitms 10
Portd.5 = 0
Portb.2 = 0
Else
End If

If M1 = 6 Then 'wenn min1 = 6 dann reset min1
M1 = 0
Portb.1 = 1
Waitms 10
Portb.1 = 0
Else
End If

'Sekunden:

If X = 3 And Y = 1 Then
Portb.4 = 1
Waitms 20
Portb.4 = 0 'sekundentakt auf tastendruck
S2 = S2 + 1
Y = 0
Else
End If

If S2 = 10 Then 'wenn s1 = 10 dann reset sek2, set sek1
S1 = S1 + 1
S2 = 0
Portb.3 = 1
Portc.0 = 1
Waitms 10
Portb.3 = 0
Portc.0 = 0
Else
End If

If S1 = 6 Then 'wenn sek1 = 6 dann reset sek1
S1 = 0
Portb.5 = 1
Waitms 10
Portb.5 = 0
Else
End If

'Ende:

Ende:
Loop

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

'Unterprogramme:

Sub Anhalten
X = X + 1
End Sub

Sub Stellen
Y = 1
End Sub

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

End

Anbei noch die .bas Datei für Bascom.
Ich würde mich freuen, wenn sich jemand das Programm mal anschauen könnte und mir ein paar Verbesserungsvorschläge geben kann.

Mfg Baumschubser

uwegw
29.05.2005, 11:25
die abweichung scheint nicht weitwer verwunderlich. du erzeugst den takt mit 2xwaitms 500, aber lässt dazwischen imemr noch die anzeige multiplexen, wodurch ein haufen zeit draufgeht. dadurch dauert die gesamte programmschleife natürlich länger als eine sekunde, und dieser fehler summiert sich dann.

eine möglichkeit wäre, den haupttakt durch einen timerinterrupt erzeugen zu lassen, in dem dann die zeiten hochgezählt und die anzeigen geschaltet werden...

Baumschubser
30.05.2005, 19:35
Ich probiere grade mit Timer2 über ein externes Uhrenquarz (32767Hz) einen Interrupt zu erzeugen - leider vergblich.

Nach dem folgenden Code soll meine LED an PB4 im 1Hz Takt blinken, es tut sich aber gar nichts.



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

On Timer2 Takt


Ddrb = &B11111111
Portb = &B00000000

Assr.as2 = 1 'asynchroner Betrieb
Tccr2 = &B00000100 'Takt: 32768Hz/64=512Hz (2Hz, da 8bit-Timer 0-255 - Overflow bei 255)
Timsk.toie2 = 1 'Timer2 Overflow-Interrupt einschalten
Sreg.7 = 1 'Interrupts freischalten

Waitms 1000

Do

Loop

Takt:
Portb.4 = Not Portb.4
Return

End

BlooD
07.09.2005, 22:30
Und schon weiter?
Ich wollte demnächst auch ne Uhr bauen, werd aber wahrscheinlich nen DS1307 verwenden (RTC, gepuffert mit 3V-Batterie, über I2C auslesbar)

Was genau sind die 450? Kannst mal ne Bestellnummer bei z.B. Reichelt sagen?

Baumschubser
08.09.2005, 19:46
Hi,

das Programm habe mal fertig geschrieben - leider kam ich nicht auf genau 1Hz. Das liegt aber nicht am Quarz sondern an meinen Programmierkünsten. Ich habe mich zwischenzeitlich einem anderen Projekt gewidmet.
Ich hab mich mit dem 450 verschrieben - es ist der 4520 dual Binärzähler.
Die Reichelt Bestellnummer ist MOS 4520...das Datenblatt dazu müsste auch bei Reichelt zu finden sein.

Mfg Baumschubser