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.

Program do odczytu stanow lini portu LPT

wilkolaski 20 Mar 2007 14:11 2880 5
  • #1 20 Mar 2007 14:11
    wilkolaski
    Poziom 18  

    Witam. Chce poprosic o pomoc w napisniu programu w delphi do odczytu portu LPT. Przeznaczenim programu ma byc odczyt stanow logicznych podawanych na linie portu LPT. Zakladam nastepujace dzialanie programu. Odczytuje 4 linie portu na ktore podawane sa sygnaly: zegarowy, wysylanie danych, odbieranie danych, zajetosci. Odczyt ten nastepuje przez probkowanie wejsc portu LPT i na podstawie probek odtwarzanie zmieniajacych sie stanow na tych wejsciach. Przez to moge odtworzyc sygnal zegarowy, osmiobitowe dane wysylane i odbierane oraz sygnal zajetosci. Super jakby mozna bylo samemu okreslac czestotliwosc probkowania.Nastepnie odczytane osmiobitowe dane i sygnal zajetosci bylyby przedstawiane w tabeli w trzech kolumnach: wejscie, wyjscie, zajetosc.To tyle :) Kiepsko orientuje sie w programowaniu Delphi dlatego prosze o pomoc w napisaniu programu. Dodam ze umiem programowac w turbo paskalu i asemblerze.
    Pozdrawiam i juz teraz bardzo dziekuje za kazde info.

    0 5
  • #3 20 Mar 2007 16:45
    Fyszo
    Spec od GSM

    Cały problem z rejestratorami to synchronizacja czasowa. Program nie zawsze równomiernie w czasie odczytuje port. Nawet jak masz wyzwalanie zewnętrznym zegarem (i do tego korzystasz z przerwan portu) to czas reakcji oprogramowania jest za kazdym razem różny. Czyli reasumując łapie próbki w 0s potem po 10ms dalej po 12ms, po 8ms, po 9ms, po 11ms i tak w ten sposób.

    0
  • #4 20 Mar 2007 22:41
    wilkolaski
    Poziom 18  

    Fyszo wiec jakie jest rozwiazanie oprosz programowego odczytu bo przyznam ze glownie zalezy mi na przesledzeniu sygnalow: SCK, MISO, MOSI, SS czyli sygnalow transmisji SPI. Wiem ze sa sprzetowe analizatory logiczne ale sa albo koszmarnie drogie albo mocno skomplikowane do zbudowania samemu.

    0
  • #5 21 Mar 2007 01:39
    Akane
    Poziom 27  

    Częstotliwość próbkowania może wynosić 2 mikro sekundy w zwyczajnej aplikacji. Wprawdzie przedstawiony tu sposób pochłania połowę czasu procesora, ale pozwala innym procesom na działanie.

    Funkcją QueryPerformanceFrequency pobieramy częstotliwość któregoś synchronizatora na płycie głównej. Teraz w krótkiej pętli, za pomocą funkcji QueryPerformanceCounter pobieramy ilość taktów synchronizatora które upłynęły od czasu ostatniego pomiaru i wpisujemy wynik do tabicy, a następnie przerywamy wykonywanie sie naszego wątku funkcją SwitchToThread.

    Code:
    {
    
       int64 freq, start, stop;
       QueryPerformanceFrequency(&freq);

       #define NUM_SAMPLES 10
       double pomiar[NUM_SAMPLES];
       double srednia;

       for (x=0; x<NUM_SAMPLES; x++)
       {
          SwitchToThread();
          QueryPerformanceCounter(&stop);
          pomiar[x] = GetDiffTime(freq, start, stop); // (stop - start)/freq;
          start = stop;
       }
       srednia = 0.0;
       for (x=1; x<NUM_SAMPLES; x++) // ignoruj pierwszy pomiar
       {
          printf("czas: %.3f ms\n", pomiar[x] * 1000.0);
          srednia += pomiar[x];
       }
       srednia /= (NUM_SAMPLES-1.0);
       printf("srednia: %.3f ms\n", srednia * 1000.0);

    W systemie windows xp sp2, w którym uruchomionych jest 23 procesów (230 wątków) - nasza funkcja wykonuje pomiar 500000 razy na sekundę, czyli co 2us.
    Monitorując przebieg o częstotliwości 20kHz mamy 25 pomiarów na okres sygnału.
    Należy zauważyć iż większość wątków jest uśpiona czekając na jakieś zdarzenie, więc im więcej jest uśpionych, lub ogólnie jest mniej wątków, tym częściej będziemy robić pomiar.

    Teraz propozycja dla wilkolaski:
    Dobrze by było uruchomić szpiega w osobnym wątku żeby nie blokował okna aplikacji.
    Na początku jego działania odczytujesz częstotliwość synchronizatora i czekasz na pierwszą aktywność portu.
    Code:
    licznik = 0;
    
    port = in(port);
    QueryPerformanceFrequency(&freq); // częstotliwość synchronizatora

    while ((port == in(port)) && (g_przerwij == false))
    {
       SwitchToThread();
    }
    QueryPerformanceCounter(&start);
    gdzie g_przerwij to globalna zmienna boolean działająca jako "zatrzymaj pomiar"

    Teraz wchodzisz do właściwej pętli w której wpisujesz do tablicy kolejne stany portu i ich czas w dowolnej dokładności
    Code:
    while (g_przerwij == false)
    
    {
       SwitchToThread();
       QueryPerformanceCounter(&stop);
       pomiary[licznik].port = in(port);
       pomiary[licznik].czas = (stop - start)/freq; // czas i freq jako float lub double
       licznik++; // sprawdź maximum
    }

    0
  • #6 21 Mar 2007 08:08
    Fyszo
    Spec od GSM

    Jesli transmisja bedzie wolna o odczyt portu dosyc szybki (np. wspomniane 2us) to działać bedzie i błąd będzie nieznaczny. Ale zbocza sygnałów bedzie cięzko wykryć w ten sposób. Ja bym dał jednak troche hardware'u przy porcie, jakis zatrzask (np. 74573 itp.) synchronizowany sygnałem zewnetrznym (np. clk) i wtedy kazde zbocze clk spowoduje 'zapamiętanie' stanów i mozesz je odczytywac z portu w 'kazdej' rozsądnej chwili.

    0
  Szukaj w 5mln produktów