Hallo Gast,

Die bits stehen nicht "ganz vorne", sondern "ganz hinten", im LOW nibble.
Damit komme ich auch immer wieder durcheinander:


1. Nummerierung der BITs (und auch der BYTEs / WORDs):
In CC_BASIC wird immer "LOW to HIGH" nummeriert, beginnend mit 1. Das bedeutet:
Die BITs im BYTEPORT[1] heissen BIT[1] bis BIT[8],
und dabei ist BIT[1] das LSB (das mit dem niedrigsten Wert: "2 hoch 0" = 1),
und BIT[8] das MSB (das mit dem höchsten Wert: "2 hoch 7" = 12.

--- Ich nummeriere bits (und bytes..) eigentlich immer ab 0, nicht ab 1; das machen auch die meisten Assembler und Datenblätter so.

--- Aber meine Verwechslungen entstehen oft auch dadurch:
In CC-BASIC schreibt man bei Aufzählungen untereinander zuerst BIT[1] (LSB), dann BIT[2], .. bis BIT[8] (MSB),
während ich das IMMER umgekehrt mache, nämlich zuerst bit_7 (MSB), dann bit_6, .. bis bit_0 (LSB).
Ich bin's halt seit über 30 Jahren so gewohnt, und ich kann mir so aus den bit-Werten leichter den HEX Wert des Bytes zusammenbasteln; Dir gehts anscheinend genauso (siehe Punkt2).


2. Der LCD_PORT ist definiert als BYTEPORT[2] und umfasst demnach die bit ports PORT[9] bis PORT[16].
Dabei ist wieder PORT[9] das LSB und PORT[16] das MSB.
PORT[9] bis PORT[12] ist also das niederwertige Halbbyte ("low nibble")
und PORT[13] .. PORT[16] ist das high nibble dieses bytes.

--- Also ist bei &B00100000 = &H20 im LCD_PORT = BYTEPORT[2] die "1" der PORT[14] (und das ist RS, siehe Punkt 4).


3. Leitungen des LCD:
RS = select command (0) or data (1)
R/W (quer) = write to LCD (0) oder read from LCD (1)
E = enable (pulse)
DB0..DB3 = data LOW nibble; nur benutzt im LCD 8-bit modus; ignoriert im 4-bit mode (!!)
DB4..DB7 = data HIGH nibble im 8-bit mode; im 4-bit-mode: zuerst high nibble, dann low nibble
Die Nummerierung der data bits im LCD beginnt also mit 0 (nicht mit 1).


4. Hardware-Beschaltung des BYTEPORT[2] für das LCD:
Das low nibble des BYTEPORT[2] (also PORT[9]..PORT[12]) liegt am high (!!) nibble der LCD DATA, weil der 4-bit mode des LCD genutzt werden soll.
Das high nibble des BYTEPORT[2] enthält die LCD Steuerleitungen, und zwar:
PORT[13] liegt an RW des LCD (0 = "write to LCD"),
PORT[14] liegt an RS des LCD (0 = "LCD command", 1 = "LCD data"),
PORT[15] ist das LCD enable signal (wird gepulst),
und PORT[16] ist nicht zum LCD verdrahtet.

Das low nibble des LCD ist NICHT verdrahtet (braucht auch keine pull ups), weil hier ja der 4-bit-modus des LCD genutzt wird.


5. Im LCD 4-bit-modus werden sowohl Data als auch Command in zwei Takten übertragen.
Im ersten Takt steht das high nibble, und im zweiten Takt das low nibble des zu übertragenden Bytes im PORT[9]..PORT[12] ( = low nibble) des LCD_PORT.
In beiden Fällen wird aber auch immer PORT[13]..PORT[16] gesetzt,
wobei PORT[15] = ENABLE immer 0 ist
und PORT[13] = RW ebenfalls immer 0 = "write to LCD" ist.
PORT[16] ist nicht zum LCD verdrahtet, bedeutet also fürs LCD nix.

Jeder Takt wird dem LCD mit einem pulse des PORT[15] (= LCD enable) signalisiert;
erst jetzt interpretiert das LCD die anliegenden Daten, nämlich:
PORT[9] .. PORT[12] = Wert des high nibble beim 1. Takt bzw. des low nibble beim 2. Takt;
PORT[13] = RW = "Write to LCD";
PORT[14] = RS = "data" (falls 1) oder "command" (falls 0).


6. Die Übertragung von commands und data im 4-bit mode müsstest Du jetzt nachvollziehen können:
LCD_WRITECMD setzt PORT[14] = RS = 0 = "LCD command",
LCD_WRITECHAR dagegen PORT[14] = RS = 1 = "LCD data".
Bei beiden ist PORT[13] = RW = 0 = "Write to LCD".
Im LCD_WRITE wird zuerst das high nibble, und dann das low-nibble erzeugt und jeweils mit pulse LCD_E an das LCD übergeben.

Für die Bedeutung der commands und der bits innerhalb der commands brauchst Du natürlich auch eine Beschreibung des LCD.


7. Mit dem LCD_INIT soll das LCD in den 4-bit modus versetzt werden.

Zuerst wird &H38 mit "gosub LCD_WRITECMD" ausgegeben.
Ich erkläre mir das so, bin mir aber nicht ganz sicher (-- vielleicht kann jemand sagen, ob's stimmt --):

FALLS das LCD zu diesem Zeitpunkt im 4-bit mode läuft, dann ist das EIN command ans LCD:
001 = LCD command "FUNCTION SET" mit DL = 1 = "8-bit-mode", N = 1 = "display 2 lines" und F = 0 = "5x8 char matrix"

FALLS ABER das LCD aber zu diesem Zeitpunkt bereits im 8-bit-mode war, z. B. nach power-on, dann erzeugt "gosub LCD_WRITECMD" jetzt ZWEI commands an das LCD:
command 1 (ist das high nibble von &H3: 001 = LCD command "FUNCTION SET" mit DL = 1 = "8-bit-mode" ( + floatendes low nibble der LCD data Leitungen)
command 2 (ist das low nibble von &H3: 1 = "Set DD-RAM address" auf wert 000 ( + floatendes low nibble der LCD data Leitungen)

Egal wie: das LCD ist jetzt definitiv im 8-bit-mode.
Das folgende "LCD_PORT = &B00000010 : pulse LCD_E" ist deshalb immer ein LCD command IM 8 BIT MODE (wird ja auch NICHT mit "gosub LCD_WRITECMD" ausgegeben, sonder direkt gepulst):
PORT[13] = RW = 0 = "write to LCD",
PORT[14] = RS = 0 = "LCD command" und
PORT[9]..PORT[12] = low nibble = 0010; das liegt ja aber am HIGH (!!) nibble der LCD data. Also:
001 = LCD command "FUNCTION SET" mit DL = 0 = "4-bit-mode" ( + floatendes low nibble der LCD data Leitungen)

Jetzt ist das LCD also definitiv im 4-bit-mode,
und die Ausgaben &H28 und &H0C mit "gosub LCD_WRITECMD" sind normale LCD commands im 4-bit modus:
&H28 = 001 = "FUNCTION SET" mit DL = 0 = "4-bit-mode", N = 1 = "display 2 lines" und F = 0 = "5x8 char matrix"
&H0C = 00001 = "DISPLAY" mit D = 1 = "Display on", C = 1 = "Cursor unsichtbar" und B = 0 = "blinken aus".


UFF, ich hoffe das stimmt alles,
sonst habe ich Dich jetzt sehr verwirrt!