Autor Beitrag
decoolegangsta
Hält's aus hier
Beiträge: 5

Win95, Win98, WinME, WinXP, WinVista
Delphi 2005 Personal, Delphi7
BeitragVerfasst: Mo 17.10.05 21:40 
Hallo ihr!

Ich programmiere seit einiger Zeit ein Programm welches mir ermöglicht mittels I²C und dem PCF8574 über die parallele Schnittstelle Ausgänge anzusteuern.
Diese sollen dann verschiedene Lampen ein bzw. ausschalten.
Das ganze ist als Eisenbahnlichtsoftware gedacht.
Das Programm dafür ist kein Problem, das läuft alles ohne Probleme, jedoch macht mir die Ansteuerung des LPT zu schaffen.
Um den PCF8574 schalten zu lassen nutze ich den bekannten Ansteuerungscode, der direkt im Programm geschrieben ist, für den LPT-Zugriff nutze ich die DlPortIO.sys (bzw. dll), jedoch schalten die PCF in keinster Weise.
Das Interface und die Ausgabeplatinen sind in Ordnung, da ich mit einem Extra-Programm die schon unter WIN98 angesteuert habe.
Aber unter WINXP funktioniert nichts.
Ich habe aber auch schon andere DLLs und Sys-"es" ausprobiert (PORT.DLL, IO.DLL, Zl.PORTIO, I2C-Port.dll, ZlPortIO.sys ...)
Mit keiner DLL hat es funktioniert, mittlerweile weiß ich nicht mehr weiter, ich gehe erstmal nicht davon aus, das mein Programm Fehler aufweist (kann natürlich auch sein), da ich nicht einmal Spannungsunterschiede (Messgerät) festellen kann.
Als letzes dachte ich dann, das die DlPortIO funktioniert, da ich beim ATMEL-Brennen (Mikrocontroller) unter WINXP auch die DlPortIO brauche (AT_Prog von Johann Aichinger), jedoch funktioniert dies nur, wenn ich vorher ein anderes Programm geöffnet habe (PONYPROG2000), deshalb ging ich davon aus, das die DlPortIO erst geladen werden muss, also habe ich diese jetzt als letzes in meinem Programm genommen und PONYPROG ausgeführt, in der Hoffnung das jetzt die DLL geladen wäre, aber nichts passierte.
Das alles habe ich bis jetzt in einer Extra Unit (bzw. Projekt) versucht (also nicht in meinem Programm, welches diesen Ansteuerungscode jedoch erhalten soll).

Ich hoffe ihr könnt mir helfen.

(Programmcode füge ich hier ein, da ich nicht weis, wie ich es als Extra "Code" anzeigen lassen kann)

ausblenden volle Höhe 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:
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:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics,
  Controls, Forms, Dialogs, StdCtrls, ExtCtrls;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    Label1: TLabel;
    Label2: TLabel;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

Procedure DELAY (Port : Word); stdcallexternal 'port.dll';
Procedure DELAYUS (Port : Word); stdcallexternal 'port.dll';
function  DlPortReadPortUchar(Port : Integer) : Byte; stdcallexternal 'DLPORTIO.DLL';
procedure DlPortWritePortUchar(Port : Integer; Value : Byte); stdcallexternal 'DLPORTIO.DLL';

{$R *.dfm}

{------------------------PROCEDURE-START------------------------}

Procedure I2C_Start;  {I2C - START}

Begin
   DlPortWritePortUchar(956$81);  // SCL = 1
   DlPortWritePortUchar(958$00);  // SDA = 1
   DELAY(5);
   DlPortWritePortUchar(958$01);  // SDA = 0
   DELAY(5);
   DlPortWritePortUchar(956$80);  // SCL = 0
   DELAY(5);
End;

{-----------------------------------------------------------------}

Procedure I2C_Stop;   {I2C - STOP}

Begin
   DlPortWritePortUchar(958$01);  // SDA = 0
   DELAY(5);
   DlPortWritePortUchar(956$81);  // SCL = 1
   DELAY(5);
   DlPortWritePortUchar(958$00);  // SDA = 1
   DELAY(5);
End;

{-----------------------------------------------------------------}

Procedure I2C_WrAck (NACK : Boolean);

Begin
   If   NACK
   Then DlPortWritePortUchar(958$00)  // SDA = 1
   Else DlPortWritePortUchar(958$01); // SDA = 0
   DELAY(5);
   DlPortWritePortUchar(956$81);      // SCL = 1
   DELAY(5);
   DlPortWritePortUchar(956$80);      // SCL = 0
   DELAY(5);
   DlPortWritePortUchar(958$00);      // SDA = 1
   DELAY(5);
End;

{-----------------------------------------------------------------}

Procedure I2C_WaitAck;   {I2C - ACK}

Begin
   DlPortWritePortUchar(958$00);  //SDA = 1
   DlPortWritePortUchar(956$81);  //SCL = 1
   DELAY(5);
   If DlPortReadPortUchar($957and $40 = 0 then
   DlPortWritePortUchar(956$80Else Application.ProcessMessages;  //SCL = 0
   DELAY(5);
End;

{REPEAT-UNTIL Schleife habe ich raus genommen, da mein PC dort immer hängen geblieben ist und eine CPU-Auslastung von 100% hatte}
{-----------------------------------------------------------------}

Procedure I2C_WrData (X : Byte);  {I2C - WRITE}

Var
   Counter, Mask, Portwert: Byte;

Begin
   Mask := 128;
   For Counter := 1 To 8 Do begin
      If   (X And Mask) = Mask then Portwert:= 0 Else Portwert:= 128;
      DlPortWritePortUchar(958, Portwert);
      DELAY(1);
      DlPortWritePortUchar(956$81);  // SCL = 1
      DELAY(1);
      DlPortWritePortUchar(956$80);  // SCL = 0
      DELAY(1);
      Mask := Mask div 2;
   End;
   DELAY(1);
End;

{-----------------------------------------------------------------}

Function I2C_RdData : Byte;   {I2C - READ}

Var     Counter : Integer;
        X       : Integer;

Begin
   X := 0;
   DlPortWritePortUchar(958$00);     // SDA = 1
   DELAY(5);
   For Counter := 1 To 8 Do
   Begin
      DlPortWritePortUchar(956$81);  // SCL = 1
      DELAY(5);
      X := X Shl 1;
      If DlPortReadPortUchar(957And $40 <> 0 Then Inc (X);
      DELAY(5);
      DlPortWritePortUchar(956$80);  // SCL = 0
      DELAY(5);
   End;
   Result := X;
End

{------------------------PCF8574-ADR64-ALLON------------------------}

Procedure PCF;
Begin
   I2C_Start;
   I2C_WrData (64);
   I2C_WaitAck;
   I2C_WrData (255);
   I2C_WaitAck;
   I2C_Stop;
end;

{------------------------PCF8574-ADR64-ALLOFF-----------------------}

Procedure PCF2;
Begin
   I2C_Start;
   I2C_WrData (64);             
   I2C_WaitAck;
   I2C_WrData (0);
   I2C_WaitAck;
   I2C_Stop;
end;

{------------------------BUTTONS------------------------}

procedure TForm1.Button1Click(Sender: TObject);
begin
PCF;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
PCF2
end;

{--------------------------END-------------------------}

end.


Gruß
Patrick

Moderiert von user profile iconraziel: Delphi-Tags hinzugefügt und BBCode aktiviert.
digi_c
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1905

W98, XP
D7 PE, Lazarus, WinAVR
BeitragVerfasst: Mo 17.10.05 22:17 
Das Problem wird sein, dass diese DLLs probieren direkt auf den port zu schreiben(z.B.378h) was unter NT Ableger OSsen strengstens verboten und nicht möglich ist. Stattdessen muss der Zugriff über die WINAPI gesteruert werden(Schnittstellen verhalten sich wie Dateien)

Im Elektor war das mal an dem Beispiel zum Zugriff auf den COM Port sehr ausführlich erklärt.

Ich habe auch mit I²C experimentiert es gibt von dem einen Deutschen eine DLL mit der das Problemlos funktionierte und die bereits höhere Funktionen für Porttreiber/LCDs/... mitbrachte, kann dir nächste Woche genaueres sagen...
decoolegangsta Threadstarter
Hält's aus hier
Beiträge: 5

Win95, Win98, WinME, WinXP, WinVista
Delphi 2005 Personal, Delphi7
BeitragVerfasst: Di 18.10.05 18:41 
Danke erstmal!

Mich verwundert bei der Sache, überall, wenn ich im Web nach WinXP und LPT gesucht habe wurde dieses bekannte Problem genannt, das WinXP (NT) keine Portzugriffe erlaubt (nur mit Anmeldung..., ist mir auch bekannt) und überall steht dann, das man dann die schon oben erwähnten DLLs nutzen soll, damit sollte es funktionieren. (DLPORTIO, IO.DLL...)
Wie gesagt da funktionierte leider nichts von, muss ich diese DLLs vorher irgendwie laden per Code in Delphi oder über Windows?

Gruß
Patrick
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Di 18.10.05 18:58 
Die DLPortIO.dll kommt nicht alleine. Da ist auch noch eine .sys Datei dabei. Und im Normalfall auch eine Install.exe, die den Kernel-Mode Treiber installiert. Nach einem Neustart sollte dann eigentlich die DLL den Treiber nutzen können.

Aber so viel ich weiß schwirren da einige unterschiedliche Zusammenstellungen im Internet herum.

Probiere einfach mal diese hier.

_________________
Ist Zeit wirklich Geld?
AndyB
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 1173
Erhaltene Danke: 14


RAD Studio XE2
BeitragVerfasst: Di 18.10.05 19:04 
Zitat:
Als letzes dachte ich dann, das die DlPortIO funktioniert, da ich beim ATMEL-Brennen (Mikrocontroller) unter WINXP auch die DlPortIO brauche (AT_Prog von Johann Aichinger), jedoch funktioniert dies nur, wenn ich vorher ein anderes Programm geöffnet habe (PONYPROG2000), deshalb ging ich davon aus, das die DlPortIO erst geladen werden muss, also habe ich diese jetzt als letzes in meinem Programm genommen und PONYPROG ausgeführt, in der Hoffnung das jetzt die DLL geladen wäre, aber nichts passierte.

Den Absatz habe ich übersprungen.

Kein Wunder dass das nicht funktioniert. Das selbe Problem hatte ich vor zwei Wochen auch. Auf 5 Rechnern ging mein Übertragungsprogramm, nur auf einem Rechner, der har genau so eingerichtet ist, wie die anderen 5, ging es nicht und meldete mir: Treiber kann nicht geladen werden.

Nach längeren vergeblichen Versuchen ist mir dann aufgefallen, dass auf genau diesem Rechner das Programm PonyProg installiert ist. Mit installiertem PonyProg konnte nur der Admin übertragen, einem eingeschänkten Benutzer war es untersagt. Aber ich werde gerade noch kleine Kinder als Admin an die Rechner lassen, so verrückt bin in nun auch wieder nicht. PonyProg entfernt, Rechner neugestartet, den DLPortIO Treiben aus der schon oben verlinkten ZIP-Datei installiert und den Rechner neugestartet und volà alles funktionierte, wie es sollte.

_________________
Ist Zeit wirklich Geld?
digi_c
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 1905

W98, XP
D7 PE, Lazarus, WinAVR
BeitragVerfasst: Di 18.10.05 20:14 
Och nicht doch bitte las den Kerneltreiber, das ist doch bei einer gut programmierten DLL unnötig, sry komm erst am WE nach hasue und kann dir den Link erst am MO posten, vielleicht findest du auf www.mikrocontroller.net was.
decoolegangsta Threadstarter
Hält's aus hier
Beiträge: 5

Win95, Win98, WinME, WinXP, WinVista
Delphi 2005 Personal, Delphi7
BeitragVerfasst: Do 20.10.05 17:51 
Hallo!

Danke erstmal für jegliche Hilfe,

das mit z.B. der Exe-Datei habe ich nie im Web gefunden, ich habe viele Seiten durch gesucht und auch oft z.B. die DlPortIO gefunden aber nie den Hinweis oder den Download einer Exe-Datei...

Gruß
Patrick
decoolegangsta Threadstarter
Hält's aus hier
Beiträge: 5

Win95, Win98, WinME, WinXP, WinVista
Delphi 2005 Personal, Delphi7
BeitragVerfasst: Sa 22.10.05 15:14 
Hallo!

So nun funktioniert alles so wie es soll, nach kompletter Überarbeitung des I2C-Codes kann ich nun meine PCF´s ansteuern.

Gruß
Patrick