RS485 Schnittstelle auf pci Steckplatz
-
Vielen Dank!!!
Es klappt soweit. Wenn ich das Progrämmchen soweit laufen habe, dass es mir tut, was ich möchte, stelle ich den Code hier aus.

-
Hehe, zu früh gefreut...
Also: mein neues Problemchen:
Wenn ich den inbuffer auf eine Feldgrösse von wie hier z.B.:100 deklariere, liest doch die ReadFile() so lange, bis der inbuffer[100] voll ist. Das ist schade. (Com1)
Ich würde gerne das Einlesen starten und stoppen über ein Signal an Com2. Wenn ich aber in der ReadFile vom Com1 stecke, wird mir Com2 natürlich garnicht beachtet...
Wie kann ich den ReadFile() quasi "interrupten"?
Oder geht das nur, indem ich den inbuffer nur auf eine grösse von [1] deklariere und einlesen lasse, also zeichenweise, und nacheinander com1 + com2 abfrage und auswerte um somit eine Art interrupt zu erhalten? Das wäre ja ein etwas großer Aufwand, oder?
Also Danke für alle Tipps!!
-
Wenn du die Leseopaeration assynchron, also overlapped, durchführst, dann kannst du einfach, wenn an COM2 das Signal ankommt mit CancelIo den Lesevorgang abbrechen. Könnte zumindest irgendwie so funktionieren

-
Wie kann man den Funktionsaufruf cancelio() aufrufen, wenn mein readfile so groß ist:
ReadFile(LaserCom, &String, 10500, &AnzBytesLaser, NULL);
???cancelio(...);???Er kommt ja garnicht aus der ReadFile()-Funktion raus, bis der buffer &String voll ist, um cancelio aufzurufen... Aber ich möchte ihn ja praktisch an z. B. der Stelle String[1234] unterbrechen.
Thanxx
-
Das blockierende Lesen mit Readfile kann man auch mit einem Timeout beenden. Da muß nur nach dem Öffnen mit CreateFile() die Struct COMMTIMEOUTS gesetzt sein.
Zusätzlich kann man mit
SetCommMask (hCom, EV_RXCHAR | EV_ERR)eine Event-Maske setzten, mit:
OVERLAPPED o; o.hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);einen Event setzen und in einer Endlosschleife mit
WaitCommEvent (hCom, &dwEvtMask, &o);einen Event-Buffer bereitstellen und mit
if (WAIT_OBJECT_0 == WaitForSingleObject (o.hEvent, INFINITE))warten bis einer der beiden mit SetCommMask() definierten Events eintritt.
Die Abfrage, welcher Event kam, kann mitif (dwEvtMask & EV_RXCHAR)erfolgen.
Erst jetzt wird ReadFile aufgerufen, wenn möglich, noch mit Timeouts (s.o.).Blackbird
-
Danke, danke!!
Nur zum Verständnis nochmal deutlich:
com1 : permanentes Signal im stringformat liegt an und soll gelesen und gespeichert werden,
bis:
com2: eine 0x01 z.B. bekommt (com2 wird also auch mit readfile() ausgelesen). Diese 0x01 soll das Lesen und Speichern von com1 beenden.
Kann das über Timeouts gehen??
-
flenders schrieb:
Wenn du die Leseopaeration assynchron, also overlapped, durchführst...
dann kehrt ReadFile sofort zurück liest aber trotzdem weiter ein

Du musst also bei CreateFile FILE_FLAG_OVERLAPPED mit angeben und dann bei ReadFile im letzten Parameter (lpOverlapped) einen Pointer auf eine OVERLAPPED-Struktur übergeben - näheres siehe Doku
-
Also inzwischen habe ich von einer Funktion WaitForSingleObject() erfahren.
Jetzt hat sich das Problem geändert. Sorry, ich kannte die Fumktion bis heute nicht...
Also: Com1 empfängt permanent. CreateFile(com1h), dann ReadFile(com1h)
bei '0x01' an Com2 (auch CreateFile(com2h) & ReadFile(com2h)) soll ReadFile(com1h) mit schreiben der Werte in seinen Buffer beginnen und für exact 2000msek füllen.
Ungefähr so:for(;;) //Warten auf 0x01 { ReadFile(Com2h, &Wert, 1, &AnzBytesTeller, NULL); if(Wert[0]==0x01){break;} } char String[10500]; ReadFile(Com1h, &String, 10500, &AnzBytesLaser, NULL); //Die gelesenen char wurden zum StringWie initialisiere ich jetzt: WaitForSingleObject(LaserCom,Stop),
wenn: DWORD Stop = 2000; //2s = 2000ms
sein soll?...Danke für alle Hilfe!!!
-
Imho wirst du um Threads oder OVERLAPPED nicht rum kommen. Zumindest kann ich mir nicht vorstellen, das ein zeichenweises einlesen besonders effizient ist

BTW: Wo willst du bei deiner Variante jetzt das WaitForSingleObject einbauen

-
Du hast es erkannt!!!
Wo mache ich das? Das ist DIE Frage.
Ich kenne mich null mit threads oder overlapped aus.
Ich brauche alle gesendeten Zeichen und leider kenne ich auch nur diese einzige möglichkeit ASCII Werte über com einzulesen. Gibt ´s noch eine andere Variante? Inzwischen weisst Du ja, was ich erreichen muß.Danke
-
Ich habe dir doch schon geschrieben, wie du vorgehen solltest:
- COM1 mit CreateFile unter Angabe FILE_FLAG_OVERLAPPED öffnen (bei ReadFile musst du dann auch eine OVERLAPPED-Struktur - letzter Parameter - verwenden)
- Für COM2 machst du es ganz genau so (FILE_FLAG_OVERLAPPED + OVERLAPPED-Struktur)
- Jetzt wartest du mit WaitForMultipleObjects unter Angabe der beiden hEvent-Members der OVERLAPPED-Strukturen, dass eine der beiden Lese-Operationen beendet wird. Je nach dem, ob die erste, oder die zweite Leseoperation fertig war (Rückgabewert von WaitForMultipleObjects). Falls es die von COM2 war brichst du die erste (COM1) mit CancelIo abSo hätte ich mir das jetzt vorgestellt

-
Ach so! Sorry!
Ich war auf dem Trip, es mit dem WaitForSingleObject() zu versuchen. Oke.
Kannst Du mir bitte den dritten Punkt etwas genauer erklären? Ich habe noch nie ein Event angelegt, da gehört ja sau - viel zur Struktur dazu...
-
... soll ReadFile(com1h) mit schreiben der Werte in seinen Buffer beginnen und für exact 2000msek füllen
Das wird wohl nur mit zeichenweisem Einlesen zu machen sein. Sofort nach Empfang jedes Events EV_RXCHAR die Zeit mit QueryPerformanceCounter holen, mit QueryPerformanceFrequency berechnen und exakt nach 2000 ms abbrechen.
Die Startbedingung über die 2. serielle Schnittstelle kompliziert die Sache etwas, denn die ist nicht besonders zeitgenau. Alternativ kann auch ein User-Event oder ein Timer als Start herhalten. Die Daten liegen ja 'eh als kontinuierlicher "String" an COM1 an.
Ohne Threads wird's wohl nicht gehen.
Ein schönes Beispielprogramm ist TTY von MS. Gehört zum MSDN? oder auch zum VC++6.0? dazu. Einfach mal auf der HDD danach suchen.
Blackbird
-
Mr. T schrieb:
Kannst Du mir bitte den dritten Punkt etwas genauer erklären? Ich habe noch nie ein Event angelegt, da gehört ja sau - viel zur Struktur dazu...
Ist eigentlich nichts groß aufwändiges - wenn mein Code so stimmt:
CreateEvent(NULL,TRUE,FALSE,NULL);