* * * Форум CQHAM.RU Тема * * * -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Тема : Частотомер на МК Started at 12.09.2017 15:20 by RX3QRD Visit at http://www.cqham.ru/forum/showthread.php?t=36300 -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 1] Автор : RX3QRD Дата : 12.09.2017 15:20 Заголовок : Частотомер на МК С появлением микроконтроллеров схемотехника многих конструкций существенно поменялась. Коснулось это и частотомеров. Но есть сомнение относительно точности измерения. Частотомеры прямого отсчета, собранные на счетчиках, измеряют частоту непосредственно и погрешность минимальна и больше связана с температурным дрейфом опорного кварцевого генератора, устанавливающего время счета. В программах МК применяются два аппаратных таймера, которые переполняясь, инкреминируют переменные (время счета и число импульсов частоты на входе). Но при переполнении таймеров срабатывают прерывания и управление переходит подпрограмме обработки прерывания. Если это происходит в тот момент,когда переполняется счетчик таймера частоты, МК попросту пропускает это событие и теряет некоторое количество импульсов. Точность измерения падает. В то же время, процессор меньше шумит в эфир, что делает его применение в связной аппаратуре более приемлемым. Если мои выводы неверны,прошу разъяснить мне в чем мои заблуждения и помочь с уточнениями алгоритма. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 2] Автор : UN7GCE Дата : 12.09.2017 16:00 Но при переполнении таймеров срабатывают прерывания...При переполнении ставится флаг переполнения, а обрабатывать его, или нет это на совести программера. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 3] Автор : rx3apf Дата : 12.09.2017 16:45 И первый (наверное) вариант (AN592 от Microchip) базировался на PIC16C54, с одним таймером, и все чисто программно. Достаточно просто точно посчитать по тактам, и никаких проблем вообще нет, в принципе. Все будет в точности так же, как на жесткой логике, только на порядки проще схемотехнически. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 4] Автор : RX3QRD Дата : 12.09.2017 16:58 а обрабатывать его, или нет это на совести программера если программа должна считать,она будет считать. И пропуск флага=неточный подсчет. А если частота высокая, то пропусков будет много и ошибка растет -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 5] Автор : rx3apf Дата : 12.09.2017 17:01 Так про то и речь - обрабатывайте корректно, и все будет нормально. Таймер ведь при переполнении продолжает считать, достаточно в течении интервала переполнения отследить и обработать состояние. И так до конца окна счета. И насколько бы высокой не была входная частота, на входе таймера 0 (обычно используемого в таких частотомерах, по причине наличия асинхронного прескалера) она не может превышать тактовой (в принципе). Т.е. для обработки ситуации переполнения есть 256 командных циклов (а хватило бы и на порядок меньше). -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 6] Автор : UN7GCE Дата : 12.09.2017 17:16 если программа должна считать,она будет считать. И пропуск флага=неточный подсчет.Причём тут пропуск флага? Как это организуется в 628 ПИКе? Организуется кольцо счета, допустим на 100 mSec (к примеру). При в ходе в кольцо происходит запуск счета двух байтного таймера Timer1. По флагу переполнения происходит наращивание счетчика до 3, 4 или 10 байт (цифры беру к примеру). При выходе из кольца таймер останавливается. И никаких прерываний. Дальше обычная работа с байтами. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 7] Автор : RX3QRD Дата : 12.09.2017 17:49 Таймер ведь при переполнении продолжает считать, достаточно в течении интервала переполнения отследить и обработать состояние Понял. Флаг выставляется, таймер обнуляется и начинает цикл счета снова. Моя задача сбросить флаг и быстро посчитать. Следующий вопрос: в предделителе установлен коэфф. к примеру 256. И время счета вышло. Как узнать, сколько там "застряло"? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 8] Автор : rx3apf Дата : 12.09.2017 18:05 А для этого блокируют вход и досчитывают прескалер принудительно. В первоначальной реализации (AN592) для этого выделялась отдельная портовая нога, но гораздо проще и правильнее манипулировать битом полярности счета в байте опций. И тогда не требуется дополнительных ног. Если же прескалер внешний (или имеет дополнительные внешние каскады, например, триггеры 74 современных серий могут обработать и 300..400 MHz), придется выделить дополнительные линии, для разрешения окна счета и досчета. Итого три линии, включая вход таймера. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 9] Автор : RX3QRD Дата : 12.09.2017 18:11 гораздо проще и правильнее манипулировать битом полярности счета в байте опций расскажите поподробнее, пожалуйста. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 10] Автор : rx3apf Дата : 12.09.2017 18:21 А что подробнее ? Фронт счета (положительный или отрицательный) выбирается состоянием бита T0SE в регистре OPTION_REG. Запретив изменение состояние на входе таймера (переведя на выход), досчитывать прескалер можно как манипуляцией состоянием этой линии, так и битом T0SE. Повторяем переключение до тех пор, пока состояние TMR0 не изменится. Ну, есть тонкости с моментом изменения состояния (опрос регистра TMR0 надо на такт или два задержать, не помню уж). -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 11] Автор : UN7GCE Дата : 12.09.2017 18:35 А для этого блокируют вход и досчитывают прескалер принудительно.Подобная методика применялась в устаревших 84 ПИКах. В них не было команд управления первым таймером. Поэтому приходилсь колдовать с ногами и до счетами. В 628 ПИКе появилась команда bsf T1CON,TMR1ON ;вкл счетчик и bcf T1CON,TMR1ON ;выкл счетчик Поэтому измеряемую частоту подают всегда на порт RB6 и не морочим себе голову с до счетами. Утверждения, что пределитель и таймер1 имеют разные скорости счета неверны. Сделаны они на одной подложке и имеют одинаковую структуру. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 12] Автор : rx3apf Дата : 12.09.2017 19:32 Скорострельность таймера 1 я не проверял, поэтому что-то определенное утверждать не могу. Да, он вроде бы может работать совершенно асинхронно и, если схемотехнически реализация подобна таймеру 0, то и частота должна бы быть такого же порядка. Хотя, если судить по цифрам из даташита, там (TMR1 vs TMR0) ограничения существенно жестче. На 628 я делал частотомер с взаимным счетом, и там таймер 1 никак нельзя было отдать под измерительный вход, он там работал на счете опорника, а таймер 0 - традиционно на измерительном, плюс еще половинка 74 для повышения верхней границы (180 MHz работало). -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 13] Автор : alexis Дата : 12.09.2017 20:04 Так всё же, в итоге что оптимальнее? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 14] Автор : RX3QRD Дата : 12.09.2017 20:21 UN7GCE, Ну, заблокировать вход я могу, соединив с другой ногой порта и выставив на ней 0. Но вот не понял: для чего включается и выключается модуль? Это что дает? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 15] Автор : rx3apf Дата : 12.09.2017 20:36 Зачем соединять с другой ногой, если входную ногу ровно с тем же эффектом сделать выходом ? А включать-выключать - имелось в виду запускать и останавливать таймер TMR1, если его использовать для счета входных импульсов (тогда не требуется менять режим входной линии или использование внешней логики). -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 16] Автор : RX3QRD Дата : 12.09.2017 20:48 А включать-выключать - имелось в виду запускать и останавливать таймер TMR1 Я про запуск понял. НО не понимаю какого эффекта мы этим достигаем. Как это приводит к переполнению таймера и выставлению флага, если импульсы на входе отсутствуют? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 17] Автор : rx3apf Дата : 12.09.2017 20:51 Никак. Речь шла о управлении окном счета. Обработка переполнения - это уже другая часть задачи. Все то же самое - флаг выставляется при переполнении в процессе счета, его надо обрабатывать для расширения разрядности счетчика. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 18] Автор : RX3QRD Дата : 12.09.2017 20:57 rx3apf, я спрашивал именно про тот момент, когда окно счета захлопнулось и в предделителе застряло сколько-то импульсов. Их надо посчитать, иначе точность пострадает. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 19] Автор : rx3apf Дата : 12.09.2017 21:04 Для таймера 1 это не требуется, если не используется прескалер. Если же используется (там максимум на 8) - тем же способом, что и для таймера 0, как я уже подробно объяснил выше. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 20] Автор : RX3QRD Дата : 12.09.2017 23:19 И насколько бы высокой не была входная частота, на входе таймера 0 (обычно используемого в таких частотомерах, по причине наличия асинхронного прескалера) она не может превышать тактовой (в принципе). к примеру, измеряем частоту 40МГц. При предделителе 256 получаем 156250 срабатываний в секунду. Придется кварц 10-20МГц ставить. Запретив изменение состояние на входе таймера (переведя на выход), досчитывать прескалер можно как манипуляцией состоянием этой линии, так и битом T0SE. Повторяем переключение до тех пор, пока состояние TMR0 не изменится как меняя бит TOSE получается досчитать что в прескалере?... Он же всего-лишь определяет фронт внешнего тактового сигнала. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 21] Автор : Владимир_К Дата : 12.09.2017 23:39 Вот конструкция известного автора. Есть исходник, просмотрев который все станет ясно, как досчитывается прескалер и пр. и, все вопросы отпадут. http://msevm.com/2012/freq/index.htm А если что не ясно будет, тогда можно уточнить. А начинать на форуме с вопроса как извлечь цифру из прескалера.... то это до второго пришествия.. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 22] Автор : rx3apf Дата : 12.09.2017 23:45 1. 156 kHz - это совсем немного, и много меньше тактовой при практически произвольном выборе оной (аппаратное ограничение - частота на выходе прескалера должна быть меньше тактовой, поделенной на 4, т.е. даже при тактовой 1 MHz никаких проблем не будет) . Переполнения же будут происходить еще в 256 раз реже (чуть чаще 600 Hz). Ну и в чем же проблема ? 2. Да, бит T0SE определяет активный фронт. Ну так и изменение состояния T0SE аналогично изменению состояния входа T0CKI согласно функциональной схеме модуля TMR0. Соответственно, манипуляцией хоть этим битом, хоть состоянием входной ноги, можно получить произвольное количество импульсов на входе прескалера. Неужели и дальше надо объяснять ? -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 23] Автор : RX3QRD Дата : 13.09.2017 00:05 Ну так и изменение состояния T0SE аналогично изменению состояния входа T0CKI О как... Переключая этот бит в незамкнутом цикле с 0 на 1 и обратно мы получаем тот же эффект, что и подача импульса на ногу МК?.....Ну тогда все понятно. Переполнения же будут происходить еще в 256 раз реже Точно! Забыл, что надо учитывать 256 в самом таймере и еще делитель 256. Итого получаем 65536. -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 24] Автор : RX3QRD Дата : 13.09.2017 20:27 Может, кому-то будет интересно продвижение проекта... А профессионалов прошу не истерить по поводу примитивизма. Мы все начинаем с малого, не так ли? :smile: Итак, я решил, что проще будет, если число, соответствующее измеряемой частоте, будет изначально разбито на разряды:единицы,десятки,сотни. В проекте всего 8 разрядов, но горячие головы могут и "увеличиться". Это позволит напрямую выводить числа на индикаторы. Единицы-на свой,десятки- на свой и т.д. Но для этого надо и соответствующим образом считать. Но и алгоритм должен быть как можно короче. Вот мой вариант (тестировал в Дельфи): for i:=1 to 8 do begin Cx[i,1]:=Cx[i,1]+Cx[i,2]; if Cx[i,1]>9 then begin Cx[i+1,1]:=Cx[i+1,1]+1; Cx[i,1]:=Cx[i,1]-10; end; end; где Сх(i,j) - это массив чисел i - это разряды j - (1,2) это сами числа: 1 - число, которое считается, 2 - число, на которое идет увеличение. Оно может быть любым. Этот кусок можно оформить как процедуру и применять в любом вашем проекте. В том числе тогда, когда надо учесть промежуточную частоту, если частотомер используется как ЦШ. Только надо написать аналогичную процедуру вычитания. Ведь чем короче и быстрее счет, тем меньшее число можно закладывать в предделитель (или вообще от него отказаться!). Предупреждение: массив должен резервировать на один разряд больше, чем используете в программе. В данном примере это Сх(9,2) -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 25] Автор : rx3apf Дата : 13.09.2017 20:35 Не понимаю, к чему столь изощренные извращения ? Все делается просто до примитивизма - счет и вычисление в многоразрядной двоичной арифметике, результат преобразовывается в упакованный BCD, затем выводится на индикатор (с подавлением незначащих нулей и установки десятичной точки в нужную позицию). Не надо изобретать велосипед с треугольными колесами... -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- [Сообщение 26] Автор : RX3QRD Дата : 13.09.2017 21:28 Я с описанной вами технологией не знаком, поэтому иду своим путем. Кстати, мой не хуже. Это те же Фаберже, только чуть иначе. Он уже преобразован. Его только останется перевести в семисегментный код. Добавлено через 33 минут(ы): Вот кусок программы, обеспечивающий вычитание for i:=1 to 8 do begin if Cx[i,1]