<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="de">
		<id>https://rn-wissen.de/wiki/index.php?action=history&amp;feed=atom&amp;title=PS%2F2_-_Schnittstelle</id>
		<title>PS/2 - Schnittstelle - Versionsgeschichte</title>
		<link rel="self" type="application/atom+xml" href="https://rn-wissen.de/wiki/index.php?action=history&amp;feed=atom&amp;title=PS%2F2_-_Schnittstelle"/>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PS/2_-_Schnittstelle&amp;action=history"/>
		<updated>2026-04-11T15:14:56Z</updated>
		<subtitle>Versionsgeschichte dieser Seite in RN-Wissen.de</subtitle>
		<generator>MediaWiki 1.25.1</generator>

	<entry>
		<id>https://rn-wissen.de/wiki/index.php?title=PS/2_-_Schnittstelle&amp;diff=15843&amp;oldid=prev</id>
		<title>Screwdriver_alt: Interruptgesteuerte PS/2-Schnittstelle am AVR</title>
		<link rel="alternate" type="text/html" href="https://rn-wissen.de/wiki/index.php?title=PS/2_-_Schnittstelle&amp;diff=15843&amp;oldid=prev"/>
				<updated>2009-12-25T11:13:56Z</updated>
		
		<summary type="html">&lt;p&gt;Interruptgesteuerte PS/2-Schnittstelle am AVR&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Neue Seite&lt;/b&gt;&lt;/p&gt;&lt;div&gt;== Wissenswertes über die PS/2-Schnittstelle ==&lt;br /&gt;
Im WWW gibt es sehr viele Seiten, die sich mit der Schnittstelle und deren Protokoll befassen. Besonders empfehlen möchte ich folgende:&lt;br /&gt;
&lt;br /&gt;
*[http://www.marjorie.de/ps2/ps2_protocol.htm www.marjorie.de/ps2/ps2_protocol.htm]&lt;br /&gt;
*[http://www.uni-koblenz.de/~physik/informatik/ECC/ps2.pdf www.uni-koblenz.de/~physik/informatik/ECC/ps2.pdf]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Warum nicht die BASCOM-Funktionen GETATKBD() und GETATKBDRAW() benutzen? ==&lt;br /&gt;
&lt;br /&gt;
Die genannten Funktionen werden i.d.R. in der Hauptprogrammschleife eines BASCOM-Programms zyklisch aufgerufen. Da die Clockfrequenz der PS/2-Schnittstelle mit 10-16kHz arbeitet, muß ebenfalls mindestens in dieser Frequenz das Hauptprogramm abgearbeitet werden, ansonsten gehen Daten verloren. Das kann bei umfangreicheren Programmen schon mal zum Problem werden. Alternativ könnte man den AVR ja per Timer-Interrupt zwingen, die Funktionen GETATKBD() bzw. GETATKBDRAW() im o.g. Zeitraster auszuführen. Da die Übertragung eines Bytes jedoch bis zu 2ms dauern kann, ist für diese 2ms dann aber auch der AVR blockiert und andere Interrupts können erst anschließend ausgeführt werden. &lt;br /&gt;
Obwohl die PS/2-Schnittstelle eine bidirektionale ist, liefert BASCOM leider keine Funktion zum Senden eines Bytes an ein PS/2-Device, wie man es z.B. zur Ansteuerung der Tastatur-LED benötigt. Es müßte also sowieso etwas Programmentwicklung geleistet werden.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Hardware-Anschluss PS/2 ==&lt;br /&gt;
Das Schema zeigt ausschliessliche den Anschluss der PS/2-Schnittstelle, die Restbeschaltung ist den eigenen Bedürfnissen anzupassen. Das PS/2-Clock-Signal muss an einen externen Interrupt-Eingang (Int0, Int1, etc.) des AVR angeschlossen werden. Der verwendete Interrupteingang ist der Datei PS2_CONF.BAS dem Kompiler mitzuteilen. Der verwendete Interrupt (Int0, Int1, etc.) ist ebenfalls an verschiedenden Stellen in den Dateien PS2_CONF.BAS und PS2.BAS anzupassen.&lt;br /&gt;
&lt;br /&gt;
[[Bild:PS2-Anschluss.png ]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== BASCOM-Quellcode ==&lt;br /&gt;
Der Quellcode ist in die folgenden drei Dateien aufgeteilt:&lt;br /&gt;
{|&lt;br /&gt;
 |Hauptprogramm.bas&lt;br /&gt;
 |(Das zu kompilierende Hauptprogramm)&lt;br /&gt;
 |-&lt;br /&gt;
 |Ps2_Conf.bas&lt;br /&gt;
 |(Konfigurationsdatei)&lt;br /&gt;
 |-&lt;br /&gt;
 |Ps2.bas&lt;br /&gt;
 |(Programmdatei PS/2-Funktionen)&lt;br /&gt;
 |}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
=== Hauptprogramm.bas ===&lt;br /&gt;
Das Programmbeispiel zeigt bei Tastenbetätigung die Scancodes einer angeschlossenen PS/2-Tastatur in hexadezimaler Form auf einem Text-LCD an.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Demomonstration Anschluß PS/2 Tastatur an AVR                         ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Autor: screwdriver                                                    ***&lt;br /&gt;
'***   Datum: 25.12.2009                                                     ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Konfiguration                                                         ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Konfiguration AVR   *****************************************************&lt;br /&gt;
$regfile = &amp;quot;m16def.dat&amp;quot;&lt;br /&gt;
&lt;br /&gt;
$crystal = 16e6&lt;br /&gt;
&lt;br /&gt;
$hwstack = 64&lt;br /&gt;
$swstack = 64&lt;br /&gt;
$framesize = 64&lt;br /&gt;
&lt;br /&gt;
'***   Konfiguration LCD   *****************************************************&lt;br /&gt;
Config Lcdpin = Pin , Db4 = Portc.5 , Db5 = Portc.4 , Db6 = Portc.3 , Db7 = Portc.2 , E = Portc.6 , Rs = Portc.7&lt;br /&gt;
Config Lcd = 16 * 4&lt;br /&gt;
Cursor Off , Noblink&lt;br /&gt;
Cls&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Externe Dateien (Config)                                              ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
$include &amp;quot;PS2_Conf.bas&amp;quot;                      'Konfiguration PS/2 Tastatur&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Konstanten                                                            ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Variablen                                                             ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Dim Btemp As Byte                            'Allgemeine Byte-Variable&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   HAUPTPROGRAMM                                                         ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
&lt;br /&gt;
Call Ps2_init()                              'PS/2-Schnittstelle initialisieren&lt;br /&gt;
&lt;br /&gt;
Enable Interrupts                            'Globale Interruptfreigabe&lt;br /&gt;
&lt;br /&gt;
Do&lt;br /&gt;
&lt;br /&gt;
   If Ps2_count() &amp;lt;&amp;gt; 0 Then                  'Elemente in Ringpuffer vorhanden?&lt;br /&gt;
      Btemp = Ps2_buffer_read()              'Ein Element herrausnehmen..&lt;br /&gt;
      Lcd Hex(btemp) ; &amp;quot; &amp;quot;                   '..und auf LCD anzeigen&lt;br /&gt;
   End If&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Loop&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Externe Dateien (Programm)                                            ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
$include &amp;quot;PS2.bas&amp;quot;                           'Konfiguration PS/2 Tastatur&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ps2_Conf.bas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Konfigurationsdatei PS/2-Schnittstelle an AVR                         ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Autor: screwdriver                                                    ***&lt;br /&gt;
'***   Datum: 25.12.2009                                                     ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
$nocompile                                             'Include-Datei!&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Hardwarekonfiguration                                                 ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Ps2_clock Alias Pind.3                                 'PS/2-Clock (Eingang)&lt;br /&gt;
Ps2_clock_port Alias Portd.3                           'PS/2-Clock (Ausgang)&lt;br /&gt;
Ps2_data Alias Pind.4                                  'PS/2-Data (Eingang)&lt;br /&gt;
Ps2_data_port Alias Portd.4                            'PS/2-Data (Ausgang)&lt;br /&gt;
&lt;br /&gt;
Config Int1 = Falling                                  'PS/2-Clock auf Ext. Int1&lt;br /&gt;
On Int1 Isr_int1                                       'Sprungadresse Int1 festlegen&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Konstanten                                                            ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Const Ps2_buff_size = 8                                'Größe PS/2-Ringpuffer&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Variablen                                                             ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Dim Ps2_mode As Bit                                    '0: Host &amp;lt;- Device, 1: Host -&amp;gt; Device&lt;br /&gt;
Dim Ps2_state As Byte                                  'State-Counter PS/2 Kommunikation&lt;br /&gt;
Dim Ps2_parity As Byte                                 'Paritätszähler&lt;br /&gt;
Dim Ps2_byte As Byte                                   'Empfangenes bzw. Zusendendes Byte&lt;br /&gt;
&lt;br /&gt;
Dim Ps2_buffer(ps2_buff_size) As Byte                  'PS/2-Ring-Puffer&lt;br /&gt;
Dim Ps2_in_ptr As Byte                                 'Input-Pointer PS/2-Ring-Puffer (Schreiben)&lt;br /&gt;
Dim Ps2_out_ptr As Byte                                'Ouput-Pointer PS/2-Ring-Puffer (Auslesen)&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Deklaration Unterprogramme&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Declare Sub Ps2_init()                                 'Initialisierung PS/2 Schnittstelle&lt;br /&gt;
Declare Sub Ps2_buffer_write(byval Ps2data As Byte)    'Schreibt Element in PS/2-Ring-Puffer&lt;br /&gt;
Declare Function Ps2_buffer_read() As Byte             'Liest Element aus PS/2-Ring-Puffer&lt;br /&gt;
Declare Sub Ps2_sendbyte(byval Ps2_byte2send As Byte)  'Gibt ein Byte über PS/2-Schnittstelle aus&lt;br /&gt;
Declare Function Ps2_count()as Byte                    'Liefert aktuelle Anzahl Elemente im Ringpuffer&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Ps2.bas ===&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Programmdatei PS/2-Schnittstelle an AVR                               ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Autor: screwdriver                                                    ***&lt;br /&gt;
'***   Datum: 25.12.2009                                                     ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
$nocompile                                             'Include-Datei!&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Unterprogramme                                                        ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
&lt;br /&gt;
Sub Ps2_init()&lt;br /&gt;
   Config Ps2_clock_port = Input&lt;br /&gt;
   Config Ps2_data_port = Input&lt;br /&gt;
&lt;br /&gt;
   Ps2_mode = 0                                        'Transmission Device -&amp;gt; Host&lt;br /&gt;
   Ps2_state = 0                                       'Statemachine auf Anfang setzen&lt;br /&gt;
&lt;br /&gt;
   Ps2_in_ptr = 1                                      'Ring-Puffer &amp;quot;Schreiben&amp;quot; auf Anfang&lt;br /&gt;
   Ps2_out_ptr = 1                                     'Ring-Puffer &amp;quot;Lesen&amp;quot; auf Anfang&lt;br /&gt;
   Ps2_buffer(1) = 0                                   'Erstes Element Nullsetzen&lt;br /&gt;
&lt;br /&gt;
   Enable Int1                                         'Interruptfreigabe Int1&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Sub Ps2_buffer_write(byval Ps2data As Byte)&lt;br /&gt;
   Ps2_buffer(ps2_in_ptr) = Ps2data                    'Element in Ringpuffer schreiben&lt;br /&gt;
   If Ps2_in_ptr &amp;lt; Ps2_buff_size Then                  'Wenn Pufferende nicht erreicht,&lt;br /&gt;
      Ps2_in_ptr = Ps2_in_ptr + 1                      'PointerVar erhöhen&lt;br /&gt;
   Else                                                'sonst&lt;br /&gt;
      Ps2_in_ptr = 1                                   'PointerVar auf Anfang setzen&lt;br /&gt;
   End If&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Function Ps2_buffer_read() As Byte&lt;br /&gt;
   If Ps2_in_ptr &amp;lt;&amp;gt; Ps2_out_ptr Then                   'Wenn Elemente in Puffer vorhanden&lt;br /&gt;
      Ps2_buffer_read = Ps2_buffer(ps2_out_ptr)        'Element auslesen&lt;br /&gt;
      If Ps2_out_ptr &amp;lt; Ps2_buff_size Then              'Wenn Pufferende nicht erreicht,&lt;br /&gt;
         Ps2_out_ptr = Ps2_out_ptr + 1                 'PointerVar erhöhen&lt;br /&gt;
      Else                                             'sonst&lt;br /&gt;
         Ps2_out_ptr = 1                               'PointerVar auf Anfang setzen&lt;br /&gt;
      End If&lt;br /&gt;
   Else&lt;br /&gt;
      Ps2_buffer_read = 0                              'Keine Elemente im Puffer, Rückgabewert 0&lt;br /&gt;
   End If&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Sub Ps2_sendbyte(byval Ps2_byte2send As Byte)&lt;br /&gt;
   Disable Int1                                        'Interruptsperre Int1&lt;br /&gt;
&lt;br /&gt;
   Ps2_clock = 0                                       'Clock-Signal auf Low&lt;br /&gt;
   Config Ps2_clock_port = Output                      'Clock-Leitung als Ausgang&lt;br /&gt;
   Config Ps2_data_port = Input                        'Data-Leitung als Eingang&lt;br /&gt;
&lt;br /&gt;
   'Clock-Port für mind. 60µs auf Low halten&lt;br /&gt;
   'Waitus 20&lt;br /&gt;
   'Waitus 20&lt;br /&gt;
   'Waitus 20&lt;br /&gt;
&lt;br /&gt;
   Ps2_mode = 1                                        'Transmission Host -&amp;gt; Device&lt;br /&gt;
   Ps2_state = 0                                       'Statemachine Nullsetzen&lt;br /&gt;
&lt;br /&gt;
   Ps2_in_ptr = 1                                      'Ring-Puffer auf..&lt;br /&gt;
   Ps2_out_ptr = 1                                     '..Anfang setzen&lt;br /&gt;
   Ps2_buffer(1) = 0                                   'Erstes Element Nullsetzen&lt;br /&gt;
&lt;br /&gt;
   Ps2_byte = Ps2_byte2send&lt;br /&gt;
&lt;br /&gt;
   Config Ps2_data_port = Output&lt;br /&gt;
   Ps2_data_port = 0&lt;br /&gt;
   Config Ps2_clock_port = Input&lt;br /&gt;
&lt;br /&gt;
   Enable Int1                                         'Interruptfreigabe Int1&lt;br /&gt;
End Sub&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Function Ps2_count()as Byte&lt;br /&gt;
   Local Ps2_var As Byte                               'Hilfsvariable&lt;br /&gt;
   push r0:in r0,gicr:push r0:disable int1             'Int1 sperren&lt;br /&gt;
   Ps2_var = Ps2_in_ptr - Ps2_out_ptr                  'Ringpufferelemente bestimen&lt;br /&gt;
   pop r0:!out gicr,r0:pop r0                          'Int1 wiederherstellen&lt;br /&gt;
   If Ps2_in_ptr &amp;lt; Ps2_out_ptr Then&lt;br /&gt;
      Ps2_count = Ps2_var + Ps2_buff_size              'Korrektur bei negativem Ergebnis&lt;br /&gt;
   Else&lt;br /&gt;
      ps2_count=ps2_var&lt;br /&gt;
   End If&lt;br /&gt;
End Function&lt;br /&gt;
&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
'***   Serielle Empfangsroutine per Interrupt                                ***&lt;br /&gt;
'*******************************************************************************&lt;br /&gt;
Isr_int1:&lt;br /&gt;
   If Ps2_mode = 0 Then                                'Transmission Device -&amp;gt; Host&lt;br /&gt;
      Select Case Ps2_state&lt;br /&gt;
         Case 0                                        'Startbit&lt;br /&gt;
            Ps2_state = 1&lt;br /&gt;
         Case 1 To 8                                   '8 Databits empfangen&lt;br /&gt;
            Shift Ps2_byte , Right                     'Platz für nächstes Bit schaffen&lt;br /&gt;
            Ps2_byte.7 = Ps2_data                      'Bit lesen&lt;br /&gt;
            Ps2_state = Ps2_state + 1                  'Folge-State setzen&lt;br /&gt;
         Case 9                                        'Paritybit (keine Auswertung)&lt;br /&gt;
            Ps2_state = 10                             'Folge-State setzen&lt;br /&gt;
         Case 10                                       'Stopbit, d.h. Byte komplett&lt;br /&gt;
            Call Ps2_buffer_write(ps2_byte)            'Byte in Ringpuffer schreiben&lt;br /&gt;
            Ps2_state = 0                              'Statemachine auf Anfang&lt;br /&gt;
      End Select&lt;br /&gt;
   Else                                                'Transmission Host -&amp;gt; Device&lt;br /&gt;
      Select Case Ps2_state&lt;br /&gt;
         Case 0                                        'Startbit&lt;br /&gt;
            Ps2_data_port = 0                          'Data-Leitung Low&lt;br /&gt;
            Ps2_parity = 0                             'Paritätszähler Nullen&lt;br /&gt;
            Ps2_state = 1                              'Folge-State setzen&lt;br /&gt;
         Case 1 To 8                                   '8 Datenbit ausgeben&lt;br /&gt;
            If Ps2_byte.0 = 1 Then&lt;br /&gt;
               Ps2_data_port = 1                       'PS/2-Data-Leiung High&lt;br /&gt;
               Ps2_parity = Ps2_parity + 1             'Paritätszähler verwalten&lt;br /&gt;
            Else&lt;br /&gt;
               Ps2_data_port = 0                       'PS/2-Data-Leiung Low&lt;br /&gt;
            End If&lt;br /&gt;
            Shift Ps2_byte , Right                     'Nächstes Bit holen&lt;br /&gt;
            Ps2_state = Ps2_state + 1                  'Folge-State setzen&lt;br /&gt;
         Case 9                                        'Paritätsbit ausgeben&lt;br /&gt;
            If Ps2_parity.0 = 0 Then&lt;br /&gt;
               Ps2_data_port = 1                       'PS/2-Data-Leiung High&lt;br /&gt;
            Else&lt;br /&gt;
               Ps2_data_port = 0                       'PS/2-Data-Leiung Low&lt;br /&gt;
            End If&lt;br /&gt;
            Ps2_state = 10                             'Folge-State setzen&lt;br /&gt;
         Case 10                                       'Stopbit&lt;br /&gt;
            Config Ps2_data_port = Input&lt;br /&gt;
            Ps2_state = 11                             'Folge-State setzen&lt;br /&gt;
         Case 11                                       'Acknowlegde&lt;br /&gt;
            Call Ps2_init()&lt;br /&gt;
         End Select&lt;br /&gt;
   End If&lt;br /&gt;
Return&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[Kategorie:Quellcode Bascom]]&lt;/div&gt;</summary>
		<author><name>Screwdriver_alt</name></author>	</entry>

	</feed>