Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Prędkość odbierania znaku port rs232 PC i odczyt lini RXD

wilk125 21 Sty 2009 13:24 3485 15
  • #1 21 Sty 2009 13:24
    wilk125
    Poziom 23  

    Witam
    Problem polega na tym, że jak wysyłam znak przez port rs232 komputera z predkoscią 5 baudrate to na drugim komputerze jest on odebrany dopiero po 10 sekundach. każdy bit wysylany jest co 200ms wiec z bitem startu i bitem stopu laczny czas wysłania znaku powinien wynosci 10x200ms czyli 2 sekundy. Komputer zdalny odbiera go dopiero po 10 sekundach, z czego to moze wynikać?

    Czy jest jakis sposób na odczyt stanu lini RXD?

    0 15
  • #2 21 Sty 2009 18:32
    one_eddie
    Poziom 25  

    W jaki sposob wysyłasz ten znak (WinAPI/Custom DLL/io)? Pokaz fragment kodu.

    Po wiedz mi w jaki sposob ustawiles predkosc 5 na porcie? Kolejne pytanie ktore sie nasuwa brzmi: Dlaczego Ty wysyłasz bity, a nie bajty? Fizycznie i tak musisz wysyłać bajty, ale pakujesz pewnie w nie pojedyńcze bity z wartościami.

    Jeśli chodzi zaś o opózniony odbiór. Jesli klient będzie wysyłał znak co sek, a odbiorca będzie odbierał co 2 to będziesz miał taki własnie efekt.

    Porzedstaw swój kod to może będzie mozna powiedziec wiecej.

    0
  • #3 21 Sty 2009 18:54
    elektryk
    Poziom 42  

    wilk125 napisał:
    Problem polega na tym, że jak wysyłam znak przez port rs232 komputera z predkoscią 5 baudrate to na drugim komputerze jest on odebrany dopiero po 10 sekundach. każdy bit wysylany jest co 200ms wiec z bitem startu i bitem stopu laczny czas wysłania znaku powinien wynosci 10x200ms czyli 2 sekundy. Komputer zdalny odbiera go dopiero po 10 sekundach, z czego to moze wynikać?
    A w jaki sposób odbierasz te znaki? I tak z ciekawości jak ustawiłeś prędkość 5bit/sek ?

    0
  • #4 21 Sty 2009 19:00
    one_eddie
    Poziom 25  

    @elektryk: Sam zdziwilem sie jak mozna taka predkosc ustawic ale cusa moga sie przeceiz zdarzyc. Bardziej realnym jednak wydaje mi sie ze kolega sie pomylil i chodzilo o 500. Zakladam tez ze pierwszy raz zetknal sie z komunikacja i pomylilo mu sie kilka wartosci.

    0
  • #5 22 Sty 2009 11:17
    wilk125
    Poziom 23  

    Juz rozwiewam wszytskie wątpliwosci.

    1.Używam widows API (CreateFile itd).
    2. Wysyłam znak(bajt) nie bity, a to ze pisałem ze bit jest wysyłany co 200ms (UART robi to automatycznie) sekund wynika z ustawienia 5 baudrate. Ja normalnie uzuwam funkcji WriteFile(..) .
    3. W strukturze DCB jest pole BaudRate do którego wpisuje wartość 5 , pozniej wykonuje funkcje SetCommConfig i port jest ustawiony na 5 BaudRate. Prędkośc transmisji potwuerdzilem oscyloskopem jak również programem portmon, który bardzo fajnie wszytko pokazuje.
    4. Znak po drugiej stronie odbieram funkcją ReadFile, wczesniej czekam na pojawienie się znaku, moge to zrobic na dwa sposoby:
    a) Ustawiam flage zdarzenia EV_RXCHAR przy pomocy funkcji SetCommMask i przy pomocy funkcji WaitCommEvent czekam na odebrany znak;
    b) caly czas sprawdzam funkcją ClearCommError(port,erroe,stat) czy pole cbInQue (wskazuje na ilosc znakow odebranych i gotowych do odczytania) w strukturze stat zmienilo wartość.

    W obydwu przypadkach informacja o odebraniu znaku przez UART pojawia sie dopiero po okolo 10 sekundach i wtedy dopiero używam funkcji ReadFile, wczesniej i tak nie bylo czego odczytać.
    Zauważylem ze jak zmienie Baudrate na 10 to informacja o odebraniu znaku pojawia sie w czasie okolo 5 sekund czyli o plowe krótszym.

    Dodam jeszcze, że znak z komputera wysylany jest natychmiast, natomiast za tak długie opiznienie w informacji o odebranym znaku wine ponosi komputer odbierający znak

    Dodano po 22 [minuty]:

    Mam jescze dodatkowe pytanie, w jaki sposób można monitorować stan lini RxD?

    Dodano po 1 [godziny] 1 [minuty]:

    Zauważyłem tez, że jesli odbieram znak przy predkosci 5 baudrate i po ponad 2000ms (tyle czasu trwa wysylanie/odbieranie znaku) ustawie port (w komputerze odbierajacym znak) na dużo wyższe Baudrate np.9600 to znak zostaje odebrany praktycznie natychmiast jak tylko ustawie to baudrate. Nasuwa mi sie taki wniosek,że przy 5 baudrate znak z bufora wejsciowego jest przesuwany do nastepnych rejestrów z taka wolna predkoscią i zanim dojdzie do odpowiedniego rejestru ktory informuje sterownik portu a dalej API windowsa ze cos zostalo odebrane to mija te 10 sekund.

    Może wogóle napisze po co mi to 5 baudrate.
    Pisze program który ma emulować ECU samochodu i dla protokolu ISO 9141 i KWP2000 (wolna inicjalizacja) do rozpoczecia komunikacji z ECU trzeba go wczesniej zainicjować i robi sie to przez wysylanie odpowiedniego bajtu adresu z prędkoscią 5 baudrate. Wyslanie 5 baudrate z pozycji aplikacji do ECU jest proste, albo sterujemy odpowiedno co 200ms linia TXD korzystając z funkcji SET i CLR BREAK, albo usawiamy baudrate na 5 i wysylamy znak. Ja piszac program emuljący ECU i stoje po drugiej stronie i ten bajt wysłany z predkoscia 5bd musze odebrać. I tutaj pojawily się problemy. Przy odbieraniu znaku jest za długi czas o ktorym pisalem wyzej, idealnym rozwiazaniem bylo by sprawdzanie stanu lini RXD ale jak narazie nie wiem jak to zrobić, nie znalazłem takiej funkcji w API.

    Dodano po 5 [minuty]:

    Wracajac do sposobu szybszego odebrania znaku przez ustawienie na wyzszy baudrate po 2000ms, to rozwiązanie to jest prawie dobre, tylo ze pojawia sie problem z tym jak wykryć fakt, że zaczeto odbierac znak, zebym wtedy mógł ustawić odpowiedne opozienie 2000ms i pozniej zmienic predkosc portu a na koncu odczytac znak, nie wiem narazie jak wykryć że coś do mnie wlasnie zaczeło przychodzić

    0
  • #6 23 Sty 2009 00:26
    elektryk
    Poziom 42  

    wilk125 napisał:
    4. Znak po drugiej stronie odbieram funkcją ReadFile, wczesniej czekam na pojawienie się znaku, moge to zrobic na dwa sposoby:
    a) Ustawiam flage zdarzenia EV_RXCHAR przy pomocy funkcji SetCommMask i przy pomocy funkcji WaitCommEvent czekam na odebrany znak;
    b) caly czas sprawdzam funkcją ClearCommError(port,erroe,stat) czy pole cbInQue (wskazuje na ilosc znakow odebranych i gotowych do odczytania) w strukturze stat zmienilo wartość.
    A spróbuj odczytu blokującego przez ReadFile, może problem jest z tymi funkcjami że jakieś wewnętrzne struktury działają z opóźnieniem.

    0
  • #7 23 Sty 2009 08:28
    wilk125
    Poziom 23  

    Blokujacego? To znaczy ze mam wywołać funkcje ReadFile zanim dostane informacje ze jest bajt do odczytania?

    0
  • #8 23 Sty 2009 09:48
    szelus
    Specjalista - Mikrokontrolery

    Tak sobie myślę, że taka niska prędkość została "wymyślona" w specyfikacji, aby spokojnie można było odebrać to programowo. Może tędy droga?
    [EDIT: upss, nie doczytałem, do czego zmierzasz. Może połączyć RX z DCD?]

    Myślę że Twój wniosek o taktowaniu wewnętrznej logiki UARTA z prędkością baud rate generatora może być jak najbardziej uzasadniony...

    0
  • #9 23 Sty 2009 10:00
    wilk125
    Poziom 23  

    szelus napisał:

    Może połączyć RX z DCD?

    Już o tym myslałem, to najprostrze rozwiązanie lub do lini CTS, tylko cały czas kombinuje zeby dalo sie to zrobić prz pomocy samej lini RXD bez używania dodatkowych lini portu

    0
  • #10 23 Sty 2009 10:01
    one_eddie
    Poziom 25  

    Dalej nie jestem przekonany co do tego czy mozna ustawiac taka predkosc. Teoretycznie przy outportb mozna podac dowolne dwie wartosci (2 bajty), ktore wyznacza nam predkosc. Problem jest w tym czy CreateFile wspiera wszystkie predkosci czy tylko te powszechnie uzywane?

    Mimio iz prosiles nie przygotowales zrodel. Jesli nie chcesz ich udostepniac, to udostepnij MWE (minimum working example, MDP - minimaly dzialajacy przyklad) prezentujacy twoj problem. Chetnie zaobserwuje to na swoim sprzecie.

    0
  • #11 23 Sty 2009 11:13
    wilk125
    Poziom 23  

    Skoro mozna ustawic 5bd to chyba wspiera, mozna to takze zauwazyć sledząc co sie dzieje programem portmon. Pisałem tez ze potwierdziem taką prędkość podłączajac oscyloskop do lini TXD/RXD. Załączam program wraz z całym projektem (C++Borland 2007). Program wyglada jak pole po bitwie wiec napszie co do czego jest. Przyciski "Open Port" i "Close Port" wiadomo do czego, "Set Port" - ustawia podstawowe parametry portu ale nie bierze baudrate pod uwagę, BauRate jest pobierane z okienka obok przycisku."Send Byte"- wysyla wpisany w okienko poniezej bajt, nie nalezy zmienic ilosci bajtow do wyslania niech bedzie 1,po wcisnieciu "odczyt 1 bajtu" aplikacja bedzie czekać (bedziw w stanie zawieszenia bo dla prostoty przykladu nie uzywam struktury OVERLAPPED) aż pojawi sie bajt w odbiormiku i jesli go odczyta to wpisze do Memo1. Dodam jescze ze przy ustawionym 5bd to nawet jak klikne "Close Port" to zanim port zostanie zamknięty to trzeba chwile poczekać. Dołączam jescze program "Portmon", który ładnie pokazuje jaki ustawilismy baudrate i wogole wszytko co sie dzieje na porcie. Program Portmon trzeba uruchomic przed nasza aplikacją.

    0
    Załączniki:
  • #12 23 Sty 2009 11:33
    BoskiDialer
    Poziom 34  

    Jest pewien mechanizm przy nadajniku i odbiorniku rs232 - bufor FIFO. Dzięki niemu przerwanie zostaje zgłoszone nie co bajt, ale co pewną porcję bajtów (lub jeśli przychodzi tylko jeden bajt, przerwanie zostanie zgłoszone ze sporym opóźnieniem równym czasowi odbioru bajtów aż do poziomu przy którym bufor by się zapełnił, ażeby wygenerować przerwanie). Jeśli zamiast 2 sekund pojawia się 10, to może być namacalny dowód działania tego mechanizmu. W opcjach com'a powinna być możliwość wyłączenia buforu FIFO lub zmniejszenia jego rozmiaru do jednego bajtu.

    Inna możliwość, to wprowadzić sygnał RXD na któryś pin kontrolny, którego stan można badać (np RI?).

    0
  • #13 23 Sty 2009 14:38
    Jerzy_W
    Poziom 13  

    Ja do transmisji uzywam w Delphi komponent Comport. We właściwościach jest tam coś takiego >Timeouts<, ale nigdy tego nie uzywałem. Czy w strukturze DCB jest coś takiego?. Może tam trzeba coś wyzerować?

    0
  • #14 23 Sty 2009 15:43
    wilk125
    Poziom 23  

    BoskiDialer napisał:
    . W opcjach com'a powinna być możliwość wyłączenia buforu FIFO lub zmniejszenia jego rozmiaru do jednego bajtu.


    jest funkcja BOOL SetupComm(HANDLE hCommDev,DWORD cbInQueue, DWORD cbOutQueue);

    Ustala sie nią wielkosc bufora wy i we, jednak u mnie cały czas bufor we mam 4096 i uzycie powuższej funkcji nie zmienia tego faktu.

    Znalazlem w strukturze COMPROP pole dwMaxRxQueue (max rozmiar bufora wejsciowego) tylko nie wiem jak go ustawić, jest funkcja GetCommProperties(hPort,&comprop) która czyta ustawienia portu jednak nie ma analogicznej funkcji Set i nie wiem jak to ustawić.

    0
  • Pomocny post
    #15 23 Sty 2009 15:54
    BoskiDialer
    Poziom 34  

    Nie chodzi mi o bufor oferowany przez system. Sam układ ma bufor, chyba do 16 bajtów max. W managerze urządzeń znajdź port, w ustawieniach zaawansowanych można zmniejszyć lub wyłączyć FIFO.

    0
  • #16 26 Sty 2009 14:23
    wilk125
    Poziom 23  

    BoskiDialer napisał:
    Nie chodzi mi o bufor oferowany przez system. Sam układ ma bufor, chyba do 16 bajtów max. W managerze urządzeń znajdź port, w ustawieniach zaawansowanych można zmniejszyć lub wyłączyć FIFO.


    Zmniejszenie buforu do 1 lub jego wyłaczenie, rozwiazuje problem z opóznieniem, tylko że zmiany w ustawieniach portu zachodza dopiero po restarcie komputera, uważam temat za zamniety

    0