Autor |
Beitrag |
Marekventur
Beiträge: 72
|
Verfasst: Mi 23.03.05 19:13
Hallo!
Ich hab mir einen LCD mit HD44780-kompatiblem Controller gekauft. mit Smarties hab ich den Display dann zum Laufen gebracht. Das Programm ist Open Source (sogar in DELPHI geschrieben), aber ich krieg die Routinen, die das LCD ansteuern nicht rasugeschrieben .
Der Hintergrund ist, das ich die Ansteuerung verstehe und anwenden kann, da ich sie für ein Serverproject auf Linux portieren möchte und vielleicht auch mir (mit einem evtuellem 2. Display) ein eigenenes Programm für Windows schreiben möchte (selbstgemacht, versteht sich ).
Weiß jemand, wie ich das LCD-Dispaly ansteuern kann? Ich meine programmiertechnisch, die Codes hab ich hier.
Achso, das Display hab ich über den LPT-Port angeschloßen, nach forlgendem Schema:
MFG Marek
edit: Richtiges Schema eingestellt.... Sorry
Zuletzt bearbeitet von Marekventur am So 27.03.05 14:04, insgesamt 2-mal bearbeitet
|
|
Marekventur
Beiträge: 72
|
Verfasst: Mi 23.03.05 19:15
Sorry für das große Bild, habs einfach nur übernommen
|
|
Adrian
Beiträge: 314
|
Verfasst: Do 24.03.05 10:40
Servus!
Mit einem 1x16-LCD habe ich mich vor Kurzem (erfolgreich ) beschäftigt, wobei ich fast nicht auf vorgefertigte Routinen zurückgreifen mußte. Wenn Du etwas genauer beschreibst, wo die Probleme liegen, könnte ich Dir vermutlich helfen.
Gruß,
Adrian
|
|
Yasso
Beiträge: 35
|
Verfasst: Fr 25.03.05 10:00
ich habe vor einger Zeit ein LCD + RS232-Adapter gekauft. Ein Beispiel für Delphi gab es auch. Es war sehr einfach zu programmieren. Aber ich glaube, dass ein 4x40LCD vom Adapter nicht unterstützt wird. Denn ein 4x40 zwei Enable-Pins hat und dieser RS232-Adapter nur einen Enable-Pin hat.
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25:
| ....
function TForm1.WriteToLCD(Comport, Str: String): Boolean; var FLcd : TextFile; begin AssignFile(FLcd,Comport); {$I-} Rewrite(FLcd); {$I+}
if IOResult = 0 then begin writeln(FLcd,Str); CloseFile(FLcd); Result := true; end else Result := false; end;
procedure TForm1.BtnWriteTxtClick(Sender: TObject); begin if NOT WriteToLCD('COM1','Das ist ein LCD') then ShowMessage('kann Text nicht schreiben'); end;
.... |
hier kannst mal schauen, vielleicht haben sie dort noch andere für ein 4x40LCDs
www.channaa.com/html...232_lcd_adapter.html
Moderiert von raziel: Code- durch Delphi-Tags ersetzt.
|
|
Marekventur
Beiträge: 72
|
Verfasst: Fr 25.03.05 21:06
@Adrian: Hast du Win XP? Wenn ja, dann würde mich dein Project sehr interesssieren. Vielleicht kannst du ja mal die Hauptunit hier posten...
@Yasso: Danke für den Code, aber es scheint, als wäre der Code nur für Win 9x/me geeignet (Keine direkte Hardwareansteuerung mehr unter 2000/XP)
Mich würde interessiern: Funktioniert das einfach so? Ohne dass du Steuerzeichen senden musst? Geht dass dann nur mit dem Modul?
|
|
Yasso
Beiträge: 35
|
Verfasst: Sa 26.03.05 14:21
hi,
doch, das funktioniert auch unter XP.
Wenn du Text senden willst, dann benutzt du "WRITELN", d.h. das String wird automatisch mit CR (#13) und LF (#10) abgeschlossen (das sind auch Steuerzeichen).
Wenn du z.B. den Cursor setzen willst, dann sendest du folgendes:
...
writeln(#27,#111,#15);
...
#27 : ESC (Steuerzeichen)
#111 : Code (oder auch ein 'o') (Befehl)
#15 : entspricht 1.Zeile 16.Spalte (Daten)
das ganze wird automatisch mit CR und LF abgeschlossen. (Steuerzeichen)
_________________ Yasso
|
|
Adrian
Beiträge: 314
|
Verfasst: Sa 26.03.05 18:07
Servus!
Ja, ich benutze WindowsXP, und das Demoprogramm sieht so aus:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201:
| unit LcdDemoUnit1;
interface
uses Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, ZlPortIO, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure Schreiben(Sender: TObject); procedure FormDblClick(Sender: TObject); private public end;
var Form1: TForm1; Abbruch: Boolean=False;
implementation
{$R *.dfm}
procedure Warte(us : Longint); var Aufloes, QueryStart, QueryStop : TLargeInteger; Dauer : Real; begin QueryPerformanceFrequency(Aufloes); QueryPerformanceCounter(QueryStart); repeat QueryPerformanceCounter(QueryStop); Dauer:=1000000*((QueryStop-QueryStart)/Aufloes); until Dauer>=us; end;
function SchreibLCD(Kommando :String):PChar; var Pause: Longint; RegisterAuswahl: Integer; KommandoDaten: Integer; begin Pause:=500; Result:='Schreiben'; if StrToInt(copy(Kommando,1,1))<2 then begin RegisterAuswahl:=0; end else RegisterAuswahl:=1; KommandoDaten:=StrToIntDef('$'+copy(Kommando,2,2),0);
if RegisterAuswahl=0 then begin PortWriteB($37A,$09); Warte(Pause); PortWriteB($37A,$0B); Warte(Pause); PortWriteB($37A,$0F); Warte(Pause); PortWriteB($378,KommandoDaten); Warte(Pause); PortWriteB($37A,$0B); Warte(Pause); PortWriteB($37A,$09); Warte(Pause); end else begin PortWriteB($37A,$08); Warte(Pause); PortWriteB($37A,$0A); Warte(Pause); PortWriteB($37A,$0E); Warte(Pause); PortWriteB($378,KommandoDaten); Warte(Pause); PortWriteB($37A,$0A); Warte(Pause); PortWriteB($37A,$08); Warte(Pause); end; end;
procedure TForm1.Schreiben(Sender: TObject); begin SchreibLCD('001'); SchreibLCD('038'); SchreibLCD('00C'); SchreibLCD('006'); SchreibLCD('080'); SchreibLCD('244'); SchreibLCD('261'); SchreibLCD('273'); SchreibLCD('220'); SchreibLCD('269'); SchreibLCD('273'); SchreibLCD('274'); SchreibLCD('220'); SchreibLCD('0C0'); SchreibLCD('26E'); SchreibLCD('275'); SchreibLCD('272'); SchreibLCD('220'); SchreibLCD('265'); SchreibLCD('269'); SchreibLCD('26E'); SchreibLCD('265'); Warte(2000000); SchreibLCD('001'); SchreibLCD('080'); SchreibLCD('220'); SchreibLCD('220'); SchreibLCD('254'); SchreibLCD('265'); SchreibLCD('273'); SchreibLCD('274'); SchreibLCD('261'); SchreibLCD('26E'); SchreibLCD('0C0'); SchreibLCD('27A'); SchreibLCD('265'); SchreibLCD('269'); SchreibLCD('267'); SchreibLCD('265'); SchreibLCD('221'); SchreibLCD('220'); SchreibLCD('220'); repeat Application.ProcessMessages; until Abbruch; SchreibLCD('001');end;
procedure TForm1.Button1Click(Sender: TObject); begin if ZLIOStarted=True then begin Schreiben(nil); end else begin MessageDlg('kein Treiber',mtInformation,[mbOK],0); end; end;
procedure TForm1.FormDblClick(Sender: TObject); begin Abbruch:=True; end;
end. |
Die Umsetzung der Zeichen in der Prozedur "Schreiben" ist natürlich noch verbesserungsbedürftig, aber es war nur eine Demo, damit ich überhaupt mal was rausbekommen habe. Danach habe ich mich auf die Ansteuerung über USB gemacht, weswegen das sowie die Implementierung von Laufschriften und die Generierung von Sonderzeichen nicht mehr da drin ist, dafür aber die Verwendung von ZlPortIO demonstriert wird. Das stellt eine der Möglichkeiten dar, wie man unter XP auf die parallele Schnittstelle zugreifen kann, näheres dazu findet einem die Suche im Internet.
Solltest Du Verständnisprobleme haben, dann scheue Dich nicht, Fragen zu stellen, lediglich mit der Antwort kann es dauern, als Modembenutzer bin ich nicht dauernd online.
Gruß,
Adrian
|
|
Marekventur
Beiträge: 72
|
Verfasst: So 27.03.05 13:32
Vielen Dank!
Ich hab den Code aber leider nicht so zum Laufen gebracht..... (D3 und TLargeInteger....) Hab ihn angepasst, funktioniert trotzdem nicht..... Aber die Kommentare sind sehr Hilfreich!
Ich habe im Internet (LCDHype) noch einen Code gefunden, den ich auch modifiziert habe. Dieser funktioniert mit den ersten beiden Zeilen des Displays (1. Controller), d.h. ich kann Text ausgeben und löschen, etc. Ich poste ihn mal hier.
Ich bin gerade dabei, das "beste aus beiden Codes" zusammenzustricken, damit ein funktionierender 2-Controller-Code herrauskommt. Dann poste ich den nochmals hier.... Wie gesagt, ich habe noch eine E2-Pin... WEiß jemand, wie ich den ansprechen muss, bzw. was ich ändern muss?
@Adrian:
Adrian hat folgendes geschrieben: | Solltest Du Verständnisprobleme haben, dann scheue Dich nicht, Fragen zu stellen, lediglich mit der Antwort kann es dauern, als Modembenutzer bin ich nicht dauernd online. |
Ich leide mit dir (Bei uns liegt noch kein DSL.....)
Code der Unit (sauber getrennt *g*):
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82:
| unit lcdhd;
interface uses Windows; const port = 888; Exectime = 40; AddressMode = 'HD44780'; Width = 27; Height = 4; LCDAddr = 64; procedure LCD_SendToController(Value : Byte); procedure LCD_SendToMemory(Value : Byte); procedure LCD_SetOutputAdress(x,y : integer); procedure LCD_Init;
function DlPortReadPortUchar(Port : Integer) : Byte; stdcall; external 'DLPORTIO.DLL'; procedure DlPortWritePortUchar(Port : Integer; Value : Byte); stdcall; external 'DLPORTIO.DLL';
implementation
procedure Wait(value : Integer); var i : Integer; begin for i := 0 to value do DLPortReadPortUChar($220); end;
procedure Send(Port,High,Low,Value,Exectime : integer); begin DlPortWritePortUchar(port+2,low); Wait(exectime); DlPortWritePortUchar(port+2,high); Wait(exectime); DlPortWritePortUchar(port,Value); Wait(exectime); DlPortWritePortUchar(port+2,low); Wait(exectime); end; procedure LCD_SendToController(Value : Byte); begin Send(Port,2,3,Value,Exectime); end;
procedure LCD_SendToMemory(Value : Byte); begin Send(Port,6,7,Value,Exectime); end;
procedure LCD_SetOutputAdress(x,y : integer); begin if (y<=3) then Send(Port,2,3,128+LCDAddr+x,Exectime); end;
procedure LCD_SetDisplayAddress(Value : Byte); begin end;
procedure LCD_Init; begin
LCD_SendToController(56);
LCD_SendToController(12); LCD_SendToController(6); LCD_SendToController(1);
sleep(10); end;
end. |
Und nun der Aufruf:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47:
| unit Unit1;
interface
uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, lcdhd, StdCtrls;
type TForm1 = class(TForm) Button1: TButton; procedure Button1Click(Sender: TObject); procedure FormKeyPress(Sender: TObject; var Key: Char); procedure FormCreate(Sender: TObject); private public end;
var Form1: TForm1;
implementation
{$R *.DFM}
procedure TForm1.Button1Click(Sender: TObject); var i: Integer; begin for i := 0 to 100 do LCD_SendTomemory(56); end;
procedure TForm1.FormKeyPress(Sender: TObject; var Key: Char); begin LCD_SendTomemory(Ord(Key)); end;
procedure TForm1.FormCreate(Sender: TObject); begin LCD_Init; end;
end. |
Moderiert von raziel: Code- durch Delphi-Tags ersetzt.
|
|
Marekventur
Beiträge: 72
|
Verfasst: So 27.03.05 14:07
Sorry, ich hab auch gerade gemerkt, das meine Verlötung anders war. Ich hba nun das richtige Schema eingestellt (s.O.).
An welcher Stelle in meinem Code spreche ich den E1 an ? Da müsste ich ja einfach den anderen Pin für E2 angeben und ich könnte den 2.Teil ansprechen..... (*theoretisch*)
|
|
Marekventur
Beiträge: 72
|
Verfasst: So 27.03.05 19:45
So, es war nicht leicht, aber jetzt funktioniert alles :
Die Steruerunit sieht so aus:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172:
| unit lcd;
interface
uses Windows; const port = 888; Exectime = 40;
type TCharData = record position : byte; data : array[0..4,0..7] of byte; end;
procedure LCD_Init(ControllerCount: Integer); procedure LCD_Command(Value : Byte); procedure LCD_Write(Value : Char); procedure LCD_Row(I: Integer); procedure LCD_Clear; procedure LCD_SetOwnChar(SendChar : TCharData; ControllerNo: Integer);
function DlPortReadPortUchar(Port : Integer) : Byte; stdcall; external 'DLPORTIO.DLL'; procedure DlPortWritePortUchar(Port : Integer; Value : Byte); stdcall; external 'DLPORTIO.DLL';
implementation
var Controller: Integer;
procedure Wait(value : Integer); var i : Integer; begin for i := 0 to value do DLPortReadPortUChar($220); end;
procedure Send(Port,High,Low,Value,Exectime : integer); begin DlPortWritePortUchar(port+2,low); Wait(exectime); DlPortWritePortUchar(port+2,high); Wait(exectime); DlPortWritePortUchar(port,Value); Wait(exectime); DlPortWritePortUchar(port+2,low); Wait(exectime); end; procedure LCD_Command(Value : Byte); begin Send(Port,0+1*Controller,1+8*Controller,Value,Exectime); end;
procedure LCD_Write(Value : Char); begin Send(Port,4+1*Controller,5+8*Controller,Ord(Value), Exectime); end;
procedure LCD_Init(ControllerCount: Integer); var i: Integer; begin for i := 0 to ControllerCount - 1 do begin Controller := i; LCD_Command(60); LCD_Command(12); LCD_Command(6); LCD_Command(1); sleep(10); end; Controller := 0; end;
procedure LCD_Row(I: Integer); begin case i of 0:begin Controller := 0; LCD_Command(128); end; 1:begin Controller := 0; LCD_Command(192); end; 2:begin Controller := 1; LCD_Command(128); end; 3:begin Controller := 1; LCD_Command(192); end; end; end;
procedure LCD_Clear; begin Controller := 1; LCD_Command(1); Controller := 0; LCD_Command(1); end;
procedure LCD_SetOwnChar(SendChar : TCharData; ControllerNo: Integer); var x,y,line,z : byte; begin Send(Port,0+1*ControllerNo,1+8*ControllerNo,64+(8*SendChar.position),Exectime); for y:=0 to 7 do begin z:=1; line := 0; for x:=4 downto 0 do begin line := line + SendChar.data[x,y]*z; z:=z*2; end; Send(Port,4+1*ControllerNo,5+8*ControllerNo,line, Exectime); sleep(5); end; end;
end. |
Die Benutzung ist oben erklärt.
Vielen Dank an ViRuSTriNiTy von www.lcdhype.de.vu.
Ich hoffe, der Code ist nützlich.
Moderiert von raziel: Code- durch Delphi-Tags ersetzt.
|
|
|