logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

Sterowanie portem RS232/COM w Delphi z użyciem wstawek assemblerowych

rafiks 22 Lut 2003 17:23 13065 18
REKLAMA
  • #1 107093
    rafiks
    Poziom 18  
    Posty: 425
    Ocena: 7
    Jak sterować portm rs232/com w komputerze z poziomu delphi. Napewno będzie trzeba dać wstawkę assemblerową, ale jaką. Może ktoś wie jak się steruje tym portem w komputerze.

    Wielkie dzięki
  • REKLAMA
  • #2 107332
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    Wstawki sobie odpuść bo będą one działać tylko pod 95/98, pod XP podobno tak jeśli się zainstaluje specjalny driver. Pod windowsami otwierasz plik "com2:" i robisz zapis/odczyta tak jak do/z pliku. Jeśli chcesz więcej szczegółów to sprecyzuj bardziej swoje pytanie.
    PS do delphi są też jakieś gotowe komponenty ale ja osobiście z nich nie korzystam.Jeden się chyba nazywa "Asynch".
  • #3 107513
    rafiks
    Poziom 18  
    Posty: 425
    Ocena: 7
    Jak wysłać i odczytać stany na tym porcie? Poco się go otwiera? Czym różni się od LPT, myślałem że to działa na tej samej zasadzie tylko ma mniej wyprowadzeń!
  • REKLAMA
  • #4 107531
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    Port szeregowy działa na całkiem innej zasadzie. Podaje się mu liczbe iluś-bitową (to można skonfigurować) a on przekształci ją w ciąg binarny rozpoczynający się bitem startu a zakończony bitem stopu. Układ sterownika zbudowany jest z rejestru przesuwnego do którego wpisuje się wartość do wysłania a w czasie wysyłania kolejne bity są przesuwane tak aby opróżnić cały rejestr. Odbiór polega na wykryciu bitu startu a następnie zdekodowaniu kolejnych bitów. Stanu logicznego na liniach transmisyjnych nie da się dowolnie zmieniać, można jedynie wybierać wartość danych do przesłania, Dodatkowo dostępne są linie RTS (Request To Send) DTR (Data Terminal Ready) których stan może być stały, związany z transmisją (handshaking). Dodatkowo dostępna jest odpowiadająca im para sygnałow DSR i CTS których stan może być sprawdzony programowo jak i sprzętowo. Uzupełniem tych lini jest linia RI (Ring Indicator) która jest w standardzie ale nie jest zawsze implementowana, jej zadaniem jest generowanie przerwania przy nadejściu sygnału dzwonka do modemu.
  • #5 108215
    Kuba_eM
    Poziom 24  
    Posty: 654
    Pomógł: 36
    Ocena: 77
    Heja!
    Temat już był poruszany nie raz. "Delphiarzom" jak zawsze polecam stronę www.torry.net. Jest tam pełno komponentów m.i. do komunikacji za pomocą RSa. Ja od kilku lat używam komponenetu ze strony xcomdrv.host.sk (projekt już nie rozwijany). Od prawie półtora roku działam na XP i programiki z Delphi z tym komponentem działają bez najmniejszych problemów. To samo jest w robocie z innymi Windami.
    Pozdrawiam,
  • #6 108219
    Kuba_eM
    Poziom 24  
    Posty: 654
    Pomógł: 36
    Ocena: 77
    A jak nie chcesz komponentów, to w książce "RS232 - praktyczne programowanie" (lub tytuł zbliżony - jest już drugie wydanie), jest bardzo dobry opis jak się dostać do RSa za pimocą WIN API, z przykładami. Warto się zapoznać.
    Pozdrawiam,
  • REKLAMA
  • #7 108322
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    Ta książka ostatnio pojawiła się na elektrodzie w formie skanu, wczoraj ją akurat przejrzałem i wnioskuje że posiada kilka niedociągnięć, nie ma opisanej żadnej metody kontroli i ustawiania lini sterujących transmisją.
  • #8 110334
    jasiekz
    Poziom 15  
    Posty: 128
    Pomógł: 5
    Ocena: 2
    Ja używam RS już od dawna w delphi. wcześniej korzystałem z komponentu comport (dejana). jest to bardzo dobry komponent do portu szeregowego. Ale ostatnio musiałem z niego zrezygnować z powodu sterowania RTS.(musiałem napisać swojego dll akurat na podstawie tej książki i nie narzekam) Doszedłem do tego że w windzie jest poważny błąd (serial.vxd)i nie potrafi ona poprawnie sterować RTS sprzętowym. podobno działa to w 2000 ale w 95,98 nie. Jak jest w Xp nie wiem. musiałem więc programowo sterować tą linią. ale winda jak zwykle się nie słucha i często nie załączy w odpowiednim czasie i nie zdąży wracać z powrotem mimo stosowania przerw czasowych. Jak chcesz to napisz czy chcesz ten komponent to go wyślę z jakimś prostym opisem.(jest darmowy i dobry dla początkujących)
  • #9 118293
    krzysztof1
    Poziom 12  
    Posty: 86
    Ocena: 5
    ->elektryk
    Gdybyś mógł podać link do skanu "RS232- Praktyczne Programowanie".
    Nie mogę tego zanleźć :)
  • #11 119637
    painkiller
    Poziom 13  
    Posty: 51
    tu jest moja procedura od inicjalizacii jak troche pisz4esz w delphi to niebedziesz mial problemow

    HCOM := CreateFile(comn{pchar np 'COM1'},
    GENERIC_READ or GENERIC_WRITE,0,nil,OPEN_EXISTING,
    FILE_ATTRIBUTE_NORMAL or File_Flag_Overlapped,0);

    fillchar( dcb, sizeof(dcb), 0 );
    dcb.DCBLength := sizeof(dcb);
    dcb.BaudRate:=speed;
    dcb.Flags := 1;
    dcb.ByteSize := 8;
    dcb.Parity := NOPARITY;
    dcb.StopBits := ONESTOPBIT;
    SetCommState( HCOM, dcb )
    SetupComm(HCOM, 4, 4)

    //odczyt
    readfile(HCOM,r , 4, nread, nil);

    //zapis
    writefile( HCOM,d[0], 4, nsent, nil );


    cos takiego
  • #12 119647
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    Polecam
    zamiast ręcznej inicjacji DCB :
    GetCommState(HCOM,dcb);
    <zmienić wybrane parametry>
    SetCommState(HCOM,dcb);
    Pozatym lepiej sobie ustawić timeouty żeby trasnsmisja nie zawieszała w przypadku jeśli nic nie nadaje.
  • #13 120795
    Rysiek_W
    Poziom 12  
    Posty: 27
    Ocena: 2
    Proponuje opis obsługi portu szeregowego pod WIN98 na stronie Elektroniki praktycznej (strefa download->dokumentacje). Porty są obsługiwane funkcjami API, sam wykonałem parę prostych aplikacji z wykorzystaniem opisanych tam funkcji - wszystko działa OK. 8)
  • #14 1318943
    firedrake
    Poziom 11  
    Posty: 19
    Witam!
    Mam maly problem z odczytem stanu linii CTS DSR ktore sa ustawiane przez drugie urzadzenie. Nie chce korzystac z handshakingu tylko samemu odczytywac stan tych lini i wyswietlac to w postaci diody w mojej app. Przykladem moze byc terminal.exe. W tym programie autor zrobil takie zielone diody do pokazywania stanu linii i tam wszystko dziala a ja nie moge sie dobrac to tych linii. RTS i DTR ustawiam i odczytuje ale nie moge tego uzyskac co do CTS i DSR.
    Prosze o pomoc bo juz przeszukalem wiekszosc stron na necie i nie moge znalezc zadnej funkcji API do tego odczytywania.
    Pozdrawiam!
  • #15 1330082
    Smoczy
    Poziom 20  
    Posty: 436
    Pomógł: 26
    Ocena: 67
    Jest książka na temat obsługi RS232 w delphi, i do tej książki jest dołączona płyta z przykładami. Nie wiem jednak czy ja. posiadając taką płyte moze te przykłady zamieścić na forum (prawa autorskie). Prosze o odpowiedź, czy jest to możliwe i dopuszczalne. Jeżeli tak to bez problemu całą zawartość wystawie.
  • REKLAMA
  • #16 1360644
    marek_Łódź
    Poziom 36  
    Posty: 3103
    Pomógł: 208
    Ocena: 66
    Dziwne zjawisko

    czy ktoś mi potrafi wyjaśnić obecność pól o nazwach zaczynających się literką f w helpie DELPHI5 dcb

    fbinary,fOutxCtsFlow,fOutX,fOutxDsrFlow,fDsrSensitivity itp.

    pola te prawdopodobnie nie występują w DCB, gdy kompiluję program odwołujący się do tych pól, stwierdza niezidentyfikowaną zmienną.

    W związku z tym nie bardzo wiem, jak z poziomu programu wyłączyć XON/XOFF lub zmienić obsługę sygnałów modemu.

    Dopisano po około xxx godz

    Cytat:
    Literka f oznacza, że dane pole to flaga (w notacji jakiegoś węgra bodajrze).


    Jak się odwołuję do tych pól to Delphi 5 sygnalizuje mi niezdefiniowaną zmienną. W helpie wszystkie te pola są opisane. Czy ktoś wie o co chodzi i jak włączyć/wyłączyć XON/XOFF.

    typedef struct _DCB { // dcb  
        DWORD DCBlength;           // sizeof(DCB) 
        DWORD BaudRate;            // current baud rate 
        DWORD fBinary: 1;          // binary mode, no EOF check 
        DWORD fParity: 1;          // enable parity checking 
        DWORD fOutxCtsFlow:1;      // CTS output flow control 
        DWORD fOutxDsrFlow:1;      // DSR output flow control 
        DWORD fDtrControl:2;       // DTR flow control type 
        DWORD fDsrSensitivity:1;   // DSR sensitivity 
    
        DWORD fTXContinueOnXoff:1; // XOFF continues Tx 
        DWORD fOutX: 1;            // XON/XOFF out flow control 
        DWORD fInX: 1;             // XON/XOFF in flow control 
        DWORD fErrorChar: 1;       // enable error replacement 
        DWORD fNull: 1;            // enable null stripping 
        DWORD fRtsControl:2;       // RTS flow control 
        DWORD fAbortOnError:1;     // abort reads/writes on error 
        DWORD fDummy2:17;          // reserved 
        WORD wReserved;            // not currently used 
    
        WORD XonLim;               // transmit XON threshold 
        WORD XoffLim;              // transmit XOFF threshold 
        BYTE ByteSize;             // number of bits/byte, 4-8 
        BYTE Parity;               // 0-4=no,odd,even,mark,space 
        BYTE StopBits;             // 0,1,2 = 1, 1.5, 2 
        char XonChar;              // Tx and Rx XON character 
        char XoffChar;             // Tx and Rx XOFF character 
        char ErrorChar;            // error replacement character 
    
        char EofChar;              // end of input character 
        char EvtChar;              // received event character 
        WORD wReserved1;           // reserved; do not use 
    } DCB; 
    
      with dcb do
        begin
        BaudRate:=cbr_38400;   //OK
        StopBits:=ONESTOPBIT; //OK 
        fbinary:=1;                   //Undeclared identifier "fbinary"
        end;
    
     


    Sorry, nie chciałem mnożyć postów.
  • #17 1363326
    Smoczy
    Poziom 20  
    Posty: 436
    Pomógł: 26
    Ocena: 67
    Literka f oznacza, że dane pole to flaga (w notacji jakiegoś węgra bodajrze).
  • #18 2613680
    KanGu
    Poziom 13  
    Posty: 76
    Pomógł: 4
    Ocena: 1
    czytam czytam i nie moge nic znaleść o tych zapytaniach :cry:

    
      query : PChar = 'CDAT?'+#13+#10;  // przykładowe zapytanie
                                      // zakończone parą znaków CR LF
    


    Czy ktoś pomógłby mi to zrozumieć (dodam że sam się tego ucze i nie mam z nikąd pomocy). Sama ksiązka sporo mi dała "Praktyczne programowanie rs232" sporo objaśnień odnośnie całej komunikacji ale nigdzie tam nie ma wyjaśnień jakie zapytanie wysyłaja inne urządzenia np mikrokontrolery czy należy w nich coś ustawiać przed wysłaniem itp.

    Mam dwa DS'y w ktorych obliczam wynik w następujący sposób:

    
    Dim Name As String * 10
    Dim Bd(9) As Byte
    Dim Tmp As Integer
    Dim Wynik As Single
    dim temp1 as integer (albo string * 10)
    dim temp2 as integer (albo string * 10)
    '---------------------procedóra odczytu dla 2 taka sama
    Config 1wire = Portd.4
    1wreset
    If Err = 1 Then
    Locate 1 , 21
    Lcd "ERR   "
    Else
    1wwrite Skip_rom
    1wwrite Convert
    Waitms 800
    1wreset
    1wwrite Skip_rom
    1wwrite Read_sp
    Bd(1) = 1wread(9)
    1wreset
    Tmp = Bd(2) * 256
    Tmp = Tmp + Bd(1)
    Wynik = Tmp
    Wynik = Wynik / 16
    


    i wysyłam

    
    print temp1
    print temp2
    


    To jak to poźniej wyłapać w komputerze przy pomocy delphi. Z poziomu delphi nie mam problemów z wysyłaniem zapytań i znaków, a w Hyperterminalu wyświetla mi dobrze te dwie temperatury jedna pod drugą w pewnych krótkich odstępach czasu. Nie wiem jak je odczytac i wpisac do dwóch elemntach RichEdit

    Dodam tu jeszcze procedóry z Delphi jakich urzywam

    
    var
    
      query : PChar = 'CDAT?'+#13+#10;  // przykładowe zapytanie
                                      // zakończone parą znaków CR LF
      Buffer_O : ARRAY[0..cbOutQueue] of Char; // bufor wyjściowy
      Buffer_I : ARRAY[0..cbInQueue] of Char;  // bufor wejściowy
    //----------------------------------------------------------------------------------
    function TForm1.Read_Comm(hCommDev: THANDLE;
                               Buf_Size: DWORD): Integer;
      var
         nNumberOfBytesToRead: DWORD;
    begin
       ClearCommError(hCommDev, Errors, @Stat);
       if (Stat.cbInQue > 0) then
         begin
            if (Stat.cbInQue > Buf_Size) then
              nNumberOfBytesToRead := Buf_Size
              else
                 nNumberOfBytesToRead := Stat.cbInQue;
             ReadFile(hCommDev, Buffer_I, nNumberOfBytesToRead,
                      Number_Bytes_Read, NIL);
             Read_Comm := 1;
         end
           else
              begin
                Number_Bytes_Read := 0;
                Read_Comm := 0;
              end;
    end;
    //-----------------------------
      FlushFileBuffers(hCommDev);
      Until (Write_Comm(hCommDev, StrLen(Buffer_O)) <> 0);
    
      if (Read_Comm(hCommDev, SizeOf(Buffer_I)) > 0) then // odbiór
                                                           // danych
      RichEdit1.Text := Buffer_I
      else
      RichEdit1.Text := 'Brak danych'; 
    

    Przy urzyciu powyzszego kodu w elemencie RichEdit wyświetlaja mi sie dziwne znaki nie widze w nich nieczego co mogło by mi pomóc zrozumieć cały ten proces.

    Będe bardzo wdzięczny za wszelką pomoc zwłaszcza jeśli ktoś by miał chwile i mi to potłumaczył na gg czy przez mail'e :|:
  • #19 2623424
    Fakiros
    Poziom 13  
    Posty: 92
    Pomógł: 3
    Ocena: 1
    Proponuje komponent o nazwie "ComPort" , do sciagniecia w sieci, darmowy, znalazlem kiedys taki w google. Komponent jest z przykladami i moze b yc zainstalowany w delphi lub Builderze C++, bardzo prosty w obsłudze - polecam.

Podsumowanie tematu

✨ Dyskusja dotyczy sterowania portem RS232/COM w Delphi, z uwzględnieniem użycia wstawek assemblerowych oraz alternatywnych metod. Zaleca się rezygnację z wstawek assemblerowych ze względu na ograniczoną kompatybilność (działają głównie pod Windows 95/98, a pod XP wymagają specjalnych sterowników). Pod Windows otwiera się port jako plik (np. "COM2:") i operuje na nim za pomocą standardowych funkcji odczytu i zapisu plików. Istnieją gotowe komponenty Delphi do obsługi portu szeregowego, takie jak "Asynch", "Comport" (Dejana) oraz "ComPort" (darmowy, z przykładami), które ułatwiają komunikację i konfigurację. Opisano również podstawy działania portu szeregowego, w tym formatowanie danych (bity startu, stopu), rejestr przesuwający, oraz linie sterujące RTS, DTR, CTS, DSR i RI, z uwzględnieniem ich funkcji i problemów z ich programową kontrolą, zwłaszcza w systemach Windows (np. błędy w serial.vxd). Podkreślono znaczenie korzystania z API Windows do konfiguracji portu (funkcje CreateFile, SetCommState, SetupComm, ReadFile, WriteFile) oraz ustawiania timeoutów transmisji. Wskazano na przydatność literatury, zwłaszcza książki "RS232 - praktyczne programowanie", choć zauważono jej niedociągnięcia w opisie kontroli linii sterujących. Poruszono także kwestie problemów z odczytem stanów linii CTS i DSR bez użycia handshakingu oraz zagadnienia związane z polami flagowymi w strukturze DCB w Delphi. Udostępniono linki do zasobów i skanów książek oraz przykładowe fragmenty kodu inicjalizacji i obsługi portu w Delphi.
REKLAMA