- fchao-Sinus-Wechselrichter AliExpress         
Ergebnis 1 bis 3 von 3

Thema: Quick und Dirty Pong-Spiel auf einem KS0108-GrafikLCD

  1. #1
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638

    Quick und Dirty Pong-Spiel auf einem KS0108-GrafikLCD

    Anzeige

    Praxistest und DIY Projekte
    Um mich etwas in ein KS0108-GLCD einzuarbeiten entstand aus einer "Drauf-los-Programmiererei" ein kleines Pong-Spiel.

    Der Hintergrund dazu: Eigentlich wird aus der ganzen Sache mal ein Datenlogger mit USB-Stick, da ich aber bisher nur T6963C-Displays verwendet habe und dieses Projekt erstmal ein KS0108-GLCD verwendet habe ich mich mal in der Ansteuerung versucht. Grundsätzlich besitzt dieses Display einige Tücken. So muss zum Beispiel ein Grafik-Befehl in einem Rutsch ausgeführt werden und darf keinesfalls unterbrochen werden (z. B. durch einen Interrupt). Während das T6963C-Display bei Unterbrechung gemütlich gewartet hat, bis der Befehl vollständig übertragen wurde, führt das KS0108 den angebrochenen Befehl sofort aus - mit interessanten Folgen. Anschließend stimmt nichts mehr und jeder darauffolgende Befehl wird völlig falsch ausgeführt. Ebenfalls tödlich ist das Beschreiben außerhalb der Display-Position: Das T6963C-Display hat den Befehl dann einfach ignoriert während das KS0108-Display quasi überläuft und eine exestierende Position nimmt, ähnlich wie wenn man einer Bytevariable mit dem Wert null den Wert eins abzieht, was den Wert 255 als Ergebnis liefert.

    Zum Programm: Es ist eine Quick'n'Dirty-Lösung, die rein aus dem Bauch heraus entstand. Wenn ich mich dazu motivieren kann werde ich den Code vielleicht noch umschreiben und erweitern, damit was schönes dabei rauskommt. Trotzdem funktioniert die Sache bereits tadellos.
    Wird der Ball mit dem Schläger getroffen gibt es einen Punkt, verfehlt man den Ball wird ein Punkt abgezogen. Weniger wie null Punkte gibts nicht.

    Vielleicht hat ja jemand Spaß daran und entwickelt es weiter oder spielt einfach nur ein paar Runden.

    Code:
    '#########
    '## EDT ##
    '#########
    '---------
    'KS0108-Ansteuerung
    'V1.0
    '07.10.2012
    'BASCOM 2.0.7.5
    '---------
    'schaltplan_ks0108ans_v1_0.dsn
    '---------
    'DEMO- und Testprogramm zur Ansteuerung eines GLCDs mit KS0108-Controller.
    'Mit optional angeschlossenen Tastern an Pind.0 und Pind.1 kann das Spiel gespielt werden.
    '---------
    
    
    $regfile = "m32def.dat"                                     'AtMega32
    $crystal = 1000000                                          '1Mhz
    $hwstack = 32                                               'nicht optimiert
    $swstack = 8                                                'nicht optimiert
    $framesize = 32                                             'nicht optimiert
    
    
    Config Pind.0 = Input
    Config Pind.1 = Input
    Config Pind.2 = Input
    Config Pind.3 = Input
    Portd.0 = 1
    Portd.1 = 1
    Portd.2 = 1
    Portd.3 = 1
    
    'KONFIGURATION TIMER0
    Config Timer0 = Timer , Prescale = 256                      '65,5ms
    On Timer0 Isr_timer0
    Enable Timer0
    Start Timer0
    
    'VARIABLEN
    Dim X As Byte                                               'X-Pos. des Balls
    Dim Y As Byte                                               'Y-Pos. des Balls
    Dim X_dir As Bit                                            'Horizontale Laufrichtung 1=rechts, 0=links
    Dim Y_dir As Bit                                            'Vertikale Laufrichtung 1=unten, 0=oben
    Dim X_bar As Byte                                           'X-Position des Schlägers (linkes Ende)
    Dim X_bar_offset As Byte                                    'X-Position des Schlägers (rechtes Ende)
    Dim X_bar_temp As Byte                                      'Schlägerposition zum Rechnen
    Dim Y_bar As Byte                                           'Y-Postion des Schlägers
    Dim Point As Byte                                           'Punktestand
    Dim Timer_flag As Bit                                       'Timer Flag
    Dim I As Byte                                               'Indexvariable für For-Schleife
    
    'INITIALISIEREN DER VARIABLEN
    X = 20                                                      'X-Pos. des Balls am Start
    Y = 20                                                      'Y-Pos. des Balls am Start
    Y_bar = 60                                                  'X-Pos. des Schlägers am Start
    X_bar = 20                                                  'Y_Pos. des Schlägers
    
    
    $lib "glcdKS108.lbx"                                        'Lib für das Display
    
    Config Graphlcd = 128 * 64sed , Dataport = Portc , Controlport = Porta , Ce = 4 , Ce2 = 3 , Cd = 0 , Rd = 1 , Reset = 5 , Enable = 2
    Cls                                                         'LCD-löschen
    
    Setfont My6_8
    
    Lcdat 1 , 1 , "GLCD-DEMO" , 0
    Lcdat 2 , 1 , "----------" , 0
    Lcdat 4 , 1 , "KS0108-GLCD 128x64" , 0
    Lcdat 5 , 1 , "AtMega32 @1Mhz" , 0
    Lcdat 6 , 1 , "EDT 2012" , 0
    Wait 1
    Cls
    
    Enable Interrupts
    
    '### HAUPTSCHLEIFE ###
    Do
    
       If Timer_flag = 1 Then
          Pset X , Y , 0                                        'Ball löschen
          If X_dir = 1 Then Incr X Else Decr X                  'Ballbewegung X-Ache
          If Y_dir = 1 Then Incr Y Else Decr Y                  'Ballbewegung Y-Achse
          If X = 127 Then X_dir = 0                             'Richtungswechsel X-Achse
          If Y = 63 Then                                        'Verzweigung wenn Ball am unteren Spielrand
             Y_dir = 0                                          'Richtungswechsel Y-Achse
             If Point > 0 Then Decr Point                       'Punktestand dekrementieren
          End If
          If X = 1 Then X_dir = 1                               'Richtungswechsel X-Achse
          If Y = 1 Then Y_dir = 1                               'Richtungswechsel Y-Achse
          X_bar_temp = X_bar                                    'Temporäre Variable zum Rechnen mit der aktuellen Schlägerpos. füllen
          For I = 1 To 10                                       'For-Schleife mit 10 Durchläufen
             If Y = 60 And X = X_bar_temp And Y_dir = 1 Then    'Abfrage ob Ball die Schlägerposition erreicht hat
                Incr Point                                      'wenn ja, Punktestand inkrementieren
                Toggle Y_dir                                    'und Richtungswechsel Y-Achse
             End If
             Incr X_bar_temp                                    'Temporäre Variable mit Schlägerposition um eins erhöhen
          Next
          Pset X , Y , 1                                        'Ball zeichnen
    
          If Pind.0 = 0 Then
             X_bar_offset = X_bar + 10
             Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 0    'Schläger löschen
             If X_bar > 10 Then Decr X_bar                      'Schlägerposition dekrementieren
             X_bar_offset = X_bar + 10                          'Rechtes Schlägerende neu berechnen
             Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 1    'Schläger zeichnen
          End If
    
          If Pind.1 = 0 Then
             X_bar_offset = X_bar + 10
             Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 0
             If X_bar < 100 Then Incr X_bar
             X_bar_offset = X_bar + 10
             Line(x_bar , Y_bar) -(x_bar_offset , Y_bar) , 1
          End If
    
          Lcdat 1 , 1 , Point , 0                               'Punktestand zeichnen
    
          Reset Timer_flag
       End If
    
    Loop
    
    '### ISR ###
    Isr_timer0:
    
       Set Timer_flag
    
    Return
    
    
    End
    
    $include "my6_8.font"
    Grüße
    Thomas

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    16.02.2006
    Beiträge
    1.113
    Hallo Thomas,
    solange dein Programm genau so aussieht, ist es vollkommen überflüssig, die Zeit in einem Timer Interrupt zu verschwenden. Da du nichts anderes machst, als das Flag zu setzen, das du dann in der Hauptschleife wieder abfragst, kannst du auch gleich das Interrupt Flag des Timers abfragen.
    Die Schleife würde dann so aussehen:
    Code:
    Do
       If TIFR.TOV0 = 1
       ...
       Set TIFR.TOV0
    Loop
    Das ändert an dem Ablauf nichts, nur hast du die Zeit zum Aufruf und Verlassen der ISR gespart.
    Damit kann dann auch kein Interrrupt deine LCD Kommandos unterbrechen.
    Ist allerdings dann nicht mehr so leicht übertragbar auf andere Hardware, weil dort die Register evtl. anders heißen.

  3. #3
    Erfahrener Benutzer Roboter Experte Avatar von Thomas E.
    Registriert seit
    29.12.2011
    Beiträge
    638
    Hallo for_ro!


    Danke für deinen Hinweis. An diese Variante habe ich gar nicht gedacht.
    Grüße
    Thomas

Ähnliche Themen

  1. GrafikLCD Menü
    Von Gaschue im Forum C - Programmierung (GCC u.a.)
    Antworten: 0
    Letzter Beitrag: 12.01.2011, 21:42
  2. Spiel Ping Pong bei Conrad mit Mega8 & 120LEDs
    Von chr-mt im Forum AVR Hardwarethemen
    Antworten: 9
    Letzter Beitrag: 08.08.2010, 20:19
  3. Quick&Dirty Geräuschgenerator, laut, Schussgeräusch
    Von loonquawl im Forum Elektronik
    Antworten: 5
    Letzter Beitrag: 25.06.2009, 13:52
  4. AMP Quick Connector
    Von bow.town im Forum Konstruktion/CAD/3D-Druck/Sketchup und Platinenlayout Eagle & Fritzing u.a.
    Antworten: 0
    Letzter Beitrag: 14.04.2008, 11:18
  5. Neigungssensor quick and dirty
    Von ritzdank im Forum Sensoren / Sensorik
    Antworten: 0
    Letzter Beitrag: 14.12.2006, 02:49

Stichworte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests