Цитата(vvs157 @ Jul 28 2005, 13:09)
Цитата(techno @ Jul 27 2005, 18:44)
Хотя так же мне не понятно, что может тормозить в самом ком-порте

Возможно это связано с неверным опросом счетчика таймера? Программа работает под чистым DOS. Все измерения написаны на ассемблере.
В СОМ порте при опросе CTS в принципе ничего тормозить не может. А каким образом Вы снимаете показания таймера?
В самом начале не полную информацию предоставил. Используется 8 контакт разъема DB-25, соответственно обрабатывается сигнал DCD (обнаружение несущей).
Понимаю, что в чужой алгоритм вникать дело не благодарное. Также должен признать, что алгоритм - не мой, организован на основе материалов, которые я нашел в интернете.
Особо не надеясь, что кто-то будет искать изъян в алгоритме, но все же приведу текст кода. Уверен, что он далек от совершенства, поэтому прошу не судить строго: ведь с чего надо начинать
double freq_measure(int imp)
{
WORD dos_start=0, dos_stop=0;
DWORD dos_count=0;
WORD timer_start=0, timer_stop=0;
WORD timer_ticks;
double time=1.0, freq=0.0;
imp*=2;
s: asm{
mov dx,_port_address //задается адрес опрашиваемого порта
in al,dx //запускается цикл ожидания, пока состояние порта не
and al,_test_mask //будет соответствовать желаемому
cmp al,_test_mask //
jne s //_test_mask=0x8 - состояние порта, когда сигнал DCD имеет высокий уровень.
mov al,34h //назначение таймера
out 43h,al
mov ax,0 //инициализация таймера
out 40h,al //на максимальное разрешение
mov al,ah
out 40h,al
mov dx, ds //запоминание времени DOS
mov bx, 0x40
mov ds, bx
mov bx, 0x6C
mov ax, [bx]
mov dos_start, ax
mov ds, dx
mov cx,imp //задается число импульсов
mov dx,_port_address
jmp r
}
r: asm{ in al,dx //читается содержимое порта
and al,_test_mask //сравнивается с маской состояния
cmp al,_test_mask //проверка состояния порта
jne r //если состояние порта не изменилось нужным образом, то продолжается опрос
dec cx //иначе уменьшить переменную цикла на 1
cmp cx,0 //если зарегистрировано меньше заданного количества импульсов
jne r //то продолжается опрос порта
//снятие показания таймера
mov al,0
out 43h,al
mov dx,40h
in al,dx
mov ah,al
in al,dx
mov ch,ah
mov ah,al
mov al,ch
mov timer_stop,ax //в timer_stop содержится показание счетчика таймера в момент остановки
mov dx, ds
mov bx, 0x40
mov ds, bx
mov bx, 0x6C
mov ax, [bx]
mov dos_stop, ax //в dos_stop содержится показание dos времени в момент остановки
mov ds, dx
}
dos_count = dos_stop - dos_start; //изменение досовского времени
if(timer_stop==0) timer_stop=65535;
timer_ticks=timer_start-timer_stop; //изменение счетчика таймера
time=(double)((dos_count<<16)+timer_ticks)/1193180.0; //пересчет показаний счетчиков в секунды
if(time==0) time=-1; //обработка нулевого времени для исключения деления на 0
freq=0.5*imp/time;
return freq;
}