Forum: PC-Programmierung Display über Parallelport ansteuern mit C (unter Linux)


von wurstbonbon (Gast)


Angehängte Dateien:

Lesenswert?

Hallo!
ich würde gerne interessehalber ein SDA5708-Display über den PC (linux) 
ansteuern.
Das Display nimmt seriell Daten entgegen, während Load und reset low 
sind. Bei jeder steigenden Flanke von sdclk wird der aktuelle zustand, 
der am dateneingang liegt in ein register gespeichert, solange bis 8bit 
voll sind, dann wird load auf 1 geschaltet und der displaycontroller 
wertet die 8-bit, die nun parallel in den registern liegen, aus.
Dafür würde sich die Parallele Schnittstelle am besten eignen, oder?

Jedoch habe ich noch ein verständnisproblem mit der schnittstelle:
Die Parallele Schnittstelle hätte 8 Datenleitungen, dann könnte man ja 
eine für load, eine für reset, eine für sdclock und eine für daten 
verwenden, oder?
allerdings habe ich dann noch das problem, dass die daten seriell ins 
displaycontrollerregister geschrieben werden sollen, jedoch die 
parallelschnittstelle beispielsweise eine zahl 101 nur gleichzeitig auf 
3 datenausgängen sendet. Es ist also nicht möglich jeden einzelnen 
datenausgang der parallelen schnittstelle seriell anzusteuern (also dass 
die 101 hintereinander auf nur einen datenausgang anliegen, während die 
anderne ausgänge andere sachen senden können), richtig?

Also müsste ich jeden sendezyklus einzeln beschreiben? Wenn man pro 
datenbit 2 sendezyklen annimmt, also quasi 16 zeilen
outb(xxxxxxxx,BASEPORT);
wobei beispielsweise das 1.x load darstellen soll, das 2.x sdclk usw?

Nachdem aber Load low-aktiv ist, könnte man nicht einfach anstatt den 
datenausgang einen hardwareinvertierten ausgang (z.b. strobe-ausgang) 
verwenden?

auf die anderen parallelen-leitungen (busy, strobe, etc) muss ich keine 
rücksicht nehmen, weil ich nur in eine richtung (vom pc zum display) 
senden will, oder?

Ich hoffe ich habe mich einigermaßen verständlich ausgedrückt, kenne 
mich noch nicht so richtig aus ;-)

Viele Grüße
Michael

von Karl H. (kbuchegg)


Lesenswert?

wurstbonbon schrieb:

> Jedoch habe ich noch ein verständnisproblem mit der schnittstelle:
> Die Parallele Schnittstelle hätte 8 Datenleitungen, dann könnte man ja
> eine für load, eine für reset, eine für sdclock und eine für daten
> verwenden, oder?

Yep.

> allerdings habe ich dann noch das problem, dass die daten seriell ins
> displaycontrollerregister geschrieben werden sollen, jedoch die
> parallelschnittstelle beispielsweise eine zahl 101 nur gleichzeitig auf
> 3 datenausgängen sendet.

Dazu hast du deine load und sdclock Leitungen.
Es ist dann dein Bier ein Byte durch wackel an den ensprechenden Pins in 
das Display zu shiften.

> Es ist also nicht möglich jeden einzelnen
> datenausgang der parallelen schnittstelle seriell anzusteuern (also dass
> die 101 hintereinander auf nur einen datenausgang anliegen, während die
> anderne ausgänge andere sachen senden können), richtig?

Richtig.
Aber du kannst ja jedes Datenbit auf der Schnittstelle einzeln 
ansteuern. Und wenn du das in der richtigen Reihenfolge machst, dann 
werden da dann doch die Bits 'seriell' rausgeshiftet.

> Also müsste ich jeden sendezyklus einzeln beschreiben? Wenn man pro
> datenbit 2 sendezyklen annimmt, also quasi 16 zeilen
> outb(xxxxxxxx,BASEPORT);
> wobei beispielsweise das 1.x load darstellen soll, das 2.x sdclk usw?

Ich versteh jetzt nicht, was du uns hier sagen willst.

> Nachdem aber Load low-aktiv ist, könnte man nicht einfach anstatt den
> datenausgang einen hardwareinvertierten ausgang (z.b. strobe-ausgang)
> verwenden?

Oder ganz einfach die entsprechende Leitung auf 0 setzen wenn sie 0 sein 
soll und auf 1 setzen, wenn sie 1 sein soll.

> auf die anderen parallelen-leitungen (busy, strobe, etc) muss ich keine
> rücksicht nehmen, weil ich nur in eine richtung (vom pc zum display)
> senden will, oder?

Die interessieren dich nicht mehr die Bohne.
Die parallele Schnittstelle ist dann keine parallele Schnittstelle im 
eigentlichen Sinne mehr, sondern für dein Programm eine Möglichkeit, wie 
dein Programm gezielt mit ein paar Leitungen Nullen und Einsen auf jeder 
der Leitungen erzeugen kann. Was diese Nullen und Einsen bedeuten und in 
welcher Reihenfolge sie geschaltet werden, obliegt einzig und alleine 
deinem Programm. Da mischt sich dann niemand mehr rein.

von wurstbonbon (Gast)


Lesenswert?

Danke! Das hat mir sehr stark geholfen! Ein wenig habe ich nun schon 
rumexperimentiert, dabei ist folgender C-Code herausgekommen, welcher im 
Prinzip funktionstüchtig sein müsste.
Leider habe ich im Moment das Display nicht zur Hand und habe deshalb 
die Ausgabe nicht auf den parallelport geschrieben, sondern als 
textausgabe, quasi zum händischen debuggen. die printfs werden später 
durch outb() ersetzt.
Hier mal quasi nur der teil, der den control-register ansteuert (die 
anderen teile für adress-register und zeilen-register wären ähnlich).

ohne dass ihr jetzt groß in die thematik einsteigt, ist das guter code? 
wie könnte man ihn grob verbessern?
übrigens, die wait-befehle fehlen noch an diversen stellen ;)
1
..
2
#define LPT 0x378  /* standardadresse 0x378 (LPT1). fuer lpt2: 0x278, fuer lpt3: 0x3bc */
3
4
int load=0, data=0, sdclk=0, rst=0, out=0;
5
6
/*
7
pdata7,6,5,4 = 0
8
pdata3 (pin5) = rst = 0
9
pdata2 (pin4) = data
10
pdata1 (pin3) = sdclk
11
pdata0 (pin2) = load
12
*/
13
14
void control_reg(int helligkeit)  //halbe helligkeit: 1, volle helligkeit: leer
15
{
16
  int  data_temp, i=0;
17
  if (helligkeit==0) data=0xC0; /*11000000;*/ else data=0xC2; /*11000010:*/ 
18
19
   
20
  out=0; printf("1. %X\n", out); //  outb(0x0,LPT);  
21
22
  for (i=0;i<=7;i++)
23
  {
24
    //sdclock bit auf 0 setzen
25
    out=out&0xD;     printf("2. %X\n", out);  //outb(out,LPT);
26
    
27
  
28
    //neues äußerstes zeichen bilden, schreiben
29
    data_temp=data>>i;
30
    data_temp=data_temp&0x1; 
31
    data_temp=data_temp<<2;  //data ist 3. bit
32
    if (data_temp==0x4) out=out|data_temp; else out=out&0xb;
33
    printf("3. %X\n", out);  //outb(out,LPT);
34
35
36
    // wait - sdclock bit 1 setzen - wait  
37
    out=out|0x2;     printf("4. %X\n", out); //outb(out,LPT);
38
  
39
  }
40
}
41
42
43
void reg_voll()
44
{
45
  //outb(0x1,LPT);
46
  out=0x1; printf("0. %X\n", out);
47
48
  //wait time  
49
}
50
51
52
53
54
int main(int argc, char *argv[])
55
{
56
  reg_voll();
57
  control_reg(1);  //halbe helligkeit
58
59
}

viele grüße

von Μαtthias W. (matthias) Benutzerseite


Lesenswert?

Hi

mit outb() wirst du unter Linux nicht viel Erfolg haben. Direkte 
Hardwarezugriffe sind unter ernst gemeinten PC-Betriebssystemen nicht 
möglich. Schau dich mal nach /dev/parport* um. Damit sollte es gehen.

Matthias

von wurstbonbon (Gast)


Angehängte Dateien:

Lesenswert?

Hallo
inzwischen funktioniert die Ansteuerung ganz gut, siehe Bild.

Mein userspace-programm kam übrigens mit outb() zurecht, allerdings 
benötigte es die anweisung
1
ioperm();
sonst gabs einen seg fault

Falls jdm interesse am code hat kann ich ihn hochladen, noch ist er aber 
nicht perfekt.

viele Grüße

von Andreas K. (Firma: keine) (knuppel)


Lesenswert?

Moin.

Mich würde der Code interessieren.

mfg knuppel

von Rolf Magnus (Gast)


Lesenswert?

wurstbonbon schrieb:
> Mein userspace-programm kam übrigens mit outb() zurecht, allerdings
> benötigte es die anweisung
> ioperm();

Besser wäre aber, statt dem ioperm-Gefrickel gleich das parport-Device 
zu verwenden.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.