Pingpong-Nachbau mit PDIP28-Controller

Elektronik-Labor   Projekte   AVR 

 
Video: https://youtu.be/QP6gT_PwhN8

Wolfgang, DH3SW hat das Franzis PingPong-Spiel nachgebaut. Aus technischen Gründen wurde für den ATmega8 die Bauform Dip28 gewählt. Zunächst gab es ein Problem, weil die Pins für die Potis fehlten. 




Die Variante war für die Kinder gedacht, und die müssen ja nicht unbedingt spielen, sondern sie sollen löten und programmieren lernen.



Es wurde original immer nur die SMD-Version des Mega8 verwendet, der gemeinerweise noch ADC6 und 7 herausführt. Aber zum Glück ist ADC4 und 5 noch frei geblieben. Die folgende Anpassung funktioniert für diese beiden Eingänge:


PongPongFirmwareDIL.zip 

'12.7.09   final Version
'5.4.16: Änderung der Poti-Eingänge auf ADC4 und ADC5 wg. DIL-Version

$crystal = 8000000
$regfile = "m8def.dat"
$hwstack = 64
$swstack = 16
$framesize = 64

Config Portc = 15 'PORTC als AD-Eingang
Config Portb = Output
Config Portd = 255

Dim X(14) As Word
Dim W As Word
Dim D As Byte
Dim N As Byte
Dim Ticks As Byte

Dim Xgeschw As Integer
Dim Ygeschw As Integer
Dim Xpos As Byte
Dim Ypos As Byte
Dim Altpos As Byte

Dim Vh1 As Integer

Dim Ad0 As Word
Dim Ad0_mean As Word

Dim I As Byte
Dim Vhelp As Word
Dim Vhelp1 As Integer
'Dim Vhelp3 As Integer
Dim Dat As Integer
Dim Vy As Byte
Dim Col As Byte
Dim Portdout As Byte
Dim Portcout As Byte

'MENUE
Dim Mplaywahl As Bit
Dim Pl2c As Bit
Dim Pl1c As Bit
Dim Pl2c1 As Bit
Dim Pl2c2 As Bit
Dim Pl1c1 As Bit
Dim Pl1c2 As Bit
Dim Mdlauf As Word
Dim Mdlaufa As Byte
Dim Vtime As Byte
Dim Noadcpl2 As Bit
Dim Noadcpl1 As Bit
Dim Plst As Bit

Dim Level As Byte
Dim Vhlepl1 As Byte
Dim Levelpl1 As Byte
Dim Vhlepl2 As Byte
Dim Levelpl2 As Byte


Dim Ue As Integer
Dim E2 As Single
Dim U2 As Single
Dim U As Integer
Dim Ysch1 As Word
Dim Ysch1pos As Byte
Dim Vysch1pos As Byte
Dim Ysch2pos As Byte
Dim Vysch2pos As Byte
Dim Pupl1 As Byte
Dim Pupl2 As Byte
Dim Vhelp2 As Word
Dim Vhelp3 As Integer
Dim Y(10) As Word

Declare Sub Standby
Declare Sub Test

Config Timer2 = Timer , Prescale = 8

On Ovf2 Tim2_isr
Enable Timer2
Enable Interrupts
Config Int0 = Low Level 'Falling
On Int0 Int_isr


Start Timer2
Config Adc = Single , Prescaler = 64 , Reference = Off
Start Adc


Readeeprom I , 0
If I = 255 Then Test


Portc.4 = 1 'Pullup
'Testroutine
If Pinc.4 = 0 Then Test 'Test gestartet
'Test Ende


'Spielstart, Variablen auf Anfangswert
Spstart:
Pupl1 = 0
Pupl2 = 0
Pl2c = 1
Pl1c = 1
Pl2c1 = 0
Pl2c2 = 0
Pl1c1 = 0
Pl1c2 = 0
Mdlauf = 0
Mdlaufa = 0
Mplaywahl = 1 'zuerst Spieler auswählen
Vhlepl1 = 0
Vhlepl2 = 0
Levelpl1 = 0
Levelpl2 = 0
Level = 0

Do
Ypos = Rnd(6)
Ypos = Ypos + 2
Do
Vtime = Vtime + 1

'SCHLÄGERSTEUERUNG
'Schlager1
Ue = Getadc(4)
If Ue > 170 Then Ue = Ue - 170 Else Ue = 0
If Ue > 680 Then Ue = 680
Ue = Ue / 68
If Ue < 0 Then Ue = 0
If Ue > 8 Then Ue = 8
'Computer Spielt
If Mplaywahl = 0 And Pl1c = 0 Then
If Xgeschw <= 0 And Rnd(100) > 5 Then 'And Rnd(100) < 9
Vhelp3 = Ypos - Ysch1pos
If Vhelp3 > 1 Then Ue = Ysch1pos + 1
If Vhelp3 <= 0 And Ysch1pos > 0 Then Ue = Ysch1pos - 1
If Vhelp3 = 1 Then
Ue = E2
If Ygeschw = 0 And Xpos < 4 Then Ue = Ysch1pos -1
End If
Else
Ue = E2
End If
End If
If Ue < 0 Then Ue = 0
If Ue > 8 Then Ue = 8
'Ausgabe
E2 = Ue
Ysch1pos = Ue
Ue = 2 ^ Ue
Ysch1 = Ue
Ue = Ue * 2
Ysch1 = Ysch1 + Ue
X(1) = Ysch1

'Nur vor dem ersten Schalg: Spielerauswahl
If Mplaywahl = 1 Then
If Vhlepl1 = 0 Then If Ysch1pos > 4 Then Vhlepl1 = 1
If Vhlepl1 = 1 Then If Ysch1pos < 4 Then Vhlepl1 = 2
If Vhlepl1 = 2 Then
If Ysch1pos > 4 Then 'Levelerhöhen
Vhlepl1 = 1
Levelpl1 = Levelpl1 + 1
If Levelpl1 > Levelpl2 And Levelpl1 < 6 Then 'Levelanzeige
Vhelp1 = Levelpl1
Vhelp1 = 6 - Vhelp1
Vhelp1 = Vhelp1 * 2
Vhelp1 = Vhelp1 - 1
Vhelp3 = 2 ^ Vhelp1
X(5) = X(5) + Vhelp3
Vhelp1 = Vhelp1 - 1
Vhelp1 = 2 ^ Vhelp1
X(5) = X(5) + Vhelp1
X(6) = X(5)
End If
End If
End If
If Ysch1pos < 1 Then Pl1c = 0 Else Pl1c = 1
End If



'Schlager2
U = Getadc(5)
'U = 1024 - U
If U > 170 Then U = U - 170 Else U = 0
If U > 680 Then U = 680
U = U / 68
If U < 0 Then U = 0
If U > 8 Then U = 8
If Mplaywahl = 0 And Pl2c = 0 Then
If Xgeschw => 0 And Rnd(100) > 5 Then 'And Rnd(100) < 9
Vhelp3 = Ypos - Ysch2pos
If Vhelp3 > 1 Then U = Ysch2pos + 1
If Vhelp3 <= 0 And Ysch2pos > 0 Then U = Ysch2pos - 1
If Vhelp3 = 1 Then
U = U2
If Ygeschw = 0 And Xpos > 9 Then U = Ysch2pos -1
End If
Else
U = U2
End If
End If
If U < 0 Then U = 0
If U > 8 Then U = 8
U2 = U
Ysch2pos = U
U = 2 ^ U
Ysch1 = U
U = U * 2
Ysch1 = Ysch1 + U
X(12) = Ysch1

'Nur vor dem ersten Schalg: Spielerauswahl und: wer beginnt
If Mplaywahl = 1 Then
If Vhlepl2 = 0 Then If Ysch2pos > 4 Then Vhlepl2 = 1
If Vhlepl2 = 1 Then If Ysch2pos < 4 Then Vhlepl2 = 2
If Vhlepl2 = 2 Then
If Ysch2pos > 4 Then
Vhlepl2 = 1
Levelpl2 = Levelpl2 + 1
If Levelpl2 > Levelpl1 And Levelpl2 < 6 Then
Vhelp1 = Levelpl2
Vhelp1 = 6 - Vhelp1
Vhelp1 = Vhelp1 * 2
Vhelp1 = Vhelp1 - 1
Vhelp3 = 2 ^ Vhelp1
X(5) = X(5) + Vhelp3
Vhelp1 = Vhelp1 - 1
Vhelp1 = 2 ^ Vhelp1
X(5) = X(5) + Vhelp1
X(6) = X(5)
End If
End If
End If
If Ysch2pos < 1 Then Pl2c = 0 Else Pl2c = 1
If Ysch2pos > Ysch1pos Then Xpos = 11 Else Xpos = 2
End If

If Mplaywahl = 0 Then
'BALLSTEUERUNG:
Altpos = Xpos
Xpos = Xpos + Xgeschw
Ypos = Ypos + Ygeschw
X(altpos) = 0
Vhelp1 = 2 ^ Ypos
X(xpos) = X(xpos) Or Vhelp1

'Seite Player1
If Xpos = 2 Then
Vh1 = Ysch1pos - Ypos
If Vh1 >= -2 And Vh1 <= 1 Then
If Vh1 = 1 Then
If Ygeschw = 1 Then
Xgeschw = 1
If Rnd(100) > 50 Then Ygeschw = -1 Else Ygeschw = 0
Elseif Ygeschw = 0 Then
Xgeschw = 1
Ygeschw = -1
End If
End If
If Vh1 = 0 Then Xgeschw = 1 'And Ygeschw = -1
If Vh1 = -1 Then Xgeschw = 1
If Vh1 = -2 Then
If Ygeschw = -1 Then
Xgeschw = 1
If Rnd(100) > 50 Then Ygeschw = 1 Else Ygeschw = 0
Elseif Ygeschw = 0 Then
Xgeschw = 1
Ygeschw = 1
End If
End If
End If
End If

'Seite Player2
If Xpos = 11 Then
Vh1 = Ysch2pos - Ypos
If Vh1 >= -2 And Vh1 <= 1 Then
If Vh1 = 1 Then
If Ygeschw = 1 Then
Xgeschw = -1
If Rnd(100) > 50 Then Ygeschw = -1 Else Ygeschw = 0
Elseif Ygeschw = 0 Then
Xgeschw = -1
Ygeschw = -1
End If
End If
If Vh1 = 0 Then Xgeschw = -1 'And Ygeschw = -1
If Vh1 = -1 Then Xgeschw = -1
If Vh1 = -2 Then
If Ygeschw = -1 Then
Xgeschw = -1
If Rnd(100) > 50 Then Ygeschw = 1 Else Ygeschw = 0
Elseif Ygeschw = 0 Then
Xgeschw = -1
Ygeschw = 1
End If
End If
End If
End If

'GRENZEN & RICHTUNGSÄNDERUNG
If Xpos >= 12 Then
Wait 1
Goto Pout 'Aus! Punkteanzeige
End If
If Xpos <= 1 Then
Wait 1
Goto Pout 'Aus! Punkteanzeige
End If
If Ypos >= 9 Then Ygeschw = -1
If Ypos <= 0 Then Ygeschw = 1

'Geschwindigkeit
If Levelpl1 > Levelpl2 Then Level = Levelpl1 Else Level = Levelpl2
If Level < 2 Then Waitms 100
If Level = 2 Then Waitms 80
If Level = 3 Then Waitms 60
If Level = 4 Then Waitms 40
If Level > 4 Then Waitms 20
Else 'Spielerauswahl
Mdlauf = Mdlauf + 1
Mdlaufa = Mdlaufa + 1
If Mdlaufa => 11 Then Mdlaufa = 0
If Mdlaufa > 6 Then
If Pl1c = 0 Then X(1) = &B0000000000
If Pl2c = 0 Then X(12) = &B0000000000
Waitms 50
Else
Waitms 50
End If

If Mdlauf >= 70 Then 'Menudauer
Wait 1
X(5) = 0
X(6) = 0
If Pl1c = 0 And Pl2c = 0 Then Levelpl1 = Rnd(5) 'Computer spielt zufälliges level
Mplaywahl = 0
End If
End If
Loop

Pout:
X(1) = 0
X(12) = 0

If Xpos >= 12 Then
Xpos = Xpos - 1
Xgeschw = 0
Ygeschw = 0
If Pupl1 < 10 Then Pupl1 = Pupl1 + 1
End If
If Xpos <= 1 Then
Xpos = Xpos + 1
Xgeschw = 0
Ygeschw = 0
If Pupl2 < 10 Then Pupl2 = Pupl2 + 1
End If

Vh1 = 10 - Pupl1
Vh1 = 2 ^ Vh1
Vh1 = Vh1 - 1
Vh1 = 1023 - Vh1
If Vh1 > 0 Then X(1) = Vh1 Else X(1) = 0
Vh1 = 10 - Pupl2
Vh1 = 2 ^ Vh1
Vh1 = Vh1 - 1
Vh1 = 1023 - Vh1
If Vh1 > 0 Then X(12) = Vh1
If Pupl1 = 10 Then
Wait 3
Standby
Goto Spstart:
End If
If Pupl2 = 10 Then
Wait 3
Standby
Goto Spstart:
End If
Wait 1

Loop

Sub Standby
Stop Timer2
Portc = 0
Portd = 0
Portb = 0
Stop Adc
Portd.2 = 1
Ddrd.2 = 0
Waitms 1
Enable Int0
Waitms 1
Powerdown
Ddrd.2 = 1
Portd.2 = 0
Start Adc
Start Timer2
End Sub

Sub Test
For I = 1 To 12
X(i) = 1023
Next I
Waitms 1000
For U = 1 To 12
For I = 1 To 12
X(i) = 0
Next I
X(u) = 1023
Waitms 100
Next U
For U = 1 To 12
For I = 1 To 12
Vhelp = U - 1
Vhelp = 2 ^ Vhelp
X(i) = Vhelp
Next I
Waitms 100
Next U
For U = 1 To 12
X(u) = 0
Next U

I = 0
Writeeeprom I , 0

End Sub

Int_isr:
Disable Int0
Return


Tim2_isr:
'800 µs
'Timer2 = 56
Col = Col + 1
If Col = 13 Then Col = 1
Vy = Col + 0
Portd = 0
Portb = 0
Portc = 0
If Col = 1 Then Portb.4 = 0 Else Portb.4 = 1
Portb.3 = 1 'cl
Portb.3 = 0
Portb.2 = 1 'Str
Portb.2 = 0
Portdout = Low(x(vy))
Portcout = Portdout And 15
Portdout = Portdout And 240
Portd = Portdout
Portc = Portcout
Portb = High(x(vy))
'Waitms 500
Return
End



Elektronik-Labor   Projekte   AVR