Ich möchte gerne unter Windows XP daten über COM1 schicken.
outp ist ja nicht mehr. Jetzt möchte ich aber nicht ie ganzen utils
benutzen die im netz rumschwirren damit das wieder geht.
Weis jemand wie man richtig mit dem lcc-win32 c compiler
auf einfachste weise dir serielle schnittstelle COM1 öffnet und einfach
1 byte darüber schickt. Ich habe mich jetzt schin durch tausende web
sites geklickt wurde aber nicht schlau daraus
Das geht mit den Systemfunktionen CreateFile, WriteFile/ReadFile etc.
und noch ein paar anderen, mit denen Baudrate etc. konfiguriert
werden.
Ein Tutorial, das zumindest einen Anhaltspunkt liefern dürfte, ist
http://www.luxoncreations.com/tutorials/serial_read/
Mit direkten Portzugriffen (outp etc.) wärest Du bei einer seriellen
Schnittstelle übrigens schon unter Windows 3.0 (ja, dem 16-Bit-Relikt)
auf die Schnauze gefallen; von Hardware, die Interrupts auslösen kann
und vom Betriebssystem auch dafür konfiguriert ist, sollte man
tunlichst die Finger lassen.
Es geht aber auch ohne Programmieren:
In der Kommandozeile ("Eingabeaufforderung", von manchen Leuten
fälschlicherweise "DOS-Box" genannt) tippst Du folgendes ein:
copy con com1:
dann drückst Du die Eingabetaste, tippst die zu sendenden Zeichen ein
und schließt die Eingabe mit Ctrl+Z ("Strg+Z") ab.
Konfigurieren kannst Du die Schnittstelle in der Kommandozeile mit dem
Mode-Befehl:
MODE COMm[:] [BAUD=b] [PARITY=p] [DATA=d] [STOP=s]
[to=on|off] [xon=on|off] [odsr=on|off]
[octs=on|off] [dtr=on|off|hs]
[rts=on|off|hs|tg] [idsr=on|off]
Ausführlicher:
baud=b
Baudrate, kennt folgende Abkürzungen:
11 110 Baud
15 150 Baud
30 300 Baud
60 600 Baud
12 1200 Baud
24 2400 Baud
48 4800 Baud
96 9600 Baud
19 19.200 Baud
parity=p
Bestimmt, wie das System das Paritätsbit verwendet, um
Übertragungsfehler zu überprüfen. In der folgenden Tabelle sind
gültige Werte für p aufgeführt.
n,e,o,m,s = none, even, odd, mark, space
Der Standardwert ist e. Die Werte m und s werden nicht auf
allen Computern unterstützt.
data=d
Gibt die Anzahl der Datenbits pro Zeichen an. Gültige Werte
für d liegen im Bereich von 5 bis 8. Der Standardwert ist 7.
Nicht alle Computer unterstützen die Werte 5 und 6.
stop=s
Gibt die Anzahl der Stoppbits an, die das Ende eines
Zeichens definieren: 1; 1,5 oder 2. Wenn die Übertragungsrate
110 eingestellt wurde, werden standardmäßig 2 Stoppbits
verwendet; andernfalls ist 1 der Standardwert.
Nicht alle Computer unterstützen den Wert 1,5.
to={on|off}
Bestimmt, ob die Verarbeitung der endlosen Zeitüberschreitung
ein- oder ausgeschaltet ist. Der Standardwert ist off.
xon={on|off}
Bestimmt, ob das xon- oder xoff-Protokoll für die
Datenflusssteuerung ein- oder ausgeschaltet ist.
odsr={on|off}
Bestimmt, ob der Ausgabehandshake, der das DSR (Data Set
Ready)-Signal verwendet, ein- oder ausgeschaltet ist.
octs={on|off}
Bestimmt, ob der Ausgabehandshake, der das CTS (Clear To
Send)-Signal verwendet, ein- oder ausgeschaltet ist.
dtr={on|off|hs}
Bestimmt, ob das DTR (Data Terminal Ready)-Signal ein-
(on) bzw. ausgeschaltet (off) ist oder auf Handshake (hs)
gesetzt bzw. umschaltbar (tg) ist.
rts={on|off|hs|tg}
Bestimmt, ob das RTS (Request To Send)-Signal ein- (on)
bzw. ausgeschaltet (off) ist oder auf Handshake (hs) gesetzt
bzw. umschaltbar (tg) ist.
idsr={on|off}
Bestimmt, ob das DSR-Signal verwendet wird oder nicht.
also beispielsweise
Mode com1: Baud=19200 Parity=n Data=8 Stop=1
Pedanterie:
Das ist kein "Dos32"-Programm, sondern ein ganz normales
32-Bit-Konsolenprogramm.
Bitte keine unnötigen Termini für bereits definiertes erfinden, das
schafft nur Verwirrung.
@Blackbird
Ich bin absolut begeistert es funktioniert vielen Dank endlich mal eine
klare leicht verständliche Antwort die wirklich funktioniert.
Jetzt habe ich nur noch eine andere Frage.
Ich möchte jetzt noch daten Empfangen. Wie geht das?
Da ich nämlich über dir RS232 eine Datenstrom empfange und diesen
mchteich dann in einem File abspeichern. Wie das mit dem File geht
weis. Ich müsste nur wissen wie ich halt Daten uner win Xp in einem
eigenem C Programm empfangen kann
Mal ne dumme Frage.
Gibt es für so etws kein Interrupt wie z.B bei einem µC.
Wo kann man eigentlich in einem Buch solche sachen nachlesen.
In den ganzen Büchern werden immer nur die grundlagen vermittelt.
Gibt es eigentlich etwas wo z.B richtig drinn steht wie man Interrupts
programmiert Timer auswertet Schnittstellen steuert usw usw
Oder ist die einzige Quelle MSDN?
Heutzutage programmiert man nicht mehr direkt an der Hardware. Dadurch
fallen Interrupts und direkte Nutzung von Schnittstellen weg. Kein
aktuelles System lässt dich da mehr ran. Als Programmierer ist man nur
noch auf die Schnittstellen des OS angewiesen.
Aber etwas ähnliches wie Interrupts gibt es auch bei aktuellen Systemen
in Form von Callbacks oder Events. Dazu gibts in der MSDN auch sehr gute
Artikel, z.B
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnfiles/html/msdn_serial.asp
Thanks at Tobi.
Die Seite ist auch sehr hilfreich. Dort steht ja auch die behnadlung
der serillen Schnittstelle drin.
Aber wieso hat man keinen Timer.
Ich müsste jetzt noch wiesen wie man in C eben alle 100 ms beschied
bekommt weil ich dann eine Funktion aufrufen möchte
Timer gibt es auch.
Ich benutz bei mir die recht präzisen Multimedia-Timer mit
timeSetEvent, timeKillEvent
Der ersten Funktion gibt man eine Callback-Routine mit, wie oft und,
dass es periodisch aufgerufen werden soll. Am Ende mit der 2. Funktion
den Timer wieder löschen und fertig
Ich würde dir Empfehlen, dich zumindest grundlegend mit der seriellen
Schnitstelle auseinander zu setzen. In deinem Schaltplan steht nicht
umsonst etwas von RTS. Schau dir mal die Pins einer solchen
Schnittstelle an und lies dir in den oben schon angegebenen Links
durch, wie man diese Pins ansteuert. Ich kann dir gleich sagen, dass
der Code, den du dort unnötigerweise noch einmal gepostet hast nicht
funktionieren wird.
@Weinga-Unity - snaky.1gmx.at:
loest der Link, den Du angegeben hast, das Problem des Threaderstellers
oder das von Selim Mut (trooper81vs18) ?
Blackbird
Ich denke, es löst das Problem des Threadstellers. Mit der angegebenen
Bibliothek (einfach die benötigen CPP und H Files in das eigene Projekt
beifügen) bekommt man auf einfachste Weise zugriff auf die serielle
Schnittstelle und man kann so sehr einfach ein Byte schicken.
mfg W.K.
Was ist bei meiner Loesung nicht (Zitat:) "einfachste Weise " (siehe
Post vom 10.08. ?
Und ist das Problem damit nicht schon geloest gewesen, einschliesslich
des Lesens vom COM-Port?
Selim Mut (trooper81vs18) hat ein ganz anderes Problem, die Hardware.
Blackbird
@blackbird
das von dir gepostete c-programm mit welchem bytes gesendet und
empfangen werden können über den com funktioniert bei mir nicht. fliegt
immer raus nach dem ersten return. neben bei mekert der compiler bei:
BOOL bRet = true
was mache ich falsch?
dei c-routine nur fürs senden, am anfang des thread funkt probklemlos!
gruss raphael
Hi ihr
Ich erstelle gerade ne dialogbox und habe dazu den oben genannten code
testweise übernommen.
die baudrade habe ich auf 110 gestellt, damit ich mit meinem uralt oszi
noch was messen kann (dachte ich mir zumindest so)
wenn ich jetzt am Pin RTS messe, dann messe ich ca -12V
wenn ich dann die 4 Bytes übertrage (also auf meinen button klicke) dann
reagier des programm 4 sekunden lang nicht, und der pegel springt von
-12V auf +10V nach den 4 sekunden springt er dann wieder auf -12V....
Sollte der Pegel an RTS nicht aber "wild" hin und her zappeln?
Mache mit der RS232 erst so meine anfänge.... und bin jetzt erstmal
total verunsichert....
vielen dank schonmal
gruß#
ich
"... wenn ich jetzt am Pin RTS messe, dann messe ich ca -12V ..."
RTS ist aktiv - ist in Ordnung.
"... wenn ich dann die 4 Bytes übertrage (also auf meinen button klicke)
dann
reagier des programm 4 sekunden lang nicht, und der pegel springt von
-12V auf +10V nach den 4 sekunden springt er dann wieder auf -12V...."
i.O.: R(eady)-T(o)-S(end) ist solange inaktiv, wie gesendet wird.
"Sollte der Pegel an RTS nicht aber "wild" hin und her zappeln?"
Nein, TxD (Pin3) sollte aber "zappeln". Vorher und nachher sollten
-8V...-12V anliegen.
Mal http://www.beyondlogic.org/serial/serial.htm#1 besuchen.
Blackbird
Oh weia.... danke backbird
wer misst misst mist..... bin da jetzt nochmal ruhig ran gegangen und
siehe da.... am TxD zappelt was, des ist mir gestern gar nicht
aufgefallen, und dann hat mich der post mit dem RTS nur noch verwirrt
herzlichen dank;-)
juhu
danke
gruß
ich
@Blackbird:
Du hast am 10.08.2006 einen Code zur Ansteuerung der seriellen
Schnittstelle unter C online gestellt. Dieser lässt sich bei mir auch
problemlos kompilieren. Allerdings muss ich ein RDS Gerät, welches am
Com Port hängt, ansprechen. Der Befehlssatz ändert sich laufend und auch
die Länge. Um nun als Beispiel einen dieser Befehle zu schicken habe ich
Deinen Code abgeändert. Folgendes soll laut Herstellerfirma des Geräts
als Command übertragen werden:
STX + 0x02 + 0x00 + ASCII1 + ETX + CHK
Wobei ASCII1 = '1' für gesetztes Bit ist.
Folgenden Code habe ich geschrieben:
#include <windows.h>
int main ()
{
DCB dcb;
DWORD iBytesWritten;
int laenge = 3;
unsigned char *output; // Liste mit x-Einträgen
output = (unsigned char*) malloc(sizeof(int)*laenge);
output[0] = 0x02;
output[1] = 0x02;
output[2] = '1';
output[3] = 0x03;
HANDLE hCom = CreateFile ("COM1", GENERIC_WRITE, 0, 0,
OPEN_EXISTING, 0, 0);
dcb.DCBlength = sizeof(DCB); // Laenge des Blockes MUSS gesetzt sein!
GetCommState (hCom, &dcb); // COM-Einstellungen holen und aendern
dcb.BaudRate = 9600; // Baudrate
dcb.ByteSize = 8; // Datenbits
dcb.Parity = NOPARITY; // Parität
dcb.StopBits = ONESTOPBIT; // Stopbits
SetCommState (hCom, &dcb); // COM-Einstellungen speichern
WriteFile (hCom, &output, sizeof (output), &iBytesWritten, NULL);
// Senden von output mit oben defenierter Größe
CloseHandle (hCom); // COM1 schließen
return(0);
}
Wie gesagt: Der Code lässt sich ohne Probleme bei mir kompilieren und
ausführen. Aber das angeschlossene Gerät reagiert nicht drauf (an dem
Gerät liegt es nicht, da es mit der Steuersoftware vom Hersteller
klappt. Da aber ein automatisierter Protzess ablaufen soll, soll das
ansprechen des RDS Coder mittels eines Programmteils in C geschehen).
Ich wäre Dir und auch jedem anderen für ein wenig Hilfe sehr dankbar.
:-)
Ich hoffe, dass mir einer helfen kann. Verzweifel daran schon.
Ich habe auch meine Email Adresse angegeben und bin für jeden Vorschlag
und Hilfe auch per email unendlich dankbar.
Hoffe bald weiter zu kommen.
Gruß
Wolfsblut
Hi Wolfsblut,
mal einige Sachen, die mir aufgefallen sind:
"STX + 0x02 + 0x00 + ASCII1 + ETX + CHK"
sieht irgendwie nach 6 Bytes aus. (btw. was ist CHK, eventuell irgendein
Prüfbyte; wenn ja, wie berechnet?)
In Deinen Code ist "laenge=3" ?!?!?
Dann "... malloc(sizeof(int)*laenge)", warum multiplizierst Du hier mit
sizeof(int) und nicht mit sizeof(char) bzw. sizeof(unsigned char) ?
Anschließend schreibts Du da 4 Bytes rein! Sollten das nicht 6 sein?
Und zum Schluß benutzt Du "sizeof (output)" für die Anzahl der zu
übertragenden Byte. Das ist definitiv auch nicht das, was Du willst! Das
liefert Dir die Größe des Pointers, aber nicht die Anzahl der Bytes auf
die dieser zeigt!
CU
Noch was.
Wenn Du nicht sicher bist, was an der seriellen Schnittstelle geschieht,
so verbinde sie einfach mit einer weiteren seriellen Schnittstelle und
lasse dort ein Terminalprogram drauf laufen, welches auch hexadezimal
darstellen kann, z.B. "SerialWatcher.exe".
Blackbird
Erstmal vielen Dank für Eure Hilfe und Unterstüztung. Das hilft mir echt
weiter und ich sehe meine Fehler nun leider auch...
Ouch... Das tut weh!
@... :
Vielen Dank für Deine Anmerkungen. Es ist schon ziemlich doof was ich da
für "Flüchtigkeitsfehler" eingebaut habe.
Also:
- laenge = 3; :
Was ich hier gepostet habe wird später ja nur ein Unterprogramm. Und
in diesem soll die Laenge des Vektors ( da dieser bei verschiedenen
Befehl verschieden lang sein wird) variiert werden. Zum testen wollte
ich die Länge auf einen festen Wert setzen. Dabei sollte ich aber auch
einen Wert nehmen, der dem ganzen angemessen ist... Ist bereits
geändert.
- CHK:
Nun ja. Wenn ich schon sowas schreibe sollte ich auch angeben, was CHK
ist. Hier mal die Aufschlüsselung:
CHK = STX .XOR. CODE (hier: 0x02) .XOR. Pointer (hier: nicht vorhanden,
aber in anderen Befehlen) .XOR. ASCII1 .XOR. ASCII2 .XOR. ... (weitere
ASCII Codes bei anderen Befehlen, hier nur ein einziger) .XOR. ETX
- Ähm... :
Was mir noch aufgefallen ist: Selbst wenn ich die Prüfsumme CHK am
Ende weglassen würde, so muss ich doch die 0x00, die ich beim Command
erwähnt habe, mit einbauen. Das tat ich nicht. Klar, dass es dann auch
schon mal nicht geht...
- sizeof(int):
OK. Da sollte sizeof(unsigned char) stehen... Schon geändert.
- sizeof(output):
Hier hatte ich mich auf den Code von Blackbird bezogen.... Für mich
klang es logisch, dass ich die Anzahl der auszugebenden Bytes angeben
muss.
@ Blackbird:
Danke für Deine Zeit und Deine Anregungen.
Es ist eine sehr gute Idee eine feste Zeichenfolge zu verwenden. Aber
leider ändert sich Länge der Zeichenfolge von Command zu Command. STX
und ETX habe ich allerdings laut Deinem Vorschlag vordefiniert und sie
werden am Ende einfach einfügen.
Mit der Überprüfung des Return codes.... Da trau ich mich noch nicht
ran. Verstehe den Code, um ehrlich zu sein, noch nicht 100pro... Muss
mich da noch tierisch einarbeiten.
Danke auch für Deine Anregung mit der Verbindung zwischen zwei
Computern. Kann so wenigstens ja mal testen, ob da überhaupt was
kommuniziert.
Danke euch beiden für eure schnellen und für mich wichtigen Antworten.
Werde versuchen alles umzusetzen und am Montag in der Firma zu testen.
:-)
CU soon
Liebe Gürße
Wolfsblut
Hallo nochmals!
Also: Ich habe es mit der Zeit nun doch hinbekommen, dass ich einen Com
Port öffnen, schreiben und lesen kann.
Vielen vielen Dank an dieser Stelle an euch und eure Hilfe!!! Und vor
allem auch an eure Geduld mit Quereinsteigern wie mir ;-)
Aber: Ich habe immer noch ein Problem.
Ich kann den Com Port nicht mehr schliessen...
Wenn ich das Programm das erste Mal starte, läuft alles scheinbar
tadelos. Starte ich es dann ein zweites Mal, so hängt es sich in der
ersten do-while- Schleife auf bei "WaitCommEvent". Und ich kann nicht
verstehen warum.
Das Programm dient der Steuerung eines externen Gerätes, welches später
Teil eines großen Programms zur Automation wird. Bei dem Gerät liegt
eine eigene Software bei. Mit dieser funktioniert alles, also auch nach
mehrmaligem Starten. Wenn ich aber meinen eigenen Code verwende um das
Gerät anzusprechen, und nach einem Erfolgreichen lauf das Hersteller
eigene Programm starte, dann bekomme ich von dem Tool die Fehlermeldung
"Serial Port timeout".
Schliesst mein Programm den Port nicht? Oder habe ich timeout Probleme?
Ich komme damit leider nicht weiter und auch ein Kollege von mir ist
ratlos, obwohl er einige Jahre mehr Erfahrung hat.
Bitte helft mir!!! Ich weiss gerade nicht weiter.
Vielen Dank!
Viele Grüße
Wolfsblut
Naja, lasse Dir doch die return codes (bzw. die lesbare Entsprechung)
von Programm in einer MessageBox anzeigen. Von allen Funktionen, auch
von CloseHandle.
@ Blackbird:
Sorry. Ich hatte vergessen zu erwähnen, dass ich mir die Codes schon mal
habe ausgeben lassen. Dabei kam "Das Handle ist ungültig" heraus.
Das macht mich auch so ratlos. Warum soll CloseHandle ungültig sein?
(Hatte nur danach den Codeteil für return codes wieder rausgeschmissen,
da ich mir mehr Übersicht verschaffen wollte)
Wenn das Handle (nicht die Funktion CloseHandle!) ungültig war, hast Du
entweder auf eine nicht initialisierte Variable zurückgegriffen (kann
bei der Parameter-Übergabe an andere Funktionen passieren) oder es war
schon freigegeben.
Wahrscheinlich ersteres.
Blackbird
@ Blackbird
Auch wenn ich kein Freund von so langen Posts mit Code und allem bin, so
mache ich es diesmal doch. Leider kann ich nur keine Datei anhängen...
seufz
Ich habe HANDLE hCom... und damit arbeite ich die ganze Zeit
(CreateFile, ReadFile, WriteFile) Und immer frage ich ab, ob auch der
Com Port geöffnet ist ( if(hCom == INVALID_HANDLE_VALUE) ). Aber dennoch
klappt es nicht wie ich möchte. Aber ich brauche den Code dringend...
Deine Fehlerauswertung ist ... merkwürdig.
Beim Fehlschlagen von CreateFile solltest Du GetLastError aufrufen und
dessen Ergebnis ausgeben, das hilft bei der Diagnose.
Nach SetupComm und SetCommMask ist es völlig nutzlos, das Handle auf
Gültigkeit zu überprüfen - diese Funktionen verändern das Handle nicht,
sondern haben einen Rückgabewert, und den solltest Du auswerten.
Und das auch bei allen anderen Funktionen, wie beispielsweise WriteFile.
Wenn Du mit Overlapped I/O arbeiten willst, dann musst Du das auch beim
Aufruf von CreateFile machen - Du solltest Dir dringend die
Dokumentation der von Dir verwendeten API-Funktionen ansehen.
> Vor dem ersten Öffnen des COM-Ports kannst Du auch schreiben:>> CloseHandle (hCom); // "alten" COM-Port schließen
Davon würde ich abraten. Wie kommt der "alte" COM-Port in die nicht
initialisierte Variable hCom? Eben.
@ Rufus
Ich gebe zu, dass meine Auswertung der Fehler ein wenig merkwürdig ist.
Aber ich habe einfach nur eine schnelle Ausgabe gemacht, die einfach bei
einem Fehler mir diesen anzeigt. Und ich bekomme keinen Fehler bis zu
dem Punkt, wo er das CloseHandle umsetzen soll.
Dokumentation von der API Funktion ist ein gutes Stichwort. Die gibt es
nicht. Zumindest steht sie mir nicht zur Verfügung. Alles was ich habe
ist ein fertiges Programm des Geräteherstellers und eine Liste der
Befehle, die das Gerät akzeptiert. Eigentlich ist es dazu gedacht über
die Bedienoberfläche der mitgelieferten Software bedient zu werden. Nur
kann ich diese Bedienoberfläche für meine Automation nicht nutzen. Somit
muss ich alles alleine herausfinden. Ich kann das Gerät ja ansprechen
und bekomme die richtigen "Antworten" zurück. Das sagt mir der serial
monitor. Aber am Ende will er den Port nicht schliessen.
@ Blackbird
FILE_FLAG_OVERLAPPED habe ich versuchsweise in CreateFile eingebaut...
Dann endet der gesamte Lauf schon in der ersten do-while -Schleife bei:
1
printf("\nWait for event\n");
2
WaitCommEvent(hCom,&dwEvtMask,&o);
Ich habe auch mal die gesamte do-while-Schleife weggelassen, also auch
"WaitCommEvent" nicht ausgeführt und nach
jeweils direkt eingelesen. Funktioniert ebenso gut oder eben schlecht.
Wie oben schon erwähnt: Ich habe keine Dokumentation über die API. Ich
muss trial and error machen. Und bisher macht es ja fast das was ich
will...
Gruß
Wolfsblut
@ Rufus
Oh... Da habe ich etwas falsch verstanden. Klar. Die MSDN habe ich auch
auf dem PC installiert und verwende sie regelmäßig.
Ich dachte es war die Rede von der genauen Schnittstellenbeschreibung
des Gerätes, also die API Funktionen meines Endgerätes, sprich eine
Treiberschnittstelle, die ich nutzen kann.
Aber wer zu schnell liest, der versteht eben nur die Hälfte. Sorry.
(Und ja: Manchmal drücke ich mich einfach zu kompliziert aus, wenn ich
nicht weiss wie und ob ich es richtig beschreibe ;-) )
@ Blackbird
Vielen Dank für die große Hilfe. Leider kann ich das erst am Montag
testen, da mir dann erst wieder die Hardware zur Verfügung steht :-( .
Hätte es gerne sofort gemacht.
Und glücklicherweise verstehe ich auch fast jeden Schritt. Allerdings
ist mir leider nicht soooo ganz klar, was der Pointer Buf macht...
Sorry, wenn die Frage dumm klingt. Aber leider sehe ich das nicht so
direkt. Vielleicht sehe ich auch vor lauter Codes das Programm nicht
mehr. So langsam raucht mein Kopf weil ich fast jeden Tag alles
umschreibe und versuche zu verbessern. grins
Aber hab vielen Dank. Ich werde es testen. ;-) Ist auf jeden Fall
einfacher als mein Durcheinander.
Buf ist ein Pointer auf ein char-Array, welches mit malloc erst zur
Laufzeit erstellt wird (und der "allokierte" Speicher muß auch mit
free(Buf) wieder freigegeben werden!). Das Array wird von der Funktion
dump benutzt weil diese Funktion dort ihr Ergebnis reinschreibt.
Die Funktion dump habe ich nur wegen der Anzeige der hex-Werte
geschrieben, sie ist nicht notwendig für die Gesamtfunktion. Buf ebenso.
Den Ablauf kannst Du nach Belieben optimieren, Fehlerbehandlung,
Datenwiederholungen usw. sollten auch implementiert sein.
Für solche Abläufe bietet sich eine State-Event-Maschine an.
Die meisten Aktionen und Fehler können auch in eine Log-Datei
geschrieben werden statt per MessageBox aufzupoppen.
Viel Spaß beim Testen,
Blackbird.
@ Blackbird:
WOW! Es funktioniert endlich wie es soll!!!! Danke!
Habe erstmal Deine Programmierung probiert. Natürlich 1A! Und dann hab
ich mal geschaut, woran es bei mir gescheitert sein könnte. Habe die
Blöcke ausgetauscht (Ja, es war ein Fehler, den ich mir bei
CloseHandle(hCom) selber eingebaut habe) und siehe da... ES KLAPPT!
Nun bin ich nicht nur sehr erleichtert, sondern auch wieder ein ganzes
Stück weiter. Selbst nach dem Umschreiben und einbauen in das
eigentliche Programm gab es keine Schwierigkeiten. Und nun kann ich die
restlichen 10 oder 15 Funktionen noch schreiben, ohne dass ich mich mit
solchen dummen Fehlern zwei Wochen aufhalte. (So hoffe ich doch grins)
Aber das sind die kleineren Übel... mehr so Standard Funktionen, die man
in den ersten Grundkursen lernt. ;-)
Nochmals vielen Dank!
Auch für die wertvollen Tips von Rufus! ;-)
Viele Grüße aus dem Bergischen!
Wolfsblut
Tach, sorry dass ich diesen alten Thread ausgrabe, aber ich bin mir
sicher ihr könnt mir helfen.
Ich programmiere nur selten und auch nur simple Dinge, daher versteh ich
recht wenig von WinAPI und komme nicht so ganz damit zu recht.
Im Rahmen einer Projektarbeit will ich ein Programm schreiben, mit dem
man eine "programmierbare" Steuerungen mit einfachen Positionen füttern
kann. Das erstellen der Positionen klappt und wenn ich die erzeugte
TxT-Datei mit Copy&Paste in die Hyperterminalsitzung kopiere und somit
an die Steuerung übertrage funktioniert auch alles prima.
Nun sollte der Anwender die erzeugte TxT-Datei direkt im Programm an die
Steuerung übertragen (damit die sich nicht erst mit Hyperterminal
auseinander setzen müssen und die richtigen COM-Einstellungen raussuchen
müssen). Eigentlich muss ich nur Zeile für Zeile an die Steuerung
übertragen, Rückgabe brauche ich keine...ich geh davon aus, dass alles
klappt :-)
Ich habe Blackbirds kleines Programm geschnappt, kompliliert und
ausgeführt. Scheint ok zu sein. Leider kann ich an meinen Arbeitsplatz
nicht prüfen, was die COM-Schnittstelle wirklich ausspuckt (kein
Nullmodemkabel).
Also meine zwei Fragen:
1) Wie sende ich ein "Return" oder wird nach dem Write-Befehl
automatisch ein Return eingefügt?
2) Wie aktiviere ich die FlowControl "Xon/Xoff" ?
Laut Microsoft muss fOutX auf TRUE sein. Macht man das dann so?:
dcb.DCBlength = sizeof(DCB);
GetCommState (hCom, &dcb);
dcb.BaudRate = 9600;
dcb.ByteSize = 8;
dcb.Parity = NOPARITY;
dcb.StopBits = ONESTOPBIT;
dcb.fOutX = 1; //Flowcontrol Xon/Xoff für Ausgabe auf TRUE?
SetCommState (hCom, &dcb);
Danke schon mal für Eure Hilfe!
Hmm aaaalso ich habe schon neue Erkenntnisse:
"Return" sollte 0x13 sein, sollte also so tun (die restlichen 3
Buchstaben jucken mal nicht):
unsigned char ucMsg[] = {0x13, 0x42, 0x20, 0x43}; // (4)
und ich sollte wohl lieber die Terminalsitzung beenden um auf den Port
zugreifen zu können :-)
Aber bisher reagiert der Antrieb meiner Steuerung nicht. Wenn ich ein
"Return" erfolgreich versende, dann bewegt sich der Antrieb und das
bedeutet für mich "JUHU".
Sorry, dass ich soviel schreibe, aber man kann ja leider die Beiträge
(jedenfalls als nicht-registrieter Benutzer) nicht ändern.
Welche Hexzahl nun "Return" darstellt ist wohl nicht immer eindeutig und
abhängig vom Zeichensatz (logisch). Mit einem kleinem Programm habe ich
ein "Return" als hex zurückgegeben und das meinte "0x0A" bzw.
"10"-dezimal ist ein Return.
Beim Senden von "ucMsg[] = {0x6D, 0x73, 0x30, 0x0A};" passiert am
Antrieb nichts.
Statt nur ein Return möchte ich ein nun den Befehl "ms0" (msNULL) und
Return senden.
Das übertragen der Textdatei ist ja mein finales Ziel, erst einmal wäre
ich glücklich nur "ms0" mit einem anschließenden Return zuversenden.
Ist der Ansatz mit "ucMsg[] = {0x6D, 0x73, 0x30, 0x0A};" richtig, oder
sollte man lieber einen anderen Arraytyp (int, char, etc.) nehmen, oder
vielleicht die Sache ganz anders angehen?
Ich würde sooo gerne mal ne COM-Schnittstelle ansteueren :-)
PS: mit Portmon von Sysinternals soll man seine COM-Schnittstellen
belauschen können, aber bei zwei PCs wo ich es nun getestet habe, bleibt
das Tool leer und zeigt nichts an. Gibts ne Alternative zu Portmon?
0x0A ist Line Feed (LF) - "eine Zeile runterrücken"
0x0D ist Carriage Return (CR) - "Wagen zurückfahren"
Die ASCII codes kommen noch aus der Fernschreibertechnik.
Versuche es mal so:
1
ucMsg[]={0x6D,0x73,0x30,0x0D};
statt so:
1
ucMsg[]={0x6D,0x73,0x30,0x0A};
oder so:
1
ucMsg[]={0x6D,0x73,0x30,0x0A,0x0D};
Blackbird
PS: Bei mir funktioniert Portmon. Hyperterminal auch. SerialWatcher
ebenso. Liegt sicherlich an der Einstellung oder am Anschluß.
Juhu,
es tut.
Einen Zeilenumbruch Return Enter sendet man mit "\r\n" und nicht nur
mit "\n"...bis ich das raus hatte.
Beispiel:
WriteFile( hCom, "ms0\r\n", 4, &iBytesWritten, NULL);
Sendet:
"ms0"+Zeilenumbruch
Schönen Tag noch und danke euch für die schnell Hilfe. Nun muss ich
schnell mal schauen, dass ich auch anderen Text übertragen kann.
Weißt Du eigentlich, was Du tust?
Hast Du auch verstanden, was ich geschrieben habe?
1
WriteFile(hCom,"ms0\r\n",4,&iBytesWritten,NULL);
sendet genau 4 Zeichen: m, s, 0 und \r
Das \n wird nicht gesendet.
Da \r aber Carriage Return (also CR = 0x0D) ist, hast Du zufällig das
richtige Zeichen gesendet. Sonst sah der String ja so aus "ms0\n".
Anmerkung:
\n wird von den meisten Programmen/"Maschinen" als \r\n interpretiert,
aber eben nicht von allen.
Blackbird
Hallo Blackbird,
ich muss ein Programm in c Sprache unter Windows schreiben, das auf die
serielle Schnittstelle zugreift, um Daten (GPS_Daten)auszulesen. Die
serielle Schnittstelle ist mit einem GPS-Terminal (xt75 von Firma
MC)angeschlossen. Die Daten kann ich ansehen mit Hyper-Terminal. Ich
gebe bestimmte AT-Commands ein und dann bekomme ich die Daten (NMEA
Protokoll). Nun mein Professor will dass ich ein Programm schreibe das
direkt diesen Daten ausliest. Ich muss bis Ende diesen Monat eine Lösung
finden. Ich habe keine Ahnung wie das geht!
weiß du vielleicht wie ich es mache?
Danke
Die sind die drei Commandos die ich Hyper-Terminal eingebe:
ati
at^sgpss=1,0
at^sgpsp=2
Bis zum Erbrechen.
Damit will ich ausdrücken, daß das Thema "Wie programmiere ich die
serielle Schnittstelle unter Windows in C" in diesem Forum verdammt
oft diskutiert und ausreichend besprochen wurde. Die Forensuchfunktion
sollte helfen.