Ein Interface für den Parallel Port hat zwei gravierende Nachteile:
Vorteil des seriellen Interface:
Spannung: 8 bis 12 Volt
Strom: 25mA
Übertragungsgeschwindigkeit: ca. 9,2ms/Byte
Eine Übersicht über die Funktionsweise des I2C-Bus wird hier nicht geliefert. Das Internet ist voll davon.
Alle Schaltungen werden in ein Standard Bopla Gehäuse untergebracht, sie sind klein und trittfest.
| Globale Variable und Constante |
| Const high = false; low = true;
Var |
Basisfunktionen der seriellen Schnittstelle
| Öffnen der seriellen Schnittstelle |
| // Result = true = alles klar // Result = false = Schnittstelle steht nicht zur Verfügung Function ComOpen(ComStr:String):Boolean; Begin Result := true; CHandle := CreateFile(PCHAR(ComStr), GENERIC_READ or GENERIC_WRITE, 0, nil, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); If CHandle = INVALID_HANDLE_VALUE Then Result := false; CEnabled := Result; End; |
| Schliessen der seriellen Schnittstelle |
| Procedure ComClose; Begin If CEnabled Then Begin CloseHandle(CHandle); CHandle := INVALID_HANDLE_VALUE; End; End; |
| Setzt die DTR Leitung |
| // State = True = +5V..+12V // State = False = -12V..-5V Function DTR(State:Boolean):Boolean; Const DTR: Array[Boolean] of Integer = (CLRDTR,SETDTR); Begin Result := false; If CEnabled Then Begin Result := EscapeCommFunction(CHandle,DTR[State]); End; End; |
| Setzt die RTS Leitung |
| // State = True = +5V..+12V // state = False = -12V..-5V Function RTS(State:Boolean):Boolean; Const RTS: Array[Boolean] of Integer = (CLRRTS,SETRTS); Begin Result := false; If CEnabled Then Begin Result := EscapeCommFunction(CHandle,RTS[State]); End; End; |
| Holt den Status der DSR Leitung |
| // Result = True = +5V..12V // Result = False = -12V..0V oder Offener Eingang Function DSR:Boolean; Var Flag:DWord; Begin Result := false; If CEnabled Then Begin If GetCommModemStatus(CHandle,Flag) Then Begin Result := (Flag and MS_DSR_ON > 0); End; End; End; |
| Holt den Status der CTS Leitung |
| // True = +5V..12V // False = -12V..0V oder Offener Eingang Function CTS:Boolean; Var Flag:DWord; Begin Result := false; If CEnabled Then Begin If GetCommModemStatus(CHandle,Flag) Then Begin Result := (Flag and MS_CTS_ON > 0); End; End; End; |
| Holt den Status der Ring Leitung |
| // True = Versorgungsspannung ist vorhanden // False = Versorgungsspannung fehlt Function Ring:Boolean; Var Flag:DWord; Begin Result := false; If CEnabled Then Begin If GetCommModemStatus(CHandle,Flag) Then Begin Result := (Flag and MS_RING_ON > 0); End; End; End; |
Basisfunktionen des I2C Bus
| Setzen der SCL Leitung |
| // b1 = high = SCL Leitung liegt auf +5Volt // b1 = low = SCL Leitung liegt auf 0 Volt Procedure SCL(b1:Boolean); Begin DTR(not b1); End; |
| Setzen der SDA Leitung |
| // b1 = high = SDA Leitung liegt auf +5Volt // b1 = low = SDA Leitung liegt auf 0 Volt Procedure SDA(b1:Boolean); Begin RTS(not b1); End; |
| Lesen des Zustandes der SCL Leitung |
| // Result = high = SCL Leitung liegt auf +5Volt // Result = low = SCL Leitung liegt auf 0 Volt Function GetSCL:Boolean; Begin If DSR Then Result := low Else Result := high; End; |
| Lesen des Zustandes der SDA Leitung |
| // Result = high = SDA Leitung liegt auf +5Volt // Result = low = SDA Leitung liegt auf 0 Volt Function GetSDA:Boolean; Begin If CTS Then Result := low Else Result := high; End; |
Höhere Funktionen des I2C Bus
| Startbit ausgeben |
| Procedure I2CStartBit; Begin // Wenn CLK high ist, wechselt SDA von high nach low SDA(high); SCL(high); SDA(low); SCL(low); End; |
| Stopbit ausgeben |
| Procedure I2CStopBit; Begin // Wenn CLK high ist, wechselt SDA von low nach high SDA(low); SCL(high); SDA(high); End; |
| Initialisierung |
| //Schnittstelle öffnen und Leitungen initialisieren Function I2CInit(ComPort:String):Boolean; Begin Result := false; If ComOpen(ComPort) Then Begin DTR(false); RTS(False); Result := true; End; End; |
| Schliessen |
| // Schnittstelle freigeben Procedure I2CRelease; Begin ComClose; End; |
| Byte ausgeben |
| Function I2CPutByte(b1:Byte):Boolean; Var i:Integer; j:Byte; Begin Result := false; j := $80; For i := 1 to 8 do Begin If (j and b1) = j Then Begin SDA(high); End Else Begin SDA(low); End; SCL(high); SCL(low); SDA(low); j := j div 2; End; // Acknowledge empfangen SDA(high); SCL(high); Result := GetSDA; SCL(low); SDA(high); End; |
| Byte einlesen |
| Function GetByte(Ack:Byte):Byte; Var i:Integer; b1:Byte; Begin Result := 0; b1 := $00; SDA(high); For i := 1 to 8 do Begin b1 := b1 * 2; SCL(high); If GetSDA = high Then b1 := b1 or $01; SCL(low); End; // Acknowledge senden If Ack = 0 Then SDA(low) Else SDA(high); SCL(high); SCL(low); SDA(high); Result := b1; End; |
Download |
Bemerkung |
I2CDemo.zip |
Demo mit PCF8574 (Digital I/O) und PCF8583 (Counter) als Beispiel. |
I2CUnit.pas |
Unit mit allen Funktionen zur Bedienung des I2C-Bus Interfaces |
Die Unit enthält eine Delay Funktion, die Verzögerungszeiten im Mikrosekundenbereich ermöglicht. Sollte der Typ TLargeInteger in der gewählten Hochsprache nicht verfügbar sein, kann die Funktion entfernt werden. Sie wurde nur bei der Entwicklung benötigt und wird von den anderen Funktionen jetzt nicht mehr benutzt.