Home    Impressum / Datenschutz    Shop    Download    Links     Blog  

I2C-LCD-Gateway Programmierbeispiel

LCD-Display über den I2C-Bus mit dem I2C-Koppler ansteuern

Option Explicit

Private Sub Command_OpenCom_Click()

If Command_OpenCom.Caption = "COM öffnen" Then
  'Serielle Schnittstelle öffnen
  If OPENCOM(Combo_Com.Text & ":" & Combo_Baud.Text & ",n,8,1") = 0 Then
      MsgBox ("Fehler, kann " & Combo_Com.Text & " nicht öffnen")
  Else
      SDA 1 'I2C-Interface testen
      If Not SDA_in Then
        MsgBox ("Keine Antwort vom I2C-Seriell Interface")
        'Serielle Schnittstelle schließen
        CLOSECOM
      Else
        'I2C-Bus initialisieren
        i2cInit
        i2cStart
        i2cNoAck
        i2cStop
        Command_OpenCom.Caption = "COM schließen"
      End If
  End If
Else
  'Serielle Schnittstelle schließen
  CLOSECOM
  Command_OpenCom.Caption = "COM öffnen"
End If 

End Sub  

Private Sub Command_LICHT_Click()

i2cStart
If i2cSlave(Combo_Adresse.Text) Then    'Bus-Adresse des LCD-Gateways
  i2cOut 16                             'Steuerbyte (Licht EIN/AUS)
  i2cOut 0                              'Datenbyte  (Dummy)
End If
i2cStop

End Sub 

Private Sub Command_RESET_Click()
'Display initialisieren
'Welche Befehle hier gesendet werden müssen entnehmen
'Sie bitte dem Datenblatt des Displayherstellers

'Reset mit Pausen
Call LCD_Befehl_out(1, 48)  '1. Reset
DELAY (15)                  'Wartezeit nach Datenblatt
Call LCD_Befehl_out(1, 48)  '2. Reset
DELAY (15)                  'Wartezeit nach Datenblatt
Call LCD_Befehl_out(1, 48)  '3. Reset
DELAY (15)                  'Wartezeit nach Datenblatt
'Einstellungen
Call LCD_Befehl_out(1, 56)  '8 Bit Interface, 2 Lines
Call LCD_Befehl_out(1, 8)   'Display OFF
Call LCD_Befehl_out(1, 1)   'Display Clear
Call LCD_Befehl_out(1, 2)   'Cursor HOME
Call LCD_Befehl_out(1, 14)  'Display on, Cursor on, Cursor nicht blinken

End Sub

Private Sub Command_DISPLAY_Click()
Dim stat, Wert

Wert = 8                                                'Bit 3 = TRUE
If CheckBox_Display.Value = True Then Wert = Wert + 4   'Bit 2
If CheckBox_Cursor.Value = True Then Wert = Wert + 2    'Bit 1
If CheckBox_Blinken.Value = True Then Wert = Wert + 1   'Bit 0

' Wert zum Display schreiben
Call LCD_Befehl_out(1, Wert)

End Sub

Private Sub Command_CLEAR_Click()
  Call LCD_Befehl_out(1, 1)     'Display Clear
End Sub 

Private Sub Command_CR_Click() 'CURSOR nach Rechts verschieben
  Call LCD_Befehl_out(1, 20)    'Cursor nach rechts verschieben
End Sub

Private Sub Command_CL_Click() 'CURSOR nach Links verschieben
  Call LCD_Befehl_out(1, 16)    'Cursor nach Links verschieben
End Sub

Private Sub Command_AR_Click() 'Anzeige nach Rechts verschieben
  Call LCD_Befehl_out(1, 28)    'Cursor nach rechts verschieben
End Sub

Private Sub Command_AL_Click() 'Anzeige nach Links verschieben
  Call LCD_Befehl_out(1, 24)    'Cursor nach Links verschieben
End Sub

Private Sub Command_TEXT_2x16_Click()

Call LCD_Befehl_out(1, 128) 'DD-Ram Adresse Zeile 1 80h
Call LCD_Text_out(1, Zeile1.Text, 16)
Call LCD_Befehl_out(1, 192) 'DD-Ram Adresse Zeile 2 C0h
Call LCD_Text_out(1, Zeile2.Text, 16)

End Sub

Private Sub Command_TEXT_4x16_Click()

Call LCD_Befehl_out(1, 128) 'DD-Ram Adresse Zeile 1 80h
Call LCD_Text_out(1, Zeile1.Text, 16)
Call LCD_Befehl_out(1, 192) 'DD-Ram Adresse Zeile 2 C0h
Call LCD_Text_out(1, Zeile2.Text, 16)
Call LCD_Befehl_out(1, 144) 'DD-Ram Adresse Zeile 1 90h
Call LCD_Text_out(1, Zeile3.Text, 16)
Call LCD_Befehl_out(1, 208) 'DD-Ram Adresse Zeile 2 D0h
Call LCD_Text_out(1, Zeile4.Text, 16)

End Sub 

Private Sub Command_TEXT_4x20_Click()
Dim stat

Call LCD_Befehl_out(1, 128) 'DD-Ram Adresse Zeile 1 80h
Call LCD_Text_out(1, Zeile1.Text, 20)
Call LCD_Befehl_out(1, 192) 'DD-Ram Adresse Zeile 2 C0h
Call LCD_Text_out(1, Zeile2.Text, 20)
Call LCD_Befehl_out(1, 148) 'DD-Ram Adresse Zeile 1 94h
Call LCD_Text_out(1, Zeile3.Text, 20)
Call LCD_Befehl_out(1, 212) 'DD-Ram Adresse Zeile 2 D4h
Call LCD_Text_out(1, Zeile4.Text, 20)

End Sub 

Private Function LCD_Befehl_out(E1_2, Befehl)
Dim stat

i2cStart
If i2cSlave(Combo_Adresse.Text) Then 'Bus-Adresse des LCD-Gateways
  i2cOut (E1_2)                      'Steuerbyte (zum LCD am E1 oder E2)
  i2cOut (Befehl)                    'Datenbyte  (Befehl absetzen)
End If
i2cStop

End Function 

Private Function LCD_Text_out(E1_2, Text$, Zeichen)
Dim SteuBy, T$, z$, i

If E1_2 = 2 Then
    SteuBy = 6      'Steuerbyte (RS=1 und E2=1)
Else
    SteuBy = 5      'Steuerbyte (RS=1 und E1=1)
End If

'Wenn Zeichenanzahl angegeben ist String anpassen
If Zeichen > 0 Then
   T$ = Left$(Text$ & Space(Zeichen), Zeichen)
Else
   T$ = Text$
End If

i2cStart
If i2cSlave(Combo_Adresse.Text) Then 'Bus-Adresse des LCD-Gateways
  For i = 1 To Len(T$)    'Zeichen übergeben
    z$ = Mid$(T$, i, 1)   'Zeichen extrahieren
    
    i2cOut (SteuBy)       'Steuerbyte 
    i2cOut (Asc(z$))      'Datenbyte (Zeichencode)
  Next i
End If
i2cStop

End Function 

Private Sub Command_ZEICHEN_DEFINIEREN_Click()
'Eigene Zeichen für das LCD-Display im CGRAM ablegen
Dim SteuBy, i, ii, Wert

Call LCD_Befehl_out(1, 64)        'CG-Ram Adresse Zeile 1 40h

i2cStart
If i2cSlave(Combo_Adresse.Text) Then 'Bus-Adresse des LCD-Gateways
  SteuBy = 5                      'Steuerbyte (RS=1 RW=0 E1=1)
  For i = 0 To 7                  '8 Zeichen übertragen
    For ii = 0 To 7               '8 Werte / Zeichen
     Wert = Cells(i + 10, ii + 3) 'Werte liegen in der Tabelle ab z10s3
     i2cOut (SteuBy)              'Steuerbyte senden
     i2cOut (Wert)                'Datenbyte (Zeichen)
    Next ii
  Next i
End If
i2cStop

End Sub 

Private Sub Command_ZEICHEN_AUSGEBEN_Click()
'Ersten acht Zeichen des LCDs in der ersten Zeile ausgeben
'Diese Zeichen können ggf. selbst definiert werden
Dim z$, i, SteuBy

SteuBy = 5                    'Steuerbyte (RS=1 E1=1)
Call LCD_Befehl_out(1, 128)   'DD-Ram Adresse Zeile 1 80h

i2cStart
If i2cSlave(Combo_Adresse.Text) Then 'Bus-Adresse des LCD-Gateways
  For i = 0 To 7
     i2cOut (SteuBy)          'Steuerbyte senden
     i2cOut (i)               'Datenbyte (Zeichen 0-7)
  Next i
End If
i2cStop

End Sub

'Deklarationen und Public Functions aus dem Modul "I2C_Seriell"

Declare Function OPENCOM Lib "Port.dll" (ByVal A$) As Integer
Declare Sub CLOSECOM Lib "Port.dll" ()
Declare Sub DTR Lib "Port.dll" (ByVal b%)
Declare Sub RTS Lib "Port.dll" (ByVal b%)
Declare Function CTS Lib "Port.dll" () As Integer
Declare Function DSR Lib "Port.dll" () As Integer
Declare Sub DELAY Lib "Port.dll" (ByVal b%)

Public Function SCL(i) As Boolean
    'SCL auf der RTS-Leitung am COM-Port
    RTS i
End Function

Public Function SDA(i) As Boolean
    'Die Daten werden über DTR am COM-Port geschreiben
    DTR i
End Function 

Public Function SDA_in() As Boolean
    'Die SDA-Leitung wird über DSR am COM-Port wieder zurückgelesen
    If DSR = 1 Then
        SDA_in = True
    Else
        SDA_in = False
    End If
  
End Function 

Public Sub i2cInit()
    'Ruhezustand SDA=high und SCL=high
    SDA 1
    SCL 1
    If Not SDA_in Then MsgBox _ 
           ("Keine Antwort vom I2C-Seriell Interface")
End Sub

Public Sub i2cStart()
    'START => SDA=low anschließend SCL=low
    SDA 0
    SCL 0
End Sub

Public Sub i2cStop()
    'STOP => SDA=high, dann SCL=high
    SDA 0
    SCL 1
    SDA 1
End Sub 

Public Sub i2cAck()
    'ACKNOWLEDGE => Byte empfangen weitere Daten senden
    SDA 0
    SCL 1
    SCL 0
    SDA 1
End Sub 

Public Sub i2cNoAck()
    'NO ACKNOWLEDGE => Byte empfangen - Keine weiteren Daten senden
    SDA 1
    SCL 1
    SCL 0
End Sub 

Function i2cSlave(Adresse)    'Slave adressieren   
' Die 8 Bits der Slaveadresse werden nacheinander 
'auf die SDA-Leitung gelegt und
' jeweils mit einem Impuls auf der SCL-Leitung bestätigt.
' nach dem Stop-Befehl quittiert der Slave den Empfnag der Daten
    
    bit = 128
    For n = 1 To 8 '8 Bits senden
       If (Adresse And bit) = 0 Then SDA 0 Else SDA 1   'Daten übertragen
       SCL 1 'pos Impuls
       SCL 0 'neg Impuls
       bit = bit / 2
    Next n
    
    SDA 1   'SDA high setzen - wird vom Slave heruntergezogen
    SCL 1   '9. Impuls

    ' Slave antwortet mit neg. Flanke
    If SDA_in Then
        MsgBox ("Kein I2C-Slave an Adresse " & Adresse)
        i2cSlave = False
    Else
        'ok
        i2cSlave = True
    End If
    
    SCL 0
    
End Function

Public Function i2cIn() 'Wert vom Slave empfangen
    
' Der Master sendet 8 Impulse auf die SCL-Leitung und 
' erhält die high- oder low-Signale über die
' SDA-Leitung zurück.
    
    bit = 128
    Wert = 0
    SDA 1
    
    For n = 1 To 8
        SCL 1   'pos Impuls
        If SDA_in Then Wert = Wert + bit
        SCL 0   'neg Impuls
        bit = bit / 2
    Next n
    
    i2cIn = Wert
End Function

Public Sub i2cOut(Wert) 'Wert zum Slave senden
Dim bit, n
    
' Die 8 Datenbits werden nacheinander auf die SDA-Leitung 
' gelegt und jeweils mit einem Impuls auf der
' SCL-Leitung bestätigt.
' nach dem neunten Impuls quittiert der Slave den Empfnag der Daten

    bit = 128
    For n = 1 To 8 '8 Bits senden
       If (Wert And bit) = 0 Then SDA 0 Else SDA 1   'Daten übertragen
       SCL 1 'pos Impuls
       SCL 0 'neg Impuls
       bit = bit / 2
    Next n
    
    ' 9. Impuls
    SDA 1
    SCL 1 'pos Impuls
    
    ' Slave antwortet mit neg. Flanke
    If SDA_in Then MsgBox _ 
              ("keine quittierung der Daten vom Slave " & Adresse)

    SCL 0 'neg Impuls
    
End Sub 


 

Beispiele als Excel Makro
I2C-Ps-LCD-Gateway.xls und port.dll (101 kB)
Excel-Makro mit je einem Beispiel zur Ansteuerung der I2C-Ausgabekarte, I2C-Eingabekarte, der I2C-LCD-Anzeige, und dem Temperatursensor LM75
vba-makros.pdf (528 kB)
Bei den Makros kann es je nach Sicherheitseinstellungen zu Fehlermeldungen kommen. Eine Anleitung wie Sie die Makros ausführen können finden Sie in diesem Dokument

 

Bausätze können Sie günstig in unserem Onlineshop in der Rubrik
"I2C-Komponenten" bestellen.