[PASCAL] Jak ustawić właściwe opóźnienie???

0

Witam

Piszę program w trybie tekstowym do sterowania silników krokowych przez LPT. Wystąpił jednak następujący problem:

Program wykożystuje licznik wykonań pętli z opóźnieniem DELAY(1) do sterowania odstępów między kolejnymi impulsami dla silników. W programie jest użyte czekanie na powrót pionowy monitora, aby usunąć mruganie ekranu. Problem w tym, że czekanie na powrót pionowy bardzo spowalnia działanie programu.

Poniżej przykładowy program pokazujący o co mi chodzi. Gdy uruchomi się go bez czekania na powrót pionowy to kolor napisu zmienia się co sekundę. Gdy czekanie na powrót pionowy jest włączone to (u mnie) kolor napisu zmienia się co około 15 sekund. Jak ustawić właściwe opóźnienie nie rezygnując z likwidacji mrugania??? Przecież nie mogę dla DELAY użyć parametru ułamkowego, aby odpowiednio zmniejszyć opóźnienie (do sterowania silników używam czas od 10 ms do 1000 ms).

Poniższy program należy uruchomić BEZ lub Z komendą "czekaj_na_odswiezanie;", aby zobaczyć na czym polega problem.

program przyklad;

uses crt;

var
  kolor : byte;
  czas, czas_temp : word;

procedure czekaj_na_odswiezanie;

begin
  asm
    mov dx, 3dah
   @trwa:
    in al, dx
    test al, 00001000b
    jnz @trwa
   @nie_ma:
    in al, dx
    test al, 00001000b
    jz @nie_ma
  end;
end;

begin
  kolor:=1;
  czas:=1000;
  clrscr;
  while(1=1) do
    begin
      czekaj_na_odswiezanie;                { eliminacja mrugania ekranu }

      clrscr;           { uzyte dla pokazania mrugania (lub braku) ekranu }
      textcolor(kolor);
      gotoxy(1,1);
      write('Kolor napisu jest zmieniany co 1 sekunde...');

      if (czas_temp>czas) then
        begin
          czas_temp:=1;
          inc (kolor);
          if (kolor>15) then kolor:=1;
        end;
      inc (czas_temp);
      delay(1);

      if keypressed then halt;
    end;
end.
0

Najlepiej zrobić bufor ekranu, może to pomoże :]

0

Wydaje mi się, że bufor nie pomoże. Żeby skopiować bufor do pamięci video to muszę wykryć kiedy zaczyna się powrót pionowy (gdy już trwa powrót to procedura czeka na początek nowego powrotu). Właśnie to wykrywanie powrotu stwarza niechciane opóźnienia.

Tiger

0

odświeżanie wykonuje się średnio około 70 razy na sekundę, czyli prędkosć pętli spada do 70 razy na sekundę + delay(1) a ty dodatkowo masz zmienną czas:=1000 zmniejsz zmienną czas i dodaj jeszcze drugi bufor :] wtedy powinno być ok.

/// dodane:
Btw.
nawet by sie zgadzało... w końcu mówiłeś że prędkość gdy dodajesz tą procedurę spada do 1 zmiany na 15 sekund....
w końcu 1000 / (~70) = ~ 15 :P

więc :
czas / (~70) = 1
czas = ~70
ustaw czas na 70 i powinno być raz na 1 sekundę. Jak coś bedzie nie tak jeszcze to drugi bufor dodaj i chyba tyle :P

0

A co zrobić w przypadku programu do obsługi silników krokowych? Tam aby uzyskać czas między impulsami = 10 ms to dla DELAY musiałbym wprowadzić wartość równą ~0,14 (10 / 70 ~0,14). Niestety DELAY może przyjmować tylko wartość od 0 i tylko liczby całkowite. Wcześniej próbowałem ustawić właściwy czas dodając licznik w procedurze czekającej na odświeżanie. Następnie przypisując DELAY(1 div opoznienie_odswierzania). Myślałem nad napisaniem nowej procedury DELAY, która byłaby typu REAL i wtedy problem rozwiązany. Mogłbym ustawić wartość ułamkową, która będzie dostosowywała program do częstotliwości odświeżania ekranu na dowolnym komputerze, a nie tylko na moim. Wydaje mi się, że to najlepsze rozwiązanie, ale muszę poszukać jak napisać procedurę DELAY. Ona chyba bazuje na prędkości procesora, aby obliczyć właściwy czas.

Wielkie dzięki za pomoc. Jeszcze pokombinuję i zobaczę co z tego wyjdzie.

Tiger

0

W zasadzie ustawianie DELAY poniżej 1 nie ma sensu. Lepiej sprawdzić częstotliwość odświeżania i do niej dostosować pracę programu.

Tiger

0

Wygląda to tak:
Odświeżanie: 1/70[s] co daje 14[ms]
Delay: 1[ms]
W konsekwencji: (14[ms] + 1[ms]) * 1000 = 15[s].

Moim zdaniem nie powinieneś wykorzystywać stałego opóźnienie typu DELAY tylko powinieneś sprawdzać ile czasu mineło od ostatniego przejścia przez pętle, jeśli czas odpowiada oczekiwanemu opóźnienie to kontynuujesz pętle, a jesli nie to czekasz i nadal sprawdzasz czy nie miną odpowiedni czas.

P.S. Ta metoda jest wykorzystywana np. w grach aby uzyskać odpowiednie odświeżanie ekranu.

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