-
        

Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: UART-Synchronisation (like Interrupt) am PC

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122

    UART-Synchronisation (like Interrupt) am PC

    Anzeige

    HalloHallo...

    Ich habe mir in Borland C++ ein Programm zur RS232 Kommunikation geschrieben. Funktioniert eigentlich ganz gut...
    Nur leider gibt es ein klitzekleines Problemchen

    Zum Vergleich: Auf dem uC wird bei UART Empfang ein Interrupt ausgelöst -- Beim PC gibt es meines Wissens nach keine Empfangsinterrupts (wenn ja, wäre mein Problem gelöst...), daher habe ich einfach einen Timer eingebaut, der jede 10ms den COMPort liest. Jetzt das Problem: wenn etwas vom uC genau dann gesendet wird, wenn der Timer halt eben nicht aktiv ist, dann werden einige Zeichen abgeschnitten... Das heisst, dass die Kommunikation nicht synchron ist...

    Wie könnte ich dieses Problem lösen, ohnen den Timer extrem herunterzusetzen?

    Danke

    MfG Surfer

  2. #2
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    31.01.2004
    Ort
    36399
    Alter
    43
    Beiträge
    1.517
    naja einen interrupt gibt es nicht ganz aber es gibt eine Wait funktion.

    ich denke du programmierst unter windows sonst brauchst du nicht weiter lesen.

    Code:
    //init
     m_hCOM = CreateFile(m_csCOM.operator LPCTSTR(),GENERIC_WRITE | GENERIC_READ,0,NULL,OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);
        if(m_hCOM == INVALID_HANDLE_VALUE)
        {
            return false;
        }
    
    // lesen
            ReadFile(m_hCOM,Buffer,1,&readen,&o);
            WaitForSingleObject(o.hEvent,INFINITE);
            GetOverlappedResult(m_hCOM,&o,&Bytes,FALSE);
    Das waitforsingeleObject kommt erst zurrück wenn ein zeichen geslesen wurde.

    Gruß
    Home
    P: Meine Tochter (06.11.07) und Link
    M: Träumen hat nix mit Dummheit zu tun es ist die Möglichkeit neues zu erdenken

  3. #3
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122
    Das tönt schon recht gut... aber ist das auch unabhängig von anderen Prozessen, so wie der Timer... also das es dann nicht an dieser Programmstelle wartet, bis das Signal kommt. Alle anderen Funktionen im Programm müssen normal weiterlaufen können...

  4. #4
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    31.01.2004
    Ort
    36399
    Alter
    43
    Beiträge
    1.517
    dann mach halt eine thread draus so ist das eh üblich bei sollchen sachen.
    jetzt serial komunikation ist gethreadet.

    Gruß
    Home
    P: Meine Tochter (06.11.07) und Link
    M: Träumen hat nix mit Dummheit zu tun es ist die Möglichkeit neues zu erdenken

  5. #5
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122
    Also... Ich hab jetzt mal das ganze Programm versucht zu schreiben.
    Habe die Overlapped-Abfrage in einen Thread gesteckt...
    Nun habe ich nur das Problem, dass sobald ich im CreateFile das Attribut "FILE_FLAG_OVERLAPPED" setze, funktioniert die ganze Kommunikation nicht mehr. Ich kann den Port auch nicht mehr richtig schliessen. Ich schicke mal den Code... vielleich siehst du einen Fehler...

    Code:
    //---------------------------------------------------------------------------
    DWORD WINAPI Datenthread( LPVOID lpParam ) 
    {
        while(threading)
        {
            ReadFile(hComm, buffer, 10, &dwBytesRead, NULL);
            WaitForSingleObject(hComm,INFINITE);
            GetOverlappedResult(hComm,NULL,&dwBytesRead,FALSE);
            Form2->Memo1->Text=dwBytesRead;
        }
    
        return 0;
    }
    //---------------------------------------------------------------------------
    
    void __fastcall TForm1::Button1Click(TObject *Sender)
    {
            if(active==false&&ComboBox1->ItemIndex!=-1&&ComboBox2->ItemIndex!=-1)
            {
                    DCB dcbCommPort;
    
                    hComm = CreateFile(com,
                          GENERIC_READ | GENERIC_WRITE,
                          0,
                          NULL,
                          OPEN_EXISTING,
                          FILE_FLAG_OVERLAPPED,   //<-- Da will es nicht so ganz...
                          NULL);
    
    
                    if(hComm == INVALID_HANDLE_VALUE) Application->MessageBox(" !! Bitte anderen Port wählen !!    \n\n Der gewählte Port wird schon\nvon einem anderem Programm\n   benutzt oder existiert nicht.","      .........::: Portfehler :::.........",MB_OK);
                    else
                    {
                            Form2->Visible=true;
                            threading=true;
                            hThread=CreateThread(NULL,0,Datenthread,&dwThrdParam,0,&dwThreadId);
                            active=true;
                            Button1->Enabled=false;
                            Button2->Enabled=true;
    
                            StatusBar1->Panels->Items[3]->Text="Status: geöffnet";
                    }
                    GetCommTimeouts(hComm,&ctmoOld);
                    ctmoNew.ReadTotalTimeoutConstant = 100;
                    ctmoNew.ReadTotalTimeoutMultiplier = 0;
                    ctmoNew.WriteTotalTimeoutMultiplier = 0;
                    ctmoNew.WriteTotalTimeoutConstant = 0;
                    SetCommTimeouts(hComm, &ctmoNew);
    
                    dcbCommPort.DCBlength = sizeof(DCB);
                    GetCommState(hComm, &dcbCommPort);
    
                    switch(ComboBox2->ItemIndex)
                    {
                            case 0: BuildCommDCB("110,N,8,1", &dcbCommPort); break;
                            case 1: BuildCommDCB("300,N,8,1", &dcbCommPort); break;
                            case 2: BuildCommDCB("1200,N,8,1", &dcbCommPort); break;
                            case 3: BuildCommDCB("2400,N,8,1", &dcbCommPort); break;
                            case 4: BuildCommDCB("4800,N,8,1", &dcbCommPort); break;
                            case 5: BuildCommDCB("9600,N,8,1", &dcbCommPort); break;
                            case 6: BuildCommDCB("19200,N,8,1", &dcbCommPort); break;
                            case 7: BuildCommDCB("38400,N,8,1", &dcbCommPort); break;
                            case 8: BuildCommDCB("57600,N,8,1", &dcbCommPort); break;
                            case 9: BuildCommDCB("115200,N,8,1", &dcbCommPort); break;
                            case 10: BuildCommDCB("230400,N,8,1", &dcbCommPort); break;
                            case 11: BuildCommDCB("460800,N,8,1", &dcbCommPort); break;
                            case 12: BuildCommDCB("921600,N,8,1", &dcbCommPort); break;
                            default: Application->Terminate(); break;
                    }
    
                    SetCommState(hComm, &dcbCommPort);
            }
    }

  6. #6
    Erfahrener Benutzer Begeisterter Techniker Avatar von engineer
    Registriert seit
    24.01.2005
    Ort
    Raum Frankfurt
    Beiträge
    268
    Das darf eigentlich nicht sein. Bei korrektem Betrieb tauchst Du nur ein eine Leseroutone ein, welche den aktuellen seriellen Buffer solange ausliest, wie nichts mehr komt, also kein Zeichen ansteht. Ich time solche Zugriffe so, daß ich immer mindestens ein Zeichen vorfinde, aber der Buffer immer geleert werden kann, also nie mehr als z.B. 20 Zeichen reingeschrieben wurden. Das ist am effizientesten.

    Eine Leseroutine samt Tinitialisierung findest Du auf meiner Hp, bzw kann ich Dir senden.

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122
    Wäre nett, wenn du sie mir schicken könntest! Danke

  8. #8
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    31.01.2004
    Ort
    36399
    Alter
    43
    Beiträge
    1.517
    Hallo surfer,

    in dem Read muß du auch die Overlapp strucktur mit übergeben.
    und du drafs von ein thread nicht so auf obflächen element zu greifen
    das gibt schutz verletzungen. es gibt bei Borland den sync befehlt für so was
    aber ich persöhnlich mache es immer über nachrichten. da ich mit MS C++ arbeite da gibt es keine VCL.

    zum beenden muß du dann das evnet aus lösen. und die variable setzen dann sollte sich der thread beenden und du kannst die com schliesen.

    Gruß
    Home
    P: Meine Tochter (06.11.07) und Link
    M: Träumen hat nix mit Dummheit zu tun es ist die Möglichkeit neues zu erdenken

  9. #9
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.07.2004
    Beiträge
    122
    Tja, NumberFive... Ich muss gestehen, irgendwie ist mir das ein bisschen zu viel... Ich bin halt nicht so ein C++ Genie...

    Wie kann ich die Overlapp-Struktur übergeben?
    Soll ich im Thread einfach ein Unterprogramm aufrufen lassen?

  10. #10
    Erfahrener Benutzer Begeisterter Techniker Avatar von engineer
    Registriert seit
    24.01.2005
    Ort
    Raum Frankfurt
    Beiträge
    268
    Hier ist der link:
    http://home.arcor.de/juergen.schuhmacher/pdf/spmdwx.pdf

    Ich hoffe, es ist das aktualisierte.

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •