RS485 Schnittstelle auf pci Steckplatz



  • Yo,

    das ist so! Die Schnittstellenkarte hat bei mir die COM3 Adresse. Aber die Fukntionsweise der CreateFile und was alles dazugehört sind mir unklar. Gibt´s nicht irgendwo im Netz etwas wo ich einfach alle Funktionen nachschlagen kann? Ich habe wie gesagt keine Ahnung von der CreateFile Funktion etc..

    Thanxx



  • Du musst bei CreateFile() quasi als Dateinamen "COM3" angeben und kannst dann ReadFile() und WriteFile() auf das Handle von CreateFile() anwenden.
    Kannst ja hier mal hier im winapi-forum nach "serielle Schnittstelle" suchen, da gibts mehrere Threads zu...



  • 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 mit

    if (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 String
    

    Wie 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 ab

    So 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);
    

Anmelden zum Antworten