Oled-Display mit deutschen Sonderzeichen

Atmega 328 mit BASCOM und FORTH programmieren
Antworten
Heinrichs
Beiträge: 173
Registriert: Do 21. Okt 2010, 18:31

Oled-Display mit deutschen Sonderzeichen

Beitrag von Heinrichs » Do 21. Nov 2019, 11:33

Ein beliebtes (weil recht preiswertes) Display ist das "OLED 128x64 Display SH1106 I2C". Der Name sagt es schon: Es handelt sich um ein OLED-Display mit 128 * 64 Pixeln, welches über I2C gesteuert wird. Die I2C-Adresse ist $78 und kann (durch Umsetzen eines SMD-Widerstandes) auf $7A umgestellt werden. Als Display-Controller wird hier ein SH1106-Baustein verwendet.

sonderzeichen.jpg
OLED SH1106 mit den Sonderzeichen ö und ß
sonderzeichen.jpg (47.35 KiB) 13101 mal betrachtet

Achtung: Eine Reihe von äußerlich gleich aussehenden Displays besitzt den SSD1306; dieser ist fast(!) kompatibel zum SH1106. Einen ausführlichen Beitrag zu diesem Problem findet man hier. Grundsätzliche Bemerkungen zur Funktionsweise dieser beiden Bausteine findet man in meinem Beitrag Mini-Oszi mit OLED SSD1306.

Beide Bausteine besitzen keinen Font; man muss den Font softwaremäßig realisieren. In dem folgenden Programm findet man ihn in Form von Data-Zeilen am Ende des BASCOM-Quellcodes; derartige Byte-Tabellen für Fonts findet man an verschiedenen Stellen im Internet. Leider habe ich dort keine Font-Tabelle gefunden, welche auch die deutschen Sonderzeichen ä, ö, ü, Ä, Ö, Ü und ß besitzt. Deswegen habe ich für diese Zeichen eigene Byte-Muster gebildet und im Programm angefügt. Da die Buchstaben-Matrix (bei der hier verwendeten Kleinschrift) mit 5 x 7 Pixeln (ohne Unterlänge) sehr klein ist, musste ich beim Unterbringen der Punkte einige Kompromisse machen.

Üblicherweise findet man die Codes dieser Sonderzeichen weit jenseits der Grenze von 127; ich habe sie jedoch mit den Codes 128 bis 134 belegt. Auf diese Weise konnte ich überflüssige Data-Zeilen vermeiden. Damit das BASCOM-Programm den üblichen Codes von ä, ö, … die richtigen Data-Zeilen zuweist, wurde für diese Zeichen mit Hilfe einer CASE-Anweisung eine Umcodierung vorgenommen.

Das folgende Programm nimmt eine Zeichenkette mit maximal 128 Zeichen von einem Terminal über die serielle Schnittstelle entgegen und gibt sie auf dem Display aus. Dabei werden Zeilenumbrüche automatisch durchgeführt, ggf. auch mitten im Wort. Das kann dann so wie in der obigen Abbildung aussehen.

Code: Alles auswählen

' Programm für das Nano-Board
' Über die zu zugehörige Konfigurationsdatei werden automatisch Voreinstellungen
' für die Kompilierung übernommen; diese betreffen z. B. die Taktfrequenz, die
' Baudrate, die Anschlüsse von LCD, I2C- und SPI-Modulen.

' Programm nach I. Dobson, Sonal Pinto und Ben Zijlstra & Theo Kleijn
' OLED display 128x64 SSH1106(!) 0.96"

' Text (maximal 16*8 = 128 Zeichen) über COM eingeben
' Anzeige um 180° gedreht

'**********************************************************

$regfile = "m328pdef.dat"                                   'Dadurch wird auch das Pin Layout bestimmt
$crystal = 16000000
$framesize = 32
$swstack = 32
$hwstack = 64
$baud = 9600
Config Sda = Portc.4
Config Scl = Portc.5

'**********************************************************
'******************* Deklarationen ************************

Declare Sub Zeige_text
Declare Sub Init
Declare Sub Loeschen
Dim Kontrast As Byte
Dim Write_adresse_oled As Byte
Dim Text As String * 128
Dim X As Byte
Dim X1 As Byte
Dim X0 As Byte
Dim Page As Integer
Dim Buchstabe As String * 1
Dim Q As Integer
Dim H As Integer
Dim Temp As Integer
Dim Senden As Byte
Dim Pause As Byte
Dim J As Byte
Dim I As Byte
Dim Anzahlzeichen As Byte
Dim Anzahlzeilen As Byte
Dim Pos As Byte
Dim Zeile As String * 16
Dim Leerzeile As String * 16
Dim Rest As Byte
Dim Rest2 As Byte


'**********************************************************
'****************** Initialisierung ***********************

Ddrb.5 = 1

Config I2cdelay = 1                                         'I2C-Taktung möglichst rasch
Write_adresse_oled = &H78                                   'OLED SSD1306
Kontrast = 200                                              'hoher Kontrast
Pause = 1

'**********************************************************
'******************** Hauptprogramm ***********************



Call Init
Call Loeschen
Leerzeile = "                "

Do
  Print "Geben Sie eine Text ein (max. 128 Zeichen)! Senden mit CR"
  Input Text
  Call Loeschen
  Anzahlzeichen = Len(text)
  Anzahlzeilen = Anzahlzeichen / 16
  Rest = Anzahlzeichen Mod 16
  For I = 1 To Anzahlzeilen
    J = I - 1
    Pos = 16 * J
    Pos = Pos + 1
    Zeile = Mid(text , Pos , 16)
    X = 2                                                   'ganz links bei
    Page = I
    Zeige_text
  Next I
  If Rest > 0 Then
    Anzahlzeilen = Anzahlzeilen + 1
    J = Anzahlzeilen - 1
    Pos = 16 * J
    Pos = Pos + 1
    Rest2 = 16 - Rest
    Zeile = Mid(text , Pos , Rest) + Mid(leerzeile , 1 , Rest2)
    X = 2
    Page = Anzahlzeilen
    Zeige_text
  End If
Loop

'**********************************************************
'******************** Unterprogramme **********************

Sub Init
  I2cstart
  I2cwbyte Write_adresse_oled
  If Err = 0 Then Portb.5 = 1                               'LED bei B.5 an, wenn OLED gefunden
  I2cstop
  Waitms 500
  Portb.5 = 0

  I2cstart
  I2cwbyte Write_adresse_oled

  I2cwbyte &H00                                             'Command Stream(nötig -------------??)

  I2cwbyte &HAE                                             'DISPLAYOFF ------------------------OK

  I2cwbyte &HD5                                             'SETDISPLAYCLOCKDIV ----------------OK
  I2cwbyte &H80                                             'ratio 0x80

  I2cwbyte &HA8                                             'Set MUX
  I2cwbyte &H3F                                             '&H1F for 128x32; &H3F for 128x64

  I2cwbyte &HD3                                             'SETDISPLAYOFFSET ------------------OK
  I2cwbyte &H00

  I2cwbyte &H40                                             'SETSTARTLINE ----------------------OK

  I2cwbyte &H8D                                             'CHARGEPUMP ------------------------OK
  I2cwbyte &H14                                             'vccstate 14 for chargepump

  I2cwbyte &H20                                             'MEMORYMODE ------------------------OK
  I2cwbyte &H00                                             'horizontal addr mode

  I2cwbyte &HA0                                             'SEGREMAP links-rechts A0/A1 -------OK

  I2cwbyte &HC0                                             'COMSCANDEC (&HC0 vert. gesp.) -----OK

  I2cwbyte &HDA                                             'SETCOMPINS ------------------------OK
  I2cwbyte &H12                                             '&H12 for 64 rows

  I2cwbyte &H81                                             'SETCONTRAST -----------------------OK
  I2cwbyte Kontrast                                         'value 1-->256

  I2cwbyte &HD9                                             'SETPRECHARGE ----------------------OK
  I2cwbyte &HF1                                             'vccstate  F1

  I2cwbyte &HDB                                             'SETVCOMDETECT ---------------------OK
  I2cwbyte &H30                                             '&H30 -> 0.83*VCC; bei Arduino &H40 ??

  I2cwbyte &HA4                                             'DISPLAYALLON_RESUME ---------------OK

  I2cwbyte &HA6                                             'NORMALDISPLAY

  I2cwbyte &HAF                                             'Display on ------------------------OK
  I2cstop
End Sub

Sub Zeige_text                                              'schreibt die Zeichenkette "Zeile" (mit genau 16 Zeichen) in die Zeile "Page"
    X0 = X Mod 16
    X1 = X / 16
    X1 = X1 + &H10
    I2cstart
    I2cwbyte Write_adresse_oled
    I2cwbyte &H00                                           'command stream ------------------??
    I2cwbyte X0                                             'Spalte x Low Nibble
    I2cwbyte X1                                             'Spalte x High Nibble
    I2cstop

    Page = Page + 175
    I2cstart
    I2cwbyte Write_adresse_oled
    I2cwbyte &H80
    I2cwbyte Page                                           'Bestimmung Page (Y)
    I2cstop

    I2cstart
    I2cwbyte Write_adresse_oled
    I2cwbyte &H80
    I2cstop

    I2cstart
    I2cwbyte &H78
    I2cwbyte &H40

    'Umwandlung von Buchstaben zu Asciiwert zu Columndata der Datenbank
    For Q = 1 To 16                                         'max. 16 Zeichen pro Zeichenkette
       Temp = 0
       Buchstabe = Mid(zeile , Q , 1)
       Temp = Asc(buchstabe)
       
       If Temp > 127 Then
         Select Case Temp
           Case 228 : Temp = 128                            'ä
           Case 246 : Temp = 129                            'ö
           Case 252 : Temp = 130                            'ü
           Case 196 : Temp = 131                            'Ä
           Case 214 : Temp = 132                            'Ö
           Case 220 : Temp = 133                            'Ü
           Case 223 : Temp = 134                            'ß
           Case Else : Temp = 32                            'SPACE
         End Select
       End If

       Temp = Temp - 32
       Temp = Temp * 8
       For H = 1 To 8
          Senden = Lookup(temp , Asciitab)
          I2cwbyte Senden
          Incr Temp
       Next H
       Waitms Pause
    Next Q
    I2cstop
End Sub

Sub Loeschen                                                'speziell für SSH1106
 For X0 = 0 To 7
  X1 = &HB0 + X0
  I2cstart
  I2cwbyte Write_adresse_oled
  I2cwbyte &H80                                             'Single Command
  I2cwbyte X1                                               'Page (Y) &HB0 = Col0
  I2cstop

  I2cstart
  I2cwbyte Write_adresse_oled
  I2cwbyte &H00                                             'command stream
  I2cwbyte &H02                                             'Select start column 0; offset 2
  I2cwbyte &H10
  I2cstop

  I2cstart
  I2cwbyte Write_adresse_oled
  I2cwbyte &H40                                             'Datenstrom für das RAM
  For Temp = 0 To 127
    I2cwbyte 0
  Next Temp
  I2cstop
 Next X0
End Sub


'**********************************************************
'******************Interruptroutinen***********************


'**********************************************************

Asciitab:
    Data 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0,                     'ASCII-Code 32
    Data 0 , 0 , 6 , 95 , 6 , 0 , 0 , 0,                    'ASCII-Code 33
    Data 0 , 7 , 3 , 0 , 7 , 3 , 0 , 0,                     '...
    Data 0 , 36 , 126 , 36 , 126 , 36 , 0 , 0,              '#
    Data 0 , 36 , 43 , 106 , 18 , 0 , 0 , 0,
    Data 0 , 99 , 19 , 8 , 100 , 99 , 0 , 0,
    Data 0 , 54 , 73 , 86 , 32 , 80 , 0 , 0,
    Data 0 , 0 , 7 , 3 , 0 , 0 , 0 , 0,
    Data 0 , 0 , 62 , 65 , 0 , 0 , 0 , 0,                   'ASCII-Code 40
    Data 0 , 0 , 65 , 62 , 0 , 0 , 0 , 0,
    Data 0 , 8 , 62 , 28 , 62 , 8 , 0 , 0,
    Data 0 , 8 , 8 , 62 , 8 , 8 , 0 , 0,
    Data 0 , 0 , 224 , 96 , 0 , 0 , 0 , 0,
    Data 0 , 8 , 8 , 8 , 8 , 8 , 0 , 0,
    Data 0 , 0 , 96 , 96 , 0 , 0 , 0 , 0,
    Data 0 , 32 , 16 , 8 , 4 , 2 , 0 , 0,
    Data 0 , 62 , 81 , 73 , 69 , 62 , 0 , 0,
    Data 0 , 0 , 66 , 127 , 64 , 0 , 0 , 0,
    Data 0 , 98 , 81 , 73 , 73 , 70 , 0 , 0,                'ASCII-Code 50
    Data 0 , 34 , 73 , 73 , 73 , 54 , 0 , 0,
    Data 0 , 24 , 20 , 18 , 127 , 16 , 0 , 0,
    Data 0 , 47 , 73 , 73 , 73 , 49 , 0 , 0,
    Data 0 , 60 , 74 , 73 , 73 , 48 , 0 , 0,
    Data 0 , 1 , 113 , 9 , 5 , 3 , 0 , 0,
    Data 0 , 54 , 73 , 73 , 73 , 54 , 0 , 0,
    Data 0 , 6 , 73 , 73 , 41 , 30 , 0 , 0,
    Data 0 , 0 , 108 , 108 , 0 , 0 , 0 , 0,
    Data 0 , 0 , 236 , 108 , 0 , 0 , 0 , 0,
    Data 0 , 8 , 20 , 34 , 65 , 0 , 0 , 0,                  'ASCII-Code 60
    Data 0 , 36 , 36 , 36 , 36 , 36 , 0 , 0,
    Data 0 , 0 , 65 , 34 , 20 , 8 , 0 , 0,
    Data 0 , 2 , 1 , 89 , 9 , 6 , 0 , 0,
    Data 0 , 62 , 65 , 93 , 85 , 30 , 0 , 0,
    Data 0 , 126 , 17 , 17 , 17 , 126 , 0 , 0,
    Data 0 , 127 , 73 , 73 , 73 , 54 , 0 , 0,
    Data 0 , 62 , 65 , 65 , 65 , 34 , 0 , 0,
    Data 0 , 127 , 65 , 65 , 65 , 62 , 0 , 0,
    Data 0 , 127 , 73 , 73 , 73 , 65 , 0 , 0,
    Data 0 , 127 , 9 , 9 , 9 , 1 , 0 , 0,                   'ASCII-Code 70
    Data 0 , 62 , 65 , 73 , 73 , 122 , 0 , 0,
    Data 0 , 127 , 8 , 8 , 8 , 127 , 0 , 0,
    Data 0 , 0 , 65 , 127 , 65 , 0 , 0 , 0,
    Data 0 , 48 , 64 , 64 , 64 , 63 , 0 , 0,
    Data 0 , 127 , 8 , 20 , 34 , 65 , 0 , 0,
    Data 0 , 127 , 64 , 64 , 64 , 64 , 0 , 0,
    Data 0 , 127 , 2 , 4 , 2 , 127 , 0 , 0,
    Data 0 , 127 , 2 , 4 , 8 , 127 , 0 , 0,
    Data 0 , 62 , 65 , 65 , 65 , 62 , 0 , 0,
    Data 0 , 127 , 9 , 9 , 9 , 6 , 0 , 0,                   'ASCII-Code 80
    Data 0 , 62 , 65 , 81 , 33 , 94 , 0 , 0,
    Data 0 , 127 , 9 , 9 , 25 , 102 , 0 , 0,
    Data 0 , 38 , 73 , 73 , 73 , 50 , 0 , 0,
    Data 0 , 1 , 1 , 127 , 1 , 1 , 0 , 0,
    Data 0 , 63 , 64 , 64 , 64 , 63 , 0 , 0,
    Data 0 , 31 , 32 , 64 , 32 , 31 , 0 , 0,
    Data 0 , 63 , 64 , 60 , 64 , 63 , 0 , 0,
    Data 0 , 99 , 20 , 8 , 20 , 99 , 0 , 0,
    Data 0 , 7 , 8 , 112 , 8 , 7 , 0 , 0,
    Data 0 , 113 , 73 , 69 , 67 , 0 , 0 , 0,                'ASCII-Code 90
    Data 0 , 0 , 127 , 65 , 65 , 0 , 0 , 0,
    Data 0 , 2 , 4 , 8 , 16 , 32 , 0 , 0,
    Data 0 , 0 , 65 , 65 , 127 , 0 , 0 , 0,
    Data 0 , 4 , 2 , 1 , 2 , 4 , 0 , 0,
    Data 128 , 128 , 128 , 128 , 128 , 128 , 128 , 128,
    Data 0 , 0 , 3 , 7 , 0 , 0 , 0 , 0,
    Data 0 , 32 , 84 , 84 , 84 , 120 , 0 , 0,
    Data 0 , 127 , 68 , 68 , 68 , 56 , 0 , 0,
    Data 0 , 56 , 68 , 68 , 68 , 40 , 0 , 0,
    Data 0 , 56 , 68 , 68 , 68 , 127 , 0 , 0,               'ASCII-Code 100
    Data 0 , 56 , 84 , 84 , 84 , 8 , 0 , 0,
    Data 0 , 8 , 126 , 9 , 9 , 0 , 0 , 0,
    Data 0 , 24 , 164 , 164 , 164 , 124 , 0 , 0,
    Data 0 , 127 , 4 , 4 , 120 , 0 , 0 , 0,
    Data 0 , 0 , 0 , 125 , 64 , 0 , 0 , 0,
    Data 0 , 64 , 128 , 132 , 125 , 0 , 0 , 0,
    Data 0 , 127 , 16 , 40 , 68 , 0 , 0 , 0,
    Data 0 , 0 , 0 , 127 , 64 , 0 , 0 , 0,
    Data 0 , 124 , 4 , 24 , 4 , 120 , 0 , 0,
    Data 0 , 124 , 4 , 4 , 120 , 0 , 0 , 0,                 'ASCII-Code 110
    Data 0 , 56 , 68 , 68 , 68 , 56 , 0 , 0,
    Data 0 , 252 , 68 , 68 , 68 , 56 , 0 , 0,
    Data 0 , 56 , 68 , 68 , 68 , 252 , 0 , 0,
    Data 0 , 68 , 120 , 68 , 4 , 8 , 0 , 0,
    Data 0 , 8 , 84 , 84 , 84 , 32 , 0 , 0,
    Data 0 , 4 , 62 , 68 , 36 , 0 , 0 , 0,
    Data 0 , 60 , 64 , 32 , 124 , 0 , 0 , 0,
    Data 0 , 28 , 32 , 64 , 32 , 28 , 0 , 0,
    Data 0 , 60 , 96 , 48 , 96 , 60 , 0 , 0,
    Data 0 , 108 , 16 , 16 , 108 , 0 , 0 , 0,               'ASCII-Code 120
    Data 0 , 156 , 160 , 96 , 60 , 0 , 0 , 0,
    Data 0 , 100 , 84 , 84 , 76 , 0 , 0 , 0,
    Data 0 , 8 , 62 , 65 , 65 , 0 , 0 , 0,
    Data 0 , 0 , 0 , 119 , 0 , 0 , 0 , 0,
    Data 0 , 0 , 65 , 65 , 62 , 8 , 0 , 0,
    Data 0 , 2 , 1 , 2 , 1 , 0 , 0 , 0,
    Data 0 , 60 , 38 , 35 , 38 , 60 , 0 , 0,                'ASCII-Code 127
    Data 0 , 32 , 85 , 84 , 85 , 120 , 0 , 0,               'ä
    Data 0 , 56 , 69 , 68 , 69 , 56 , 0 , 0,                'ö
    Data 0 , 60 , 65 , 32 , 125 , 0 , 0 , 0,                'ü
    Data 0 , 125 , 18 , 17 , 18 , 125 , 0 , 0,              'Ä
    Data 0 , 61 , 66 , 65 , 66 , 61 , 0 , 0,                'Ö
    Data 0 , 60 , 65 , 64 , 65 , 60 , 0 , 0,                'Ü
    Data 0 , 254 , 9 , 73 , 78 , 48 , 0 , 0                 'ß
    Data 0 , 126 , 9 , 73 , 73 , 54 , 0 , 0                 'ß


Antworten