Hi,
ich muss ein Progamm in C schreiben und damit eine serielle
Schnittstelle ansprechen. Ich wollte jetzt erstmal ein Testprogramm
schreiben und alle Pins auf High setzen und das mit dem Multimeter
überprüfen.
Dafür habe ich _outp(0x378, 1) verwendendet und das in einer
Endlosschleife laufen lassen. Leider gehen die Pins (habe es mit
mehreren gemacht) nicht auf High. Das ganze läuft unter win98, also
sollte Windows mit dem Befehl kein problem haben.
Muss ich den Port im Programm noch öffnen?
Was ist sonst mein Fehler?
Viele Grüße
Karin
Karin schrieb:> ich muss ein Progamm in C schreiben und damit eine serielle> Schnittstelle ansprechen. Ich wollte jetzt erstmal ein Testprogramm> schreiben und alle Pins auf High setzen und das mit dem Multimeter> überprüfen.
Was soll dieses Testprogramm bringen?
Das ist in etwa wie:
"ich muss lernen mit meinem Fahrrad zu fahren, will aber erst mal
probieren, ob die Räder auch an meinen Roller passen."
Das OS stellt Funktionalität bereit, mit der man über die Serielle
Schnittstelle kommunizieren kann.
Daran vorbei irgendwelche Pins zu setzen bringt überhaupt keinen
Erkenntnisgewinn für ersteren Anwendungszweck.
Hi,
danke für die antworten. Ich habe jetzt erstmal probiert mit diesem
Verfahren zu arbeiten:
http://www.mikrocontroller.net/articles/Ports_benutzen_%28Windows%29
Dazu habe ich noch zwei Fragen:
1. da das Programm unter 98 laufen soll muss ich giveio ja nicht
einzubeziehen oder? Was muss ich stattdessen in createfile einfügen?
2. Mit outb kann ich dann ja einfach die pins ansprechen oder? Müsste
ich das auch messen können, wenn ich einen auf High setze oder geht der
so schnell wieder runter, dass es nicht messbar ist mit einem
multimeter?
@ vlad(oder soll ich dich besser dracul nennen ;-)): Da ich blutige
anfängerin bin probiere ich immer möglichst in kleinen schritten mich
voran zu arbeiten. Da ich für das spätere programm die pins einzeln
ansprechen muss, will ich als erstes überprüfen, ob ich sie einzelnt auf
high setzen kann.
danke schonmal für die hilfe
karin
> Mit outb kann ich dann ja einfach die pins ansprechen oder?
Prinzipiell: Serielle Schnittstellen werden NICHT über direkte
I/O-Befehle angesteuert. Auch nicht unter den Frickel-Versionen von
Windows.
Das macht man auch unter den Frickel-Versionen mit den Funktionen der
Win32-API.
Für das "Bit-Banging" (also willkürliches Gewackel an
Handshakeleitungen) sind serielle Schnittstellen ziemlich ungeeignet.
Außerdem hat eine serielle Schnittstelle nur zwei dedizierte
Handshake-Ausgänge (DTR und RTS), damit lässt sich eh' nicht allzuviel
anfangen.
Die wesentlichen Punkte kannst Du dem Beispielprogramm von "Blackbird"
entnehmen, das funktioniert unter jeder Windows-Version seit NT3.1.
Was soll denn insgesamt erreicht werden? Nicht, daß Du Dich in
technische Fehlentscheidungen verrennst ..
Hi,
also ich muss ein altes Turbo Pascal programm in C schreiben.
Ausgangsport ist eine DB 15 (Com Port mit 15 pins). Das TB programm ist
nicht besonders kompliziert. Nur das die Pins direkt angesprochen werden
und dies anscheinend mit C nicht soleicht geht. Insgesamt muss ich acht
Pins ansprechen ( Adresse 3f8-3ff).
danke nochmal
Karin schrieb:> Nur das die Pins direkt angesprochen werden> und dies anscheinend mit C nicht soleicht geht.
das hat nichts mit C zu tun sondern mit den aktuellen Betriebssystemen.
Wenn du nur ein USB-Serielle schnittstelle hast dann gibt es überhaupt
keine IO-Adresse dafür mehr.
Es geht auch normalerweise ab Win2000 nicht mehr mit Turbopascal.
> Insgesamt muss ich acht> Pins ansprechen ( Adresse 3f8-3ff)
Die Acht Pins liegen in dem Byte an Adresse 0x378 im IO-Raum wobei jedes
Bit in diesem Byte einem Pin am Parallelport enspricht.Die
dahinterliegenden Adressen sind für was anderes zuständig oder auch
nicht.
3f8 ist ein Comport der hat keine 8 Pins zum ansprechen
guck mal hier
http://www.stanislavs.org/helppc/8250.html
Falls es doch der Parallelport sein soll dann so:
der 1. Paralleport liegt an adresse 378
Port 378 printer data output (readable)
|7|6|5|4|3|2|1|0| ports 278, 378, 3BC
| | | | | | | `---- data bit 0, hardware pin 2
| | | | | | `----- data bit 1, hardware pin 3
| | | | | `------ data bit 2, hardware pin 4
| | | | `------- data bit 3, hardware pin 5
| | | `-------- data bit 4, hardware pin 6
| | `--------- data bit 5, hardware pin 7
| `---------- data bit 6, hardware pin 8
`----------- data bit 7, hardware pin 9
Port 379 printer status register (Parallel Printer Port)
|7|6|5|4|3|2|1|0| ports 279, 379, 3BD
| | | | | | | `---- 1 = time-out
| | | | | `------- unused
| | | | `-------- 1 = error, pin 15
| | | `--------- 1 = on-line, pin 13
| | `---------- 1 = out of paper, pin 12
| `----------- 0 = Acknowledge, pin 10
`------------ 0 = busy, pin 11
Port 37A printer control register (Parallel Printer Port)
|7|6|5|4|3|2|1|0| ports 27A, 37A, 3BE
| | | | | | | `---- 1 = output data to printer, (pin 1)
| | | | | | `----- 1 = auto line feed, (pin 14)
| | | | | `------ 0 = initialize printer, (pin 16)
| | | | `------- 1 = printer reads output, (pin 17)
| | | `-------- 0 = IRQ disable,1=IRQ enable for ACK
`------------- unused
>> ... Insgesamt muss ich acht Pins ansprechen ( Adresse 3f8-3ff).
Das sind aber keine Pins, sondern Register: Steuerregister,
Datenregister, usw.
Die Serielle Schnittstelle hat nur 3 Ausgänge (TxD, RTS, DTR) und 5
Eingänge (RI, RxD, DCD, DSR, CTS).
Wird sie denn als serielle Schnittstelle betrieben oder als
Ersatz-Parallel-Port?
Blackbird
danke schonmal für eure antworten.
@Blackbird: ich offenbare jetzt wohl meine unwissenheit: Aber ich bin
mir nicht sicher in welchem modus sie betrieben wird. Wie finde ich das
den raus??
Nur an Hand der Arbeitsweise des vorhandenen Programms. Jetzt weißt Du
ja, was die Register bedeuten und kannst nachvollziehen, was, und an
welche Stelle, da reingeschrieben wird.
TxD der COM-Schnittstellen wurde auch unter Turbo Pascal Byteweise
beschrieben. Also kein achtmal Bit-nacheinander-Rausschieben. Das sollte
im Programm schon irgendwie erkennbar sein.
Blackbird
Also bei der initialisierung werden 5 Ports auf 0 gesetzt.
Im restlichen Verlauf werden dann aber nur noch zwei Ports beschrieben.
die Ports werden immer mit hexadezimal werten beschrieben. Also nicht
nur mit high/low.
danke das ihr mir so stark helft.
Kommt drauf an, welche Ports es sind und was die gesetzten oder
gelöschten Bits bei der Initialisierung einstellen.
Beim Schreiben auf die "2 Ports" kann es sich einmal um ein
Steuerregister und dann um das Datenregister handeln. Aber das weißt nur
Du.
Blackbird
WELCHE Ports werden mit 0 beschrieben ? Und WELCHE Ports werden mit
WELCHEN Hexadezimalen Werten beschrieben in WELCHER Reihenfolge ?
Lade doch einfach den Code hoch.
Karin schrieb:> also ich muss ein altes Turbo Pascal programm in C schreiben.> Ausgangsport ist eine DB 15 (Com Port mit 15 pins).
An PCs gibt es eigentlich nur zwei Möglichkeiten für 15polige
Anschlüsse, das ist der VGA-Anschluss (mit drei Reihen à 5) und das ist
der Gameport (zwei Reihen mit 8 und 7).
Serielle Schnittstellen haben 9 Anschlüsse, selten begegnet man welchen
mit 25. Die unterscheiden sich von Druckerschnittstellen dadurch, daß
sie Stecker (Ding mit Stiften) und keine Buchsen (Ding mit Löchern)
sind.
Kläre also doch bitte erstmal, was Du da wirklich tun sollst.
Und poste den Code Deines Pascal-Programmes, dann können wir hier besser
erahnen, was Du da anzustellen versuchst.
Also es handelt sich bei dem PC um ein spezielle Messkarte, kein
standard.
Es gibt acht Ports:
1. Data Port
2. Data+ interrupt port
3. kontroll port
4. Trigger port
5. Modus kontroll
6. status port
7. digital input port
8. output controll port.
angesprochen werden die ports immer
Port(baseadr+offste) :=$17; (beispiel)
nochmal danke
Dann brauchst du die Anleitung der Messkarte. Wenn du die nicht bekommst
dann kannst du nur noch das Pascal Program nachahmen sozusagen Reverse
Engeneering. Ist aber für ein Anfänger nicht einfach.
Wie Heißt die Messkarte (Firma und Modell) ?
Warum lädst du den Code nicht hoch ?
Gibt es keinen äquivalente code zu:
Port(0x3f8) := 0x1F;
und zu
byte : x;
x := Port(0x3f8)
falls ihr mir das sagen könnten, müsste ich den rest alleine
hinbekommen.
Kommt auf deinen C compiler an.
Manche haben sowas wie outp oder so drin. Ansonsten der Inline Assembler
oder sich ein paar Assembler funktionen dazulinken.
Welchen C Compiler benutzt du denn ?
Viele können sowas wie :
void outport(unsigned short int port,unsigned char out)
{
_asm{
mov al,out
mov dx,port
out dx,al
}
}
unsigned char inport(unsigned short int port)
{
_asm{
mov dx,port
in al,dx
return al
}
}
Falls dein Compiler keinen Inline Assembler hat. Nimm einen Assembler
deiner Wahl, exportiere die beiden funktionen und compiliere als
objectfile. Danach mußt du diese funktionen nur noch als extern c in
deinem compiler deklarieren und deinem linker mitteilen wo er deine
objectfiles findet.
Du mußt natürlich im assembler die Variablenübergabe noch regeln
(Calling conventions) und nach diesem Aufrufschema auch die beiden
Assemblerfunktionen Programmieren (z.b. Variableübergabe über stack oder
über Register, wer räumt den Stack auf, wie wird der Rückgabewert
zurückgegeben ).
Alles in allem höchstens ne Stunde Arbeit.
ich benutze im moment mingw gcc. kann aber auch wechseln, wenn es was
besseres gibt.
@uwe: mein compailer erkennt die von dir geschriebenen zeilen leider
nicht :-( trotzdem danke.
Karin schrieb:> Gibt es keinen äquivalente code zu:>> Port(0x3f8) := 0x1F;> und zu>> byte : x;>> x := Port(0x3f8)
So etwas gibt es zwar, und das ist auch nicht sonderlich kompliziert,
_inp und _outp für Byte-Zugriffw, _inpw und _outpw für Word-Zugriffe:
1
#include<conio.h>
2
3
_outp(0x3f8,0x1f);
4
5
x=_inp(0x3f8);
So ist das beispielsweise bei Microsoft-C-Compilern gelöst. Unter den
ernstgemeinten Windows-Versionen geht so etwas jedoch nur mit giveio.sys
und ähnlichen Verfahren; aber Du willst ja ein Frickel-Windows
verwenden, da ist das nicht erforderlich.
Aber
Sollte die Messkarte Interrupts verwendet, geht das auf diese Art und
Weise nicht, denn einen Interrupthandler (das ist die Routine, die
aufgerufen wird, wenn die Karte über den Interrupt dem System
signalisiert, daß etwas geschehen ist), kann man auch unter
Frickel-Windows nicht in einem normalen Usermode-Programm unterbringen.
Ob sie das tut, ist nur mit einem Blick in Dein Pascalprogramm oder in
die Dokumentation der Karte möglich.
Und ob das Programm wiederum irgendwelchen Copyrightbeschränkungen
unterliegt, sollte da in Form eines Kommentares drinstehen. Wenn da kein
solcher Kommentar drin ist, dann solltest Du den hier posten können.
Da ohne die Karte der Code völlig nutzlos ist, schätze ich eine
Veröffentlichung als nicht so kritisch ein, wie der von Software, die
einen breiteren Nutzen erfüllt.
Außerdem ist das Programm gnadenlos veraltet, DOS-Programme in Pascal
hat man in der ersten Hälfte der 90er Jahre vielleicht noch geschrieben,
spätestens seit dem Jahrtausendwechsel sollte man sich sowas abgewöhnt
haben.
danke für eure antworten. ich werde mal abklären, ob ich das programm
posten darf.
Noch eine Frage: wenn ich _outp und _inp verwende, muss ich den port
vorher öffnen oder geht das so?
nochmal danke an alle
Karin schrieb:> Noch eine Frage: wenn ich _outp und _inp verwende, muss ich den port> vorher öffnen oder geht das so?
es gibt keine Port wenn du _outp verwendest, du schreibst damit direkt
auf eine Hardware-IO Adresse. Welchen Port will du denn do öffnen?
Wenn diese Funktionen implementiert sind dann hast du schon Alles was du
brauchst. Diese kannst du genauso einsetzen wie die Pascal Funktionen
(natürlich andere Syntax). Das mit dem Assembler war nur gedacht falls
"_inp" und "_outp" in deinem gcc version nicht implementiert sind. Ich
glaube diese müßten in der conio.h definiert sein.
Karin schrieb:> Noch eine Frage: wenn ich _outp und _inp verwende, muss ich den port> vorher öffnen oder geht das so?
Du kannst den Port gar nicht vorher öffnen, weil Deine Karte eben
KEINE serielle Schnittstellenkarte ist, und solange zur Karte kein
Devicetreiber gehört, gibt es auch kein Device, das vom Betriebssystem
angesprochen werden kann.
Und selbst wenn es das gäbe, darfst Du auf gar keinen Fall Zugriffe
über den Devicetreiber und Zugriffe am Devicetreiber vorbei mischen.
Ich denke das ist nur ein verständnisproblem wegen der bezeichnung
IO-Port bzw outp(ort). IO-Ports haben nichts mit Comports oder
Parallelports zu tun.
Wie kann man das jetzt erklären ohne dich weiter zu verwirren.
Hmmm.
Also um Geräte und Arbeitsspeicher zu trennen wurden zwei getrennt
Adressräume geschaffen. Um auf den IO-Raum zuzugreifen benutzt man die
CPU Befehle "in" und "out". Dahinter gibt man die IO-Adresse an die oft
auch als IO-Port bezeichnet wird jedoch mit einer Schnittstelle nichts
zu tun hat außer das auch Schnitstellen über IO-Ports angesprochen
werden.
Und wie ich schon erwähnt habe: Ohne zu klären, ob das DOS-Programm die
Karte mit Interruptbetrieb ansteuert, ist jede weitere Untersuchung
witzlos.
Erst wenn mit Sicherheit ausgeschlossen ist, daß die Karte Interrupts
verwendet, kann die Untersuchung, wie die Karte mit _inp/_outp
anzusteuern ist, fortgesetzt werden.
Naja die Karte scheint ja vorher mit Pascal auch über reine IO Zugriffe
funktioniert zu haben. Wenn die Software nun einfach nach C konvertiert
wird muß man noch nicht mal wissen wofür welcher Zugriff ist bzw. nur
das lesen oder schreiben der Daten interresiert. Was genau in den Status
und Controllregistern passiert braucht mich nicht zu kümmern solange ich
keine Bugs korrigieren oder Features hinzufügen muß.
also in dem Programm sind keine Interrupts enthalten, da bin ich mir
ganz sicher. Ich werde jetzt jetzt einfach nochmal probieren zu
übersetzen. Melde mich bestimmt aber später nochmal ;-)
nochmal danke für eure super hilfe!!!