Доброго времени суток. Пишу прогу (точнее переписываю) чтение данных с последовательного АЦП (12бит). Девайс подключен к СОМ порту, интерфейс организовал через EscapeCommFunction, внаглую дергаю вывода, на старых машинах, аля Целер 500, работала. Потом неопытный асспирант спалил АЦП, и тут начались проблемы, год железяка валялась, потом заменил почни всё "железо", а она показывает "цену на ГВОЗДИ", но некая коррфункция с адекватным значением наблюдается если делать измерения по одному каналу. Как только начинаю переключать каналы, нет слов... Думаю, что проблема во временных интервалах, если играться с параметром вот этой функции, то есть некие улучшения в работе. И так. Вопрос к знатокам. Как подождать от 1 мкс до 100мкс в юзер моде? Может функцию как-то упростить? Или ... Прога была писана 6 лет назад, на заре моей программерской. Тогда такого городил... Караул. Код (Text): Wait_us proc us_Time:DWORD LOCAL PerformanceCount:LARGE_INTEGER LOCAL PerformanceCountx:LARGE_INTEGER LOCAL Tick_Wait:DWORD invoke QueryPerformanceFrequency, ADDR PerformanceCount mov eax,DWORD PTR [PerformanceCount] mov PerformanceCount1,eax mov eax,DWORD PTR [PerformanceCount+4] mov PerformanceCount2,eax mov eax, [PerformanceCount1] invoke IntMul,eax,[us_Time] invoke IntDiv,eax,1000000 mov [Tick_Wait],eax invoke QueryPerformanceCounter, ADDR PerformanceCountx mov eax, dword ptr [PerformanceCountx] add [Tick_Wait], eax @@: invoke QueryPerformanceCounter, ADDR PerformanceCount .if eax mov eax, dword ptr [PerformanceCount] cmp eax, [Tick_Wait] jc @B .else KosjaK: ;invoke SendMessage,hDlg,WM_CLOSE,0,0 ret .endif ret Wait_us endp
сам недавно искал точные таймеры: более менее интересное по теме и может что пригодится: http://www.wasm.ru/forum/viewtopic.php?id=9034 http://www.codeproject.com/KB/system/timers_intro.aspx http://www.rsdn.ru/forum/winapi/1387967.1.aspx http://users.livejournal.com/_winnie/151099.html http://www.virtualdub.org/blog/pivot/entry.php?id=272 http://www.wasm.ru/forum/viewtopic.php?id=31308
S_Alex Переделать железку код переписать. Выкинуть задержки. Код (Text): invoke IntMul,eax,[us_Time] invoke IntDiv,eax,1000000 Если у тебя частота более 2 ГГц то в eax число отрицательное будет и ошибка в вычислениях скорее всего.
а еще я понял, что QueryPerformanceCounter вроде как обычно использует таймер на мат. плате, но его показания могут меняться в реалтайме и лучше этот метод использовать только для вычисления времени выполнения на коротких промежутках, а не для таймеров.
При загрузке система выбирает таймер. Или при установке драйверов. Должен выбирать наибыстрейший таймер, но это не всегда так. В большинстве случаях частота фиксирована и не меняется при исполнение в реалтайме. Но не исключено что на 1%(точно не знаю) компьютеров метод начнет выдавать не фиксированные значения.
А что делать с Intel SpeedStep и аналогичной плюшкой от AMD, из-за которых эти значения и без того начинают прыгать если нет сильной загрузки CPU. Вот у меня в холостом режиме эта фишка сбавляет частоту аж в 2 раза.
Когда-то писал что-то подобное для программно-аппаратного протокола HSP5 (KEB). Ввиду того что винда (особенно NT-линейки)очень далека от ОСРВ, пришлось делать все под DOS, но под вин98 тоже пахало. никак
можно попробовать старым добрым способом, но и он под виндой не идеален Код (Text): mov ecx, 1usec_ticks mov eax, 100 mul ecx @@: dec eax jnz @b при этом 1usec_ticks можно попробовать посчитать с помощью (rdtsc/rdpmc)/(QueryPerformanceCouter/QueryPerformanceFrequency) и разделить на среднее значение разницы (rdtsc/rdpmc)/(QueryPerformanceCouter/QueryPerformanceFrequency) для 10000-1000000 иттераций цикла dec eax\jnz @b
имхо, идеальный выход - поставить мегу с её стандартным АЦП + коннект к компьютеру можно сделать даже через USB. мне кажется что для решения задачи оцифровки сигнала юзать комп слишком накладно.
за 1us не скажу, а вот 100us для программатора - поставил таймер на 1006ВИ1 - и все дела. для пня 3ГГц под вынь ХР - на 0.1 мс 14 циклов чтения из ЛПт через inpout32.dll (или 47 циклов из под дос на целероне 300 МГц из форта). с другой стороны, исходя из этих данных, думаю, даже через драйвер и систему RTC 1-10us из-под винды реализовать крайне сложно, если вообще возможно
1 mks это считывание значения с порта 0x80. Ещё можно поднять приоритет и сделать замер количества итераций в цикле за определённое время. Я так делал анимацию спрайтов и работало достаточно хорошо.