Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Нештатный режим работы com порта
Форум разработчиков электроники ELECTRONIX.ru > Интерфейсы > Форумы по интерфейсам > RS232/LPT/USB/PCMCIA/FireWire
techno
Народ, думаю, что я попал куда надо! Такая проблемма у меня. Мне нужно организовать частотомер для прямоугольных импульсов через ком-порт. Частоты небольшие - от 1 кГц до 20 кГц. Придумал такое решение. Подаю импульсы источника, как будто бы сигнал готовности передающего устройства на контакт 8, определяю время прохождения заданного количества импульсов и простыми вычислениями определяю частоту. Такое решение работает до тех пор, пока частота остается примерно на одном уровне. Если резко изменить частоту, то измеренное значение сильно отличается от истинного. После небольших экспериментов установил, что в этом отношении у ком-порта есть инерционность и перед следующим, после резкой смены частоты, измерением необходимо выждать какое-то время. В связи с этим появилось два вопроса: 1) Как долго протянет ком-порт в таком режиме? и 2) Какой есть более надежный способ организации измерения частоты через ком-порт? Есть конечно идея, подавать импульсы на канал данных, но тогда, необходимо произвести предварительную установку скорости обмена данными, что опять же влечет за собой предварительное измерение частоты из-за чего такой способ не представляется эффективным.
MALLOY2
Самый надежный и правельный, это внешний контроллер подключенный к СОМ порту он меряет а данные передает на компорт. В любом другом случае точно не померяеш, не умеет PC точно интервалы выдерживать sad.gif, развечто на уровне какихто хотрых драйверов, если без внешних девайсов и частота до 20 Кгц то можно заюзать саунд бластер, но тут пахнет ЦОС. Мой совет поставить какойнибуть процик типа AT90S2313, и частоту можно будет мерять до 1 мега точно, а то и более, но прогаа приэтом усложняется.
vvs157
Если программа под Виндами, то на 20 кГц будет пропуск импульсов, если не задействовано прерывание от СОМ-порта по изменению состояния CTS.
Инерционность не у СОМ-порта, а у алгоритма. Правильную частоту можно получить только в следующим цикле измерений после изменения частоты.
Полностью согласен с предыдущим оратором, что куда правильнее взять какой-нибудь Атмеловский Tiny и на нем соорудить частотомер, который будет выдавать результат по RS-232 с питанием от того же порта.
one_man_show
Присоединяясь к двум предыдущим коллегам, но пытаясь продолжить тему автора топика, добавлю: существует еще один способ измерений через порты РС.
LPT + программа дают и частотомер и 5-ти канальный логический анализатор (Если порты двунаправленные, то каналов естесственно больше). Оптимальные параметры можно получить при условии, что программа на ассемблере и РС без Win:-)
techno
Цитата(vvs157 @ Jul 27 2005, 16:42)
Если программа под Виндами, то на 20 кГц будет пропуск импульсов, если не задействовано прерывание от СОМ-порта по изменению состояния CTS.
Инерционность не у СОМ-порта, а у алгоритма. Правильную частоту можно получить только в следующим цикле измерений после изменения частоты.
Полностью согласен с предыдущим оратором, что куда правильнее взять какой-нибудь Атмеловский Tiny и на нем соорудить частотомер, который будет выдавать результат по RS-232 с питанием от того же порта.
*


Советы полезные, благодарен! a14.gif Но вот никак не сооброжу, каким образом может алгоритм быть инерционным, если я вставляю всего лишь дополнительный цикл ожидания за пределами каких либо измерений, и у меня определяется частота, близкая к той, что должна быть? Хотя так же мне не понятно, что может тормозить в самом ком-порте unsure.gif Возможно это связано с неверным опросом счетчика таймера? Программа работает под чистым DOS. Все измерения написаны на ассемблере.
vvs157
Цитата(techno @ Jul 27 2005, 18:44)
Хотя так же мне не понятно, что может тормозить в самом ком-порте unsure.gif  Возможно это связано с неверным опросом счетчика таймера? Программа работает под чистым DOS. Все измерения написаны на ассемблере.
*


В СОМ порте при опросе CTS в принципе ничего тормозить не может. А каким образом Вы снимаете показания таймера?
techno
Цитата(vvs157 @ Jul 28 2005, 13:09)
Цитата(techno @ Jul 27 2005, 18:44)
Хотя так же мне не понятно, что может тормозить в самом ком-порте unsure.gif  Возможно это связано с неверным опросом счетчика таймера? Программа работает под чистым DOS. Все измерения написаны на ассемблере.
*


В СОМ порте при опросе CTS в принципе ничего тормозить не может. А каким образом Вы снимаете показания таймера?
*



В самом начале не полную информацию предоставил. Используется 8 контакт разъема DB-25, соответственно обрабатывается сигнал DCD (обнаружение несущей).

Понимаю, что в чужой алгоритм вникать дело не благодарное. Также должен признать, что алгоритм - не мой, организован на основе материалов, которые я нашел в интернете.

Особо не надеясь, что кто-то будет искать изъян в алгоритме, но все же приведу текст кода. Уверен, что он далек от совершенства, поэтому прошу не судить строго: ведь с чего надо начинать smile.gif excl.gif

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;
}
vvs157
По-моему правильнее использовать не CNT0 таймера, а CNT2 - он свободен. Иначе при инициализации этого таймера своими зничениями Вы сбиваете ДОСовские часы
По-моему маска 8Н соответствует изменению состояния DCD.
А какие характерные времена запаздывания отсчетов?
techno
Цитата(vvs157 @ Aug 1 2005, 00:53)
По-моему правильнее использовать не CNT0 таймера, а CNT2 - он свободен. Иначе при инициализации этого таймера своими зничениями Вы сбиваете ДОСовские часы
По-моему маска 8Н соответствует изменению состояния DCD.
А какие характерные времена запаздывания отсчетов?
*


Характерное время запаздывания отсчета - порядка 100 мс.
vvs157
Цитата(techno @ Aug 1 2005, 09:44)
Характерное время запаздывания отсчета - порядка 100 мс.
*


А время счета при этом тогда какое?
Если изменение частоты произодет во время счета, то результат будет неверным
techno
Благодарен всем, кто отклинулся на мою тему. Видимо в дебрях своей программы до конца разбираться придется самому. Огромное СПАСИБО vvs157. Ему на последний вопрос отвечу так. Каждое измерение запускается только тогда, когда подразумевается, что резких скачков не должно быть. Но вот этот алгоритм почему-то не работает. Возможно, что ошибка как раз появляется в результате того, что опрашиваемое устройство переходит в стационарный режим после смены режима за более длительный период времени, чем предполагается по задумкам. Всей особенности технической стороны рассказать не могу (не имею права). Но мысль дельная, поисследую в этом направлении.

Из всего написанного понял, что подход к измерению частоты, описанный мной в самом начале является ламерским и годится лишь для школьного кружка "Умелые руки" <_< . Если же к решению вопроса подходить профессионально, то необходимо воспользоваться средствами, разработанными умными головами, для решения задач, подобных моей (смотри ответ MALLOY2).

Вообще говоря, интерфейс RS232 (UART) - один из двух, посредством которых мне необходимо получать данные от устройства. Второй естественно же USB.
Предложенный MALLOY2-ем AT90S2313, как я понял позволяяет реализовать только UART интерфейс. Покопался я на атмелевском сайте (www.atmel.com) нашел у них новинку (???) AT76С713. Этот контроллер поддерживает оба интерфейса: и UART и USB. Хотелось бы узнать мнение специалистов об этом контроллере. Возможно, кто-то подскажет более примелемый вариант для реализации двух интерфейсов.
ValeraVi
Цитата(techno @ Aug 2 2005, 09:18)
...Возможно, кто-то подскажет более примелемый вариант для реализации двух интерфейсов.
*

Если предполагается USB как опциональный интерфейс в дополнение к комовскому (т.е. одни и те-же данные гоняются по COM или USВ в зависимости от свободного порта на компе), то можете обратить внимание на преобразователь интерфейса USB в COM FT232 или CP2101. Т.е. к компу ваш девайс будет подсоединятся к UART вашего контроллера в девайсе либо напрямюу (COM -> UART) либо через ft232 (USB -> FT232 -> UART). Драйвера под винду для ft232 доступны готовые и бесплатно. Подобное решение используется в программаторах и еще вот там обсуждается smile.gif
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.