![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Таймеры+LPT [D3, D4, D5, D6, D7, Win95/98, Win2k]
Dark Demon © (2003-05-28 01:46:00)Всем привет!
Люди - может кто подскажет ответ на следующий вопрос:
Мне надо реализовать вывод данных в LPT порт с определенной частотой (прога под винду 9x и выше). Беда в следующем - частота вывода данных в среднем должна составлять от 12 до 50 кГц. Если верить виндовому хелпу на стандартном таймере больше 1 кГц не получишь. Каким образом можно решить эту проблему?
Заранее спасибо за ответ.
Zakharov Anton (2003-05-28 10:27:00) [1]Используй приведенный ниже код пп. delay_mks(Value).
У меня работает: задержки до 5 mks.
unit Timer_and_Delay;
interface
uses windows;
const
SleepTime: dword = 200; {используется для определения частоты процессора}
Var
CPUFrequency: dword = 0; {частота процессора MHz}
LCPUFrequencyMS: single; {0.001/CPUFrequency}
LCPUFrequencyMKS: single; {1/CPUFrequency}
procedure delay_mks(Value: Integer); {формирование задержки в mks}
function cpuGetSpeed: word;
function cpuGetTick: Int64;
Function cpuGetms(Tick: Int64) :dword;
Function cpuGetmks(Tick: Int64) :dword;
function cpucalcms(const Tick1,Tick2:Int64 ):Int64;
Function cpucalcmks(const Tick1,Tick2:Int64 ):Int64;
implementation
var
inited:boolean=false;
procedure delay_mks(Value: Integer);
var
tick1, tick2: Int64;
begin
tick1 := cpugettick;
tick2 := cpugettick;
while cpucalcmks(tick1, tick2)+5 < Value do
tick2 := cpugettick;
end;
function cpugettick:Int64;
asm
dw 310Fh // rdtsc
end;
Function cpugetms(Tick: Int64): dword;
begin
asm
dw 310Fh // rdtsc
sub eax, dword [Tick]
sbb edx, dword [Tick+4]
mov dword[Tick], eax
mov dword[Tick+4], edx
end;
if not inited then cpugetspeed;
Result := round(Tick*LCPUFrequencyMS);
end;
Function cpugetmks(Tick:Int64): dword;
begin
asm
dw 310Fh // rdtsc
sub eax, dword [Tick]
sbb edx, dword [Tick+4]
mov dword[Tick], eax
mov dword[Tick+4], edx
end;
if not inited then cpugetspeed;
result:=round(Tick*LCPUFrequencyMKS);
end;
function cpucalcmks(const Tick1, Tick2: Int64 ): Int64;
begin
if not inited then cpugetspeed;
Result := round(abs(Tick2-Tick1)*LCPUFrequencyMKS);
end;
function cpucalcms(const Tick1, Tick2: Int64 ): Int64;
begin
if not inited then cpugetspeed;
result:=round(abs(Tick2-Tick1)*LCPUFrequencyMS);
end;
function CPUGetSpeed: word;
var
cpufreq: dword;
len:integer;
rh:HKEY;
i1,i2,t:Int64;
pr:dword;
begin
Result := 0;
if CPUFrequency <> 0 then
begin
Result := CPUFrequency;
exit;
end;
if RegOpenKeyEx(HKEY_LOCAL_MACHINE, "HARDWARE\DESCRIPTION\System\CentralProcessor\0",
0, KEY_READ, rh) = ERROR_SUCCESS then
begin
if RegQueryValueEx(rh,"~MHz", nil,@pr, @cpufreq, @len) = ERROR_SUCCESS then
begin
Result := cpufreq;
CPUFrequency := cpufreq;
end
else
begin
pr := GetThreadPriority(GetCurrentThread );
SetThreadPriority(GetCurrentThread,THREAD_PRIORITY_TIME_CRITICAL);
QueryPerformanceCounter( i1 );
t := cpugettick;
Sleep(SleepTime);
asm
dw 310Fh // rdtsc
sub eax, dword[t]
sbb edx, dword[t+4]
mov dword[t], eax
mov dword[t+4], edx
end;
QueryPerformanceCounter( i2 );
i2 := i2-i1;
QueryPerformanceFrequency( i1 );
i2 := i2*1000000 div i1;
Result := round(t/(i2));
CPUFrequency := Result;
SetThreadPriority(GetCurrentThread,pr);
end;
RegCloseKey( rh );
end;
LCPUFrequencyMS := 0.001/CPUFrequency;
LCPUFrequencyMKS := 1/CPUFrequency;
inited := true;
end;
end.
pasha676 (2003-05-28 09:25:00) [2]
> Либо DOS, либо драйвер.
Либо ассемблерная вставка на системном таймере время считать.
DeMoN_Astra (2003-05-28 09:10:00) [3]угу. а еще - вообще отказываться от таймера - вывод только по внешним синхроимпульсам...
Нуу (2003-05-28 04:25:00) [4]Либо DOS, либо драйвер.