Цитата(Валентиныч @ Apr 24 2007, 12:06)

Уважаемые, вспомним первоначальную постановку вопроса.
Если я правильно понимаю, человек интересуется способом (как?), позволяющим с максимальной точностью измерить частоту (какую?) за определенный интервал времени.
Зачем ему это нужно, и что он с этими результатами будет делать - вопрос третий.
ИМХО: для измерения макимально возможной частоты нужно минимизировать длительность промежуточных процедур. Например - по возможности исключить потери на вход/выход из прерываний. Это время, как известно, составляет в среднем 4 машинных такта. Плюс 2-3 такта на прочие действия. Какие уж тут 10 МГц на входе, при клоке 20 МГц?
Действительно, в погоне за исчезающе малой ошибкой потеряли исходный вопрос(:-)...
Прежде всего замечу, что если хочется мерить максимально точно, то на время измерения лучше забыть о прерываниях, или по крайней мере на моменты обработки начала и окончания окна.
Цитата(Валентиныч @ Apr 24 2007, 12:06)

Очевидно, что простой опрос порта (2 такта ) с последующим инкрементом (2 такта для регистра длиннее 1-го байта) + неизбежные прочие "мелочи" (1-2 такта) - это тот минимум, ниже которого не опуститься. Т.е. реально на регистрацию одного события по входу будет тратиться не менее 4-6 машинных тактов. Отсюда вытекает максимальная частота входного сигнала - 4 МГц. На пределе!
Второй вопрос - точность измерения. Здесь она определяется точностью задания "ворот"
Попробуем разобраться с червём сомнения, который точит Валентиныча(:-). Для автора топика опишу вгрубе алгоритм измерения методом ворот максимальной частоты 10 МГц, поданной на ножку Т0. Таймер 1 работает в режиме измерения системного клока.
1) Исходное состояние счётчика0 и таймера1 - остановлены и обнулены.
2) Запустим таймер1 и таймер0 двумя командами
Код
sts 0x81,r12
sts 0x25,r13
После выполнения инструкций T1=Nнач=2, T0=Mнач=0, в регистрах r12, r13 соответствующие настройки CSij для останова. Все переменные - 32-разрядные.
3) Ждём СТО секунд (делая попутно какие-то вещи и учитывая переносы таймеров в Mкон, Nкон).
4) Остановим таймер1 и таймер0 двумя командами
Код
sts 0x81,r14
sts 0x25,r15
После выполнения инструкций T1=Nкон=2'000'000'002, T0=Mкон=1'000'000'000, в регистрах r14, r15 соответствующие настройки CSij для останова.
5) По формуле Fx=Fo*(Mкон-Mнач±1)/(Nкон-Nнач) вычисляем измеренную частоту
Fx=20000000*(1000000000-0±1)/(2000000002-2)=10000000±0.01 Гц.
Никаких чудес, никаких прерываний, частота на входе 10 МГц, точность результата не хуже ±0.01 Гц. Программы умножения 32х32 и деления 64/32 в Сети можно найти на каждом углу(:-). Фактически, мною приведена готовая программа измерения, если вы меня понимаете.
Цитата(Валентиныч @ Apr 24 2007, 12:06)

Относительную точность "клокирования" (в тактах) реализовать не сложно, а вот обеспечить долговременную стабильность частоты расхожего "контроллерного" кристалла весьма и весьма не просто. И далеко не факт, что в течение 100 секунд эта "опора" будет стабильной...
Так что какие уж тут 0,02 Гц? Точнее - о какой достоверности подобных измерений идет речь?
Или я чего-то сильно не понимаю.

Вы говорите всё правильно, скажу только, что если уж вы решились мерять 10 МГц с такой точностью, то надо бы поставить опору, соответствующей точности, ну или по крайней мере раскошелиться на термокомпенсированный кварцевый генератор.
Есть относительно дешёвое решение - поочередно проводить измерения и калиброваться от хорошей опоры, это может быть радиосигнал, или GPS. То есть, используя секундные импульсы с GPS, сначала измерили частоту опорного генератора, используя ту же формулу и считая, что входная частота известна, затем измерили входную частоту, подставляя в формулу вычисления измеренную опорную частоту. Единственное существенное ограничение данного решения - кратковременная стабильность опорного генератора (на интервале 100 с) должна быть порядка 1Е-9 или лучше.