PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Relai per Software Steuern.



PyroMUC
12.05.04, 19:38
Hallo.

Ich hab mit Hilf der Suchfunktion ein Programm gefunden wie ich z.B Relai 3 einschalten kann.



#include <stdio.h>
#include <unistd.h> /* needed for ioperm() */
#include <sys/io.h> /* for outb() and inb() */
#include <stdlib.h>

#define DATA 0x378

int main(int argc, char* argv[]) {

if (ioperm(DATA,3,1)) {
printf("Du bist nicht berechtigt auf LPT1 zuzugreifen\n");
exit(1);
}

printf("test %s \n", argv[1]);

outb(4, DATA);

return (0);
}

Nur wie schalte ich einen bestimmten Port einzeln aus?
Mit
outb(00, DATA);
schalte ich ja alle aus.
Ich will aber wenn z.B. 3 und 7 an sind nur 3 ausschalten.

PyroMUC

derguteweka
12.05.04, 21:42
Moin,

Das ist n bisschen tricky, weil du nicht mehr zuverlaessig feststellen kannst, welche Relais an dem Port gerade an oder aus sind. Wenn man den Port zurueckliest (mit inb) kann irgendwas drinnenstehen, kann zufaellig auch das richtige sein, ist aber nicht sicher. Deshalb brauchst du eine kleine Hilfsvariable (hv), die immer den Stand des ports wiederspiegelt, d.h. sowas:

static unsigned char hv;

//...
// Setzen von .z.b. Relais an bit2
hv |= 0x04
outb(hv, DATA)

//...
// Ruecksetzen von Relais an bit 2
hv &= ~ 0x04
outb(hv,DATA)


Dann klappts auch mit dem Loeschen...

Gruss
WK

PS: Ich weiss nicht wie maechtig du der Sprache C bist, deshalb ne kleine Zeichenerklaerung:
| ist eine logische OR Verknuepfung
& ist eine logische AND Verknuepfung
~ ist ein bitweises invertieren

PyroMUC
13.05.04, 07:59
Servuz.

Ja mit der mächtigkeit happerts noch gewalltig :D

Wie Rechne ich das um? 0x04
outb(4, DATA) = outb( 0x04, DATA) oder wie?

PyroMUC

derguteweka
13.05.04, 10:49
Moin,

Oh, sorry - klar 0x4==0x04==4==04 (und == bedeutet: sind gleich; waehrend = in C eine Zuordnung ist, z.b. A=5) Ist alles das selbe - weil 4 ne kleine Zahl ist. Das 0x davor bedeutet, dass die Angabe danach hexadezimal (16er System) ist, ohne 0x ist es dezimal(10er System), aber um die Verwirrung zu steigern, bedeutet bei C eine vorangestelle 0 alleine, dass danach die Zahl oktal(8er System) ist.
Also z.B. mit einer groesseren Zahl 35:
35==0x23==043 (dez.,hex.,oktal)
Fuer solche Bitfummeleien, wie den Relais an Portpins ist hexadezimal oft leichter zu verstehen (immer 4 bit ergeben eine Hexziffer), als dezimal; naja ist halt auch Uebungssache, richtig heftig wirds erst bei 32 bit breiten Ports oder Registern, da ist mit dezimal dann wirklich Schluss.

Gruss
WK

E S
14.05.04, 11:53
Hi,

das zurücklesen mit inportb ist bei mir aber immer gelungen!

Zur erklärung:
Jedes Bit des Registers stellt ein relais da. Jedes Bit hat eine wertigkeit.

2^n (2 hoch n) wobe n die Bitnummer ist:

0 = 1
1 = 2
3 = 4
3 = 8
4 = 16
5 = 32
6 = 64
7 = 128

Möchte man also Bit 3 und 0 auf logisch '1' haben, muss man 8+1 rechnen, also eine 9 in das register schreiben.

Um Relais unabhängig zu schalten muss man binäre logikverknüpfungen machen:
OR um Bits zu setzen
UND um Bits zu löschen (Maskieren)
und XOR um zu toggeln (geziehltes invertieren, also Zustand umschalten)

Liest man mit inportb den Zustand ein (oder per Merkervariable behalten), kann man den Wert logisch manipulieren und per outportb in das Register schreiben.

Bei der UND-Verknüpfung bleiben nur die Bits stehen, die in beiden Eingangsvariablen (dem Merker und der Maske) gesetzt sind. Alle Bits, die auch in der Maske nicht gesetzt sind werden auf logisch '0' geschaltet, die anderen abhängig von der Merkervariable. So kann man einzelne Relais unabhängig von den anderen ausschalten.

Bei der OR-Verknüpfung sind alle Bits gesetzt, die in einer oder beiden Eingangsvariablen gesetzt sind. So schaltet man Relais dazu.

Beim XOR ist das Ausgangsbit gesetzt, wen genau eine Eingangsvariable an der Stelle logisch 1 hat. Setzt man in der Maske eine 1, und das Relais ist schon an, so wird es ausgeschaltet, da beide Eingangsvariablen dort eine 1 haben. War es aus, so wird es eingeschaltet, da nur eine 1 im Eingang ist.

Gruß
Elmar

derguteweka
14.05.04, 13:34
Moin,
@ES: Ob das zuruecklesen klappt, haengt stark damit zusammen, mit welcher Hardware der Parallelport aufgbaut ist. Bei aeltern (ISA-Karten) kanns passieren, dass es nicht funktioniert, weil der Port aus einem 74374 oder aehnlich besteht. Den kann man halt nicht ueber die selben Leitungen wieder auslesen :-( Dafuer sind diese Dinger dann besser "bebastelbar" als wenn der Port fest aufm MoBo sitzt...

Gruss
WK

E S
14.05.04, 13:54
Hi,

vielleicht zur 8088er Zeit, bisher habe ich immer auslesen können, egal was das für ne Schüssel war (ok, älter als 286 nicht getestet). Das Einlesen des Nachbarregisters klappt ja auch (Inputregister). So gut wie alle Karten erlauben das wiedereinlesen - mir ist in langjähriger Programmierung von Steuerungen über den Parallelport noch nie eine Karte untergekommen, die nicht den Zustand der Eingangsleitungen auslesen könnte. Auch ist das einlesen in den Parport-Specs spezifiziert.

Bei modernen Rechnern kann man übrigens die Datenleitungen auch als Input benutzen (Für Scanner, Speichermedien ECP/SPP)

Gruß
Elmar