Aktyw Forum
Zarejestruj się na forum.ep.com.pl i zgłoś swój akces do Aktywu Forum. Jeśli jesteś już zarejestrowany wystarczy, że się zalogujesz.
Sprawdź punkty Zarejestruj sięLPT w Delphi
Moderatorzy:Jacek Bogusz, Moderatorzy
Witam. Mam problem. Chcę zrobić program w Delphi do sterowania pewnego urządzenia przez port LPT (używając 'inpout.dll' aby chodził pod różnymi Windowsami). Na jednym z pinów LPT chcę uzyskać przebieg taktujący o częstotliwości z zakresu 100-1000Hz (ustawianej suwaczkiem 'TrackBar' np. co 50 Hz). Program ma chodzić jednakowo na różnych komputerach o różnych 'zegarach'. Użycie komponentu TTime dla uzyskania potrzebnych zależnośći czasowych odpada (za długie czasy). Pamiętam że w asemblerze stosowało się trik polegający na przestawieniu dzielnika w zegarze systemowym na inną częstotliwość (nie naruszając przy tym wskazań zegara 'czasowego') i użwaniu tego do taktwania swojej aplikacji. Jak to 'pożenić' z Delphi? Robię w Delphi proste aplikacje, ale ten problem przekracza moje umiejętności. A może ktoś ma jakąś elegancką procedurkę na tę okazję?
-
- -
- Posty:175
- Rejestracja:10 paź 2003, o 20:44
- Lokalizacja:Białystok
- Kontaktowanie:
Re: LPT w Delphi
Weź MMTimer. Praktycznie na każdej wspólczesnej maszynie uzyskasz rozdzielczośćNa jednym z pinów LPT chcę uzyskać przebieg taktujący o częstotliwości z zakresu 100-1000Hz (ustawianej suwaczkiem 'TrackBar' np. co 50 Hz). Program ma chodzić jednakowo na różnych komputerach o różnych 'zegarach'. Użycie komponentu TTime dla uzyskania potrzebnych zależnośći czasowych odpada (za długie czasy).
1 ms a więc 1000Hz jeszcze się da .
Pozdrowienia Jurek S.
-
- -
- Posty:651
- Rejestracja:13 sty 2005, o 18:38
- Lokalizacja:Krasnystaw
- Kontaktowanie:
Chyba mozna sprobowac stworzyc oddzielny watek (i nadac mu wysoki priorytet) i do odmierzania opoznien w tym watku uzyc QueryPerformanceCounter. Powinno dac spora rozdzielczosc czasowa, i ladnie dostosowa sie do szybkosci procesora (QueryPerformanceFrequency).
Jednak generalnie uzywanie portow PC do programowego generowania sygnalow w czasie rzeczywistym to niezbyt dobry pomysl. Jesli nie stanowi to przeszkody, lepiej podpiac malutki uC, ktory sie tym zajmie i za pomocą portow PC mowic mu, co ma wygenerowac .
BTW - czy rozdzielczosc 1ms to nie jest troche za malo jak na wygenerowanie 1000Hz? Jesli wypelnienie ma byc 50% (przebieg taktujacy) to trzebaby "machać" co 0.5ms
[ Dodano: 27-02-2006, 23:08 ]
O! Widze ze MMTimer "w bebechach" uzywa wlasnie QueryPerformanceCounter .
Jednak generalnie uzywanie portow PC do programowego generowania sygnalow w czasie rzeczywistym to niezbyt dobry pomysl. Jesli nie stanowi to przeszkody, lepiej podpiac malutki uC, ktory sie tym zajmie i za pomocą portow PC mowic mu, co ma wygenerowac .
BTW - czy rozdzielczosc 1ms to nie jest troche za malo jak na wygenerowanie 1000Hz? Jesli wypelnienie ma byc 50% (przebieg taktujacy) to trzebaby "machać" co 0.5ms
[ Dodano: 27-02-2006, 23:08 ]
O! Widze ze MMTimer "w bebechach" uzywa wlasnie QueryPerformanceCounter .
-
- -
- Posty:175
- Rejestracja:10 paź 2003, o 20:44
- Lokalizacja:Białystok
- Kontaktowanie:
Fakt Ale tak czy siak masz rację, że do takich sterowań raczej nie tędy droga.czy rozdzielczosc 1ms to nie jest troche za malo jak na wygenerowanie 1000Hz?
Cały czas reklamuję obiecujące :
http://www-user.tu-chemnitz.de/~heha/ba ... ex.html.en
Pozdrowienia Jurek S.
[ Dodano: 28-02-2006, 17:47 ]
Dołożę stare testowe przykłady ( jeszcze z D3 i win98 ) :Chyba mozna sprobowac stworzyc oddzielny watek (i nadac mu wysoki priorytet) i do odmierzania opoznien w tym watku uzyc QueryPerformanceCounter. Powinno dac spora rozdzielczosc czasowa, i ladnie dostosowa sie do szybkosci procesora (QueryPerformanceFrequency).
- Query... ( wprawdzie bez wątku )
Kod: Zaznacz cały
procedure TMainForm.Delay(ATime:Longint);
var
Freq:TLargeInteger;
StartCounter,EndCounter,EndValue:TLargeInteger;
begin
if not QueryPerformanceFrequency(Freq) then begin
MessageBox(Handle,'Twój sprzęt nie wspiera'+#10#13+
'precyzyjnych liczników','STOP !',mb_Ok);Exit end;
QueryPerformanceCounter(StartCounter);
EndValue.QuadPart:=
Comp(StartCounter)+Trunc(ATime*Comp(Freq)/1000000);
repeat
QueryPerformanceCounter(EndCounter);
until (EndCounter.QuadPart>=EndValue.QuadPart);
end;
procedure TMainForm.RunWave;
var
B:Byte;
begin
while Running do begin
if DataStat then B:=1 else B:=0;
DataStat:=not DataStat;
asm
MOV DX,$278
MOV AL,B
OUT DX,AL
end;
Delay(380);
// NT,2000,XP będą tu wymagać sterownika albo jakiegoś UserPorta
Application.ProcessMessages;
end;
end;
procedure TMainForm.BT_StopClick(Sender: TObject);
begin
Running:=False;
end;
procedure TMainForm.BT_StartClick(Sender: TObject);
begin
Running:=True;
RunWave;
end;
Kod: Zaznacz cały
procedure TimeProc(Id,Msg:UINT;dwUser,dw1,dw2:DWORD);StdCall;
begin
Form1.Licznik;
end;
procedure TForm1.Licznik;
begin
Inc(Counter);
// ST_Counter.Caption:=IntToStr(Counter);
end;
procedure TForm1.BT_GetInfoClick(Sender: TObject);
var
Info:TTimeCaps;
begin
case timeGetDevCaps(@Info,SizeOf(TTimeCaps)) of
TIMERR_STRUCT : begin MessageBeep(0);Exit;end;
TIMERR_NOERROR : begin
ST_MinRes.Caption:=IntToStr(Info.wPeriodMin);
ST_MaxRes.Caption:=IntToStr(Info.wPeriodMax);
end;
end; //case
end;
procedure TForm1.TB_ResChange(Sender: TObject);
begin
ST_Res.Caption:=IntToStr(TB_Res.Position);
end;
procedure TForm1.BT_StartClick(Sender: TObject);
begin
if Running then begin MessageBeep(0);Exit;end;
if timeBeginPeriod(1)=TIMERR_NOERROR then begin
TB_Res.Enabled:=False;
Counter:=0;
ST_Counter.Caption:='0';
TimeEvent:=timeSetEvent(TB_Res.Position,1,@TimeProc,0,TIME_PERIODIC);
Running:=True;
end;
end;
procedure TForm1.BT_StopClick(Sender: TObject);
begin
if not Running then begin MessageBeep(0);Exit;end;
timeKillEvent(TimeEvent);
timeEndPeriod(1);
TB_Res.Enabled:=True;
Running:=False;
ST_Counter.Caption:=IntToStr(Counter);
end;
Pozdrowienia Jurek S.
Witam Kolegów, dziękuję za cenne uwagi.
Chciałem uprościć część hardwarową ale widzę że przez to komplikuję software. Chyba zrobię "po bożemu": w aplikacji dam mały procek Atmela i z PC-ta będę z nim gadał po RS-ie (a może i po USB). Procek będzie odpowiednio taktował silnik krokowy i posteruje kilkoma przekaźnikami. Tak będzie najprościej. Nie ma co robić udziwnień, zwłaszcza że aplikacja jest dość banalna.
Niemniej jednak dziękuję za listingi; mogą się jeszcze przydać.
Pozdrowionka
Franek
Chciałem uprościć część hardwarową ale widzę że przez to komplikuję software. Chyba zrobię "po bożemu": w aplikacji dam mały procek Atmela i z PC-ta będę z nim gadał po RS-ie (a może i po USB). Procek będzie odpowiednio taktował silnik krokowy i posteruje kilkoma przekaźnikami. Tak będzie najprościej. Nie ma co robić udziwnień, zwłaszcza że aplikacja jest dość banalna.
Niemniej jednak dziękuję za listingi; mogą się jeszcze przydać.
Pozdrowionka
Franek
Kto jest online
Użytkownicy przeglądający to forum: Obecnie na forum nie ma żadnego zarejestrowanego użytkownika i 107 gości