Konfigurowanie portu COM

0

Witam
Przy odpaleniu programu CreateFile() zawsze zwraca mi INVALID_HANDLE_VALUE oto kod :

#include <stdio.h>
#include <windows.h>
#include <tchar.h>

int main(int argc,char* argv[])
{
    TCHAR *NazwaPortu=TEXT("COM2");
    DCB dcb;
    BOOL check;
    HANDLE uchwyt;
    //stworzenie portu COM1 lub COM2 
    uchwyt=CreateFile(NazwaPortu,GENERIC_READ|GENERIC_WRITE,0,NULL,OPEN_EXISTING,0,NULL);
    if (uchwyt==INVALID_HANDLE_VALUE){
                                      printf("CreateFiile zwróciło błąd numer %d",GetLastError());
                                      return (1);
                                      }                               
    dcb.DCBlength=sizeof(DCB);
    //pobranie ustawien portu
    check=GetCommState(uchwyt,&dcb);
    if (!check){
                printf("GetCommState zwróciło błąd numer %s",GetLastError());
                return (2);
                }
    //konifguracja portu             
    dcb.BaudRate = CBR_9600;     //  predkosc transmisji danych 9600
    dcb.ByteSize = 8;             //  ilosc bitów danych
    dcb.Parity = NOPARITY;        // brak bitu parzystosci
    dcb.StopBits = ONESTOPBIT;    //  1 bit stopu   
    //Zapisanie ustawien portu
    check=SetCommState(uchwyt,&dcb);
    if(!check){
               printf("SetCommState zwrócił błąd numer %d",GetLastError());
               return (3);
               }
    check=GetCommState(uchwyt,&dcb);
    if(!check){
               printf("GetCommState zwrócił błąd numer %d",GetLastError());
               return (2);
               }
    printf("\nUstawiona prędkość:%d\nIlosc bitów danych:%d\nParzystosc:%d\nBity stopu:%d\n",dcb.BaudRate,dcb.ByteSize,dcb.Parity,dcb.StopBits);
    
    printf("Port:%s został skonfigurowany pomyślnie!",NazwaPortu);
    system("pause");
    return 0;
}

 

z gory dziekuje za pomoc

0

2 pytania

  1. Na czym odpalasz program? W sensie PC/laptop.

  2. Co przekazujesz jako nazwe portu? Powinno byc COM1 COM2 itd.
    Do tego nie uzywaj wide charow uzyj wersji tej funkcji ktora bierze zwyklego chara CreateFileA.

  3. Co tak pozno sie zabierasz za programy na zaliczenie ;p

0

Jako nazwa portu tam jest u góry COM2 a to tak dla siebie robię bo jestem w 2 liceum dopiero ;)
odpalam na netbooku ;)

0

No to wypadaloby sie zorientowac moze najpierw, czy taki netbook posiada aktywny port com, ktory moznaby otworzyc? Do testowania uzywalem
http://www.eltima.com/products/vspdxp/
Tworzy wirtualne porty z ktorymi mozna sie laczyc, wysylac i odbierac dane.

Do tego samo ustawienie portu comm to troche wiecej danych niz to co ty u siebie robisz. Oprocz ustawienia samego portu trzeba jeszcze ustawic timeouty.

0

masz na myśli takie coś ?

 if (hCommDev != INVALID_HANDLE_VALUE)
{
        dcb.DCBlength = sizeof(dcb);
        if(!GetCommState(hCommDev, &dcb))
                return false;
        dcb.BaudRate = 19200;
        //transmission parameters
        dcb.Parity = NOPARITY;
        dcb.StopBits = ONESTOPBIT;
        dcb.ByteSize = 8;
        //DCB flags
        dcb.fParity = FALSE;
        dcb.fDtrControl = DTR_CONTROL_DISABLE;
        //DTR line dislabled
        dcb.fRtsControl = RTS_CONTROL_DISABLE;
        //RTS line disabled
        dcb.fOutxCtsFlow = FALSE;
        dcb.fOutxDsrFlow = FALSE;
        dcb.fDsrSensitivity = FALSE;
        dcb.fAbortOnError = FALSE;
        dcb.fOutX = FALSE;
        dcb.fInX = FALSE;
        dcb.fErrorChar = FALSE;
        dcb.fNull = FALSE;
        if(!SetCommState(hCommDev,&dcb))
                return false;
        if(!SetupComm(hCommDev, cbInQueue, cbOutQueue))
                return false;
}

Po zrobieniu wirtualnych portów program odpala sie i nie zwraca zadnych błedow :)

1

Potem jak znajde swoj kod do terminala, to pokaze dokladniej. ;p

Prosze bardzo. Programik bedzie idealnie dzialal na modemach z obsluga komend hayesa ;) Dobry do polaczen dalekopisowych.

bool Settings::Connect(QString port, int Sendrate)
{
    // LACZENIE //
    hPort = CreateFileA(port.toStdString().data(), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL); // tworzmy polaczenie na porcie
    if(hPort == INVALID_HANDLE_VALUE) return false;

    // KONFIGURACJA //
    SetCom.DCBlength = sizeof(DCB);
    if(!GetCommState(hPort,&SetCom))
    {
        CloseHandle(hPort);
        return false;
    }
    // PORT COM - Config //
    SetCom.BaudRate = Sendrate;
    SetCom.fBinary=TRUE;                 //windows nie wspiera nonbinary
    SetCom.fParity=TRUE;
    SetCom.fOutxCtsFlow = FALSE;         // No CTS output flow control
    SetCom.fOutxDsrFlow = FALSE;         // No DSR output flow control
    SetCom.fDtrControl=DTR_CONTROL_ENABLE;
    SetCom.fDsrSensitivity=false;
    SetCom.fTXContinueOnXoff=true;
    SetCom.fOutX=false;
    SetCom.fInX=false;
    SetCom.fErrorChar=false;
    SetCom.fNull=false;
    SetCom.fRtsControl=RTS_CONTROL_ENABLE;
    SetCom.fAbortOnError=false;
    SetCom.ByteSize=8;
    SetCom.Parity=NOPARITY;
    SetCom.StopBits=ONESTOPBIT;

    if(!SetCommState(hPort,&SetCom))
    {
        CloseHandle(hPort);
        return false;
    }

    if(!GetCommTimeouts(hPort,&timeout))
    {
        CloseHandle(hPort);
        return false;
    }
    // TIMEOUTY //
    timeout.ReadIntervalTimeout=MAXDWORD;
    timeout.ReadTotalTimeoutMultiplier=0;
    timeout.ReadTotalTimeoutConstant=0;
    timeout.WriteTotalTimeoutMultiplier=10;
    timeout.WriteTotalTimeoutConstant=100;

    if(!SetCommTimeouts(hPort,&timeout))
    {
        CloseHandle(hPort);
        return false;
    }

    Connected = true;
    return true;
}
0

mi chodzi o wysylanie pliku przez port szeregowy i odbieranie go na innym komputerze do tego chcialem sobie to zokienkowac w qt zeby sie czegos nauczyc i sie pobawic :) Bo na linuxie zrobilem ale jeszcze chcialem zrobic na win bo tutaj troche to trudniejsze jest ;) ale dziekuje bardzo za pomoc :) i na pewno skorzystam :P

0

Do tego tez sie sprawdzi dobrze. Same ustawienia czyli to co podalem sie nie zmienia. To jest jedynie otwarcie portu com. Ogolnie jest to bardzo powolne przez port com ;) Dorzuc sobie do tego sprawdzanie sumy kontrolnej crc-16 i bedzie to identyczny program jak ja na telekomunikacje musialem napisac xD

0

dlaczego gdy wysylam dane do tego wirtualnego portu one sie zapisuje a gdy chce je odebrac program zatrzymuje sie w momencie gdy dane maja byc odbierane .

    ReadFile (uchwyt,plikbuf,sizeof(plikbuf), &write, NULL); 
0

Bo trzeba to ladnie w watki upakowac ;) U mnie funkcja odbierajaca wyglada tak

char Receiver::RecvPort(HANDLE port, char &msg)
{
    DWORD Received = 0;
    if(ReadFile(port,&msg,1,&Received,0)!=0) return msg;
    else
    {
        msg = '\n';
        return 0;
    }
}

Received jest zbedne akurat.

0

http://msdn.microsoft.com/en-us/library/ms900134.aspx a mi sie zacina jak wywolam ta funckje i nie chce pchnac dalej programu a wg tamtego powinno dzialac

1

Zeby cos moglo byc odebrane, musi byc wyslane. Tam jest odczyt z pliku, to jest troche inna sprawa. Przy odczycie z portu trzeba utworzy 2 watki. Jeden do wysylania i 1 do odbierania danych, bo dane nie musza byc caly czas wysylane, dopiero jak cos zostanie wyslane to odczyta to. Do tego jesli chcesz przesylac na 1 kompie to wszystko. Musisz otworzy 2 aplikacje jedna polaczona na porcie 1 druga na porcie com2 i wtedy informacje sa przesylane z jednego portu na drugi. Nie mozna przeslac do samego siebie niestety.

0

Jest jeszcze drugie rozwiazanie - zmiana limitu czasu jaki funkcja ReadFile ma na odczytanie danych z portu - wtedy po prostu odczyta tyle danych ile bedzie gotowych do odczytania. Domysle wartosci to chyba nieskonczonosc czasu, wiec ReadFile czeka az w koncu pojawi sie cos od odebrania, ale mozesz zmienic te wartosci tak zeby odczytywal to co jest i zwracal te dane nie czekajac na wiecej. SetCommTimeouts

0

Jakie timeouty najlepiej ustawic do wysylania i odpierania plików ? 50 milisekund wystarczy?
Wlasnie tak mialem probowac wyslac z jednej aplikacji i odebrac z 2 ;) Tylko nie wiedzialem
jak to sie zachowa ale juz wiem ze jak wysle na com1 to odbiore z com2 ;) dzieki wielkie ;p
..
I tak jeszcze zapytam a jak odpale aplikacje na jednym kompie i na drugim to wszystko leci do com1 i odbieram
z com1 ?

1

Przy polaczeniu 2 kompow tak. Laczysz oba na com1 i beda wysylac do siebie. Kabel tez musi byc odpowiedni. My uzywalismy rs232 oba zlacza typ meski jesli dobrze pamietam.
Timeouty powinny byc dobre te co podalem u siebie w kodzie wczesniej. Ogolne dla portu beda dobre i do komunikacji zwyklej i do przesylania plikow.

0

No ja tez rs232 uzywałem przy wysylaniu pliku na linuxie ;P Dzieki wielkie za pomoc :)

1 użytkowników online, w tym zalogowanych: 0, gości: 1