CD_Eater 0 5 октября, 2006 Опубликовано 5 октября, 2006 (изменено) · Жалоба Не пойму, к чему эти обсуждения наилучшего кода, если задачка поставлена некорректно. Как уже было отмечено выше, точность 1 ppm на практике (используя типичный кварц) недостижима, поэтому увеличение разрядности счётчика таймера, применение однотактового аппаратного захвата и увеличение частота кварца никак не смогут улучшить ситуацию с относительной точностью измерения (которая в процентах). А если МК тактирован частотой 1 МГц достаточной точности и имеет аппаратный захват, то задача решается даже на 8-битном таймере, используя только прерывание захвата. А если нужно экономить энергию спящим режимом, то придётся использовать прерывание захвата и прерывание переполнения таймера, причём не обязательно того же самого таймера, по которому производится захват. Изменено 5 октября, 2006 пользователем CD_Eater Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
khach 44 5 октября, 2006 Опубликовано 5 октября, 2006 · Жалоба Как померять? Используя ГЛИН (генератор пилы) и внутренний АЦП АВРки. Внешней обвязки- два триггера и генератор тока на операционнике. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SapegoAL 0 5 октября, 2006 Опубликовано 5 октября, 2006 · Жалоба все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры. :) Вы сами поняли что вы написали??? А как вы узнали что "сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры" Это мне напоминает рассказ одного рыбака, который рассказывал следующее: Ну бросаю пол-дня -- нифига. Ну потом нацепил наживку в виде лягушки и выбрасываю на берег. И медленно стягиваю в воду. :) Понимаешь она (щука) стоит в воде и ждёт повернувшись мордой к берегу. А тут моя лягушка. Ну и вытащил одну. Короче приятно иметь знакомого, который запросто посмотрит внутрь процессора или сквозь толщу воды и заглянет в мозги щуки. А тут мозги подруги жизни (их там не много вроде), и то - сплошные потёмки. :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 6 октября, 2006 Опубликовано 6 октября, 2006 · Жалоба У меня ситуация, когда память Тини13 (1кь) заполнена на 960 байт, при этом ОЗУ 64 байт и его мало. Та-же прога, но адаптированная к Меге8 работает без проблем (512 байт ОЗУ). К чему бы это? Размер программы вообще роли не играет, а 64байта ОЗУ + столько же eeprom это на самом деле даже много c учетом, что программа на Asm. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stanislav 0 6 октября, 2006 Опубликовано 6 октября, 2006 · Жалоба все хорошо ребята - мона конечно извращаться с АВР с аппаратным захватом, но тут парень был прав, если в результате возникнет несколько прерываний, то не факт, что все там работает аппаратно, а вы это все понимает - паралельно, но там не все параллельно, проверить просто - забейте проц в постоянное прерывание, а лучше создайте множественные случаи прерывания, проц может просто умереть, у меня так было, и не из-за программы, а потому что сбивалась декодировка кодов внутри этой продвинутой РИСК-архитектуры. :) Вы сами поняли что вы написали??? .................................... :bb-offtopic: Дык, посмотрите, откуда парень пишет. У них там анашу на каждом углу продают вполне легально... Прошу прощенья за оффтоп. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 6 октября, 2006 Опубликовано 6 октября, 2006 · Жалоба Ну вот, опоздал к началу обсуждения, как всегда, впрочем(:-) Как можно измерить временные интервалы дительностью несколько секунд на AVRах с точностью до микросекунды? При том что кварц стоит на 1 МГц? Емкости таймера-счетчика 16 бит для такой задачи не хватает... Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные. По-моему, сделать надо вот что. Прежде всего, подключить измеряемый сигнал к схеме захвата, на таймер1 подать системный клок и выделить две 3-байтовые переменные, скажем, Т3-Т2-Т1 для хранения времени начала измеряемого интервала и Т6-Т5-Т4 для хранения времени конца интервала. Затем надо написать программу со следующим алгоритмом. 1) Обнулить Т3 и Т6. 2) Стоять здесь и ждать первого захвата. 3) Переписать значение из регистра захвата в Т2-Т1. 4) Проверить наличие переноса из таймера1. При наличии переноса добавить единицу к Т6. 5) Проверить наличие второго захвата, если нет захвата перейти к п.4. 6) После захвата переписать значение из регистра захвата в Т5-Т4. 7) Вычислить разность двух переменных Т6-Т5-Т4 и Т3-Т2-Т1, которая даст длительность интервала в микросекундах, если системная частота равна 1 МГц. Выдать результат, куда надо. 8) Переписать Т6-Т5-Т4 в Т3-Т2-Т1. 9) Перейти к п.4. Трёх байт должно хватить на длительности до 16 секунд, если надо больше, то взять 4-х байтные переменные и т.д. Относительная точность измерения будет определяться только погрешностью системной частоты +-1*Е-6. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_artem_ 0 6 октября, 2006 Опубликовано 6 октября, 2006 · Жалоба =GM=, использование арифметических операций предполагает различную длину кода при наличии или отсутствии переноса что введет нелинейность по выполненнию программы. Это можно скомпенсировать если алгоритм сделать на ассемблере а все операции засимметрировать там где это нужно noopьами для одинакового времени выполнения при любом внутреннем состоянии счетчиков. Или же измерив интервал, скорректировать результат посредством прибавления произведения коэффициента ошибок на соответствуюшее им количество переносов , что опять таки предполагает использование ассемблера максимальная ошибка измерения будет равна произведению максимального количества инструкций выпоняемых в цикле подсчета времени и для получения заданной ошибки измерения , количество тактов на самую длинную операцию не должно превышать 16 при 16 МГц тактовой частоте при условии одномикросекундной погрешности Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 6 октября, 2006 Опубликовано 6 октября, 2006 · Жалоба =GM=, использование арифметических операций предполагает различную длину кода при наличии или отсутствии переноса что введет нелинейность по выполненнию программы. Это можно скомпенсировать если алгоритм сделать на ассемблере а все операции засимметрировать там где это нужно noopьами для одинакового времени выполнения при любом внутреннем состоянии счетчиков. Или же измерив интервал, скорректировать результат посредством прибавления произведения коэффициента ошибок на соответствуюшее им количество переносов , что опять таки предполагает использование ассемблера максимальная ошибка измерения будет равна произведению максимального количества инструкций выпоняемых в цикле подсчета времени и для получения заданной ошибки измерения , количество тактов на самую длинную операцию не должно превышать 16 при 16 МГц тактовой частоте при условии одномикросекундной погрешности Если честно, ничего не понял, что вы написали(:-(. Какое использование арифметических операций? Измерение делается на аппаратном уровне, от программы требуется только запомнить начальное и конечное время, учесть переносы таймера1, ну и вычислить разность времен, чтобы получить частоту. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
_artem_ 0 7 октября, 2006 Опубликовано 7 октября, 2006 · Жалоба Правильно говорите - я то невнимательно прочитал подумал что поллингом считаете а флаги не в счет. Извиняюсь за ошибку. А даташит вообше то говорит Вашими словами .) Можно и не анализировать флаги poll'om (правильно ли я понял?) а все делать в прерываниях, хотя для критического случая совпадения overflow с capture придется таки флаг overflow анализировать при исполнении прерывания в capture - overflow по приоритету ниже чем capture. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 7 октября, 2006 Опубликовано 7 октября, 2006 · Жалоба Подправил немного код GetSmart и defunct - добавил сохранение SREG в прерываниях - добавил сброс флага TOV1 в TIFR если делали коррекцию .def AL = R24 .def Const0 = R8 .def Const1 = R9 .def _Sreg = R10 .... ldi AL, 1 mov Const1, AL clr Const0 ... ; обработчик Input Capture: TIM1_CAPT: in _Sreg,SREG in R4, ICR1L in R5, ICR1H tst R5 brne _do_not_correct_result in AL, TIFR andi AL, (1 << TOV1) breq _do_not_correct_result out TIFR, AL add R2, Const1 adc R3, Const0 _do_not_correct_result: mov R6, R2 mov R7, R3 out SREG,_Sreg ; <-- 32-х битный результат в четверке регистров R7-R6-R5-R4 (MSB R7) reti ; обработчик Timer Overflow: TIM1_OVF: in _Sreg,SREG add R2, Const1; Инкрементировать старшие 16 бит 32-х битного счетчика adc R3, Const0; учет переноса. out SREG,_Sreg reti Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Stanislav 0 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные...Основная проблема, как уже и написал уважаемый CD_Eater, заключается в том, как сделать опорный генератор, чтобы на 1с измеряемого интервала получить погрешность (а не временнОе разрешение) в 1 мкС. Сама же методика измерения, предложенная в теме, в том числе и Вами, вопросов не вызывает. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба Задача достаточно простая, а предлагаемые решения, на мой взгляд, слишком сложные...Основная проблема, как уже и написал уважаемый CD_Eater, заключается в том, как сделать опорный генератор, чтобы на 1с измеряемого интервала получить погрешность (а не временнОе разрешение) в 1 мкс. Сама же методика измерения, предложенная в теме, в том числе и Вами, вопросов не вызывает. Поясните, что в данном случае вы понимаете под погрешностью и разрешением? И как вы их вычисляете? Мне кажется, всем будет полезно понять разницу в понятиях. На мой взгляд, погрешность метода (при наличии абсолютно точного генератора) составляет 1 мкс для секундного интервала при 1МГц системном клоке. Естественно, неточность генератора увеличивает погрешность. Хотя тут вопрос, может ли помочь тот факт, что кратковременная нестабильность (на секундном интервале) кварцевого генератора достигает 1Е-9..1Е-12? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба Забавно. На этой странице всех повело совсем не в ту степь, о которой тема. Это как дайте кому-нить палец, дак он и всю руку оттяпает. Сам AVR пропал куда-то чтобы разъяснить, но в его вопросе нет слов о стабильности кварцев, а значит этот критерий точности не рассматривается. Есть слова о проце AVR и о 16 битном таймере. Если обращать внимание на них, то ответ уже давно дан положительный. Причём в условиях задачи это получается максимально возможная точность устройства, ну как 10-битный АЦП, у которого реальная точность всегда поменьше 10 бит из-за разных причин. То же и здесь. В силу разного времени прихода фронтов на шкале 1 мкс запросто может возникнуть "ошибка" вплоть до 1 мкс, от которой в данной схеме никак не избавиться. А вот всякие разговоры о точности и стабильности кварцев только дискредитируют авторов и вообще на мой взгляд какое-то балоболство. =GM= Причём тут кратковременная нестабильность в 1Е-9..1Е-12, если долговременная будет в 10000 раз хуже? Автоподстройки здесь нет и кратковременная нестабильность не спасает. А вообще, точность кварца при изготовлении наверно 1Е-4 и все разговоры о температурной и прочей нестабильности - бред какой-то. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба Подправил немного код GetSmart и defunct - добавил сохранение SREG в прерываниях - добавил сброс флага TOV1 в TIFR если делали коррекцию .def AL = R24 .def Const0 = R8 .def Const1 = R9 .def _Sreg = R10 .... ldi AL, 1 mov Const1, AL clr Const0 ... ; обработчик Input Capture: TIM1_CAPT: in _Sreg,SREG in R4, ICR1L in R5, ICR1H tst R5 brne _do_not_correct_result in AL, TIFR andi AL, (1 << TOV1) breq _do_not_correct_result out TIFR, AL add R2, Const1 adc R3, Const0 _do_not_correct_result: mov R6, R2 mov R7, R3 out SREG,_Sreg ; <-- 32-х битный результат в четверке регистров R7-R6-R5-R4 (MSB R7) reti ; обработчик Timer Overflow: TIM1_OVF: in _Sreg,SREG add R2, Const1; Инкрементировать старшие 16 бит 32-х битного счетчика adc R3, Const0; учет переноса. out SREG,_Sreg reti Хочу немного покритиковать программу. 1) От возникновения прерывания захвата до команды "in AL,TIFR" может пройти от 12 до 15 МЦ, т.е. достаточно много времени, чтобы произошел перенос от переполнения, следовательно, возможна ошибка в определении времени. 2) Вполне возможно, что если прерывания TIM1_OVF и TIM1_CAPT возникли в течение указанного периода, то прерывание TIM1_OVF выполнится после TIM1_CAPT и ПОВТОРНО скорректирует результат в r3-r2 (не уверен на все 100, надо проверять). 3) Вход в прерывание TIM1_CAPT означает конец интервала измерения и наличие правильного времени в r5-r4 за исключением возможного последнего переноса. Но поскольку перенос из r5-r4 в r7-r6 возможен в одном единственном случае, когда содержимое r5-r4 переходит из состояния 0xFFFF в 0x0000, содержимое регистров r5-r4 надо проверять на 0. В соответствии со сказанным ниже приведена исправленная программа обработки. .def temp =r16 .def savreg =r10 ; обработчик Input Capture: TIM1_CAPT: in savreg,SREG in R4,ICR1L ;точные два младших in R5,ICR1H ;байта времени movw r6,r2 ;два старших байта времени mov temp,r4 ;с возможным переносом or temp,r5 ;во время захвата brne nocarry ;не было переноса subi r6,-1 ;учтем sbci r7,-1 ;перенос nocarry: out SREG,Sreg reti ; обработчик Timer Overflow: TIM1_OVF: in savreg,SREG subi r2,-1 ; sbci r3,-1 ; out SREG,savreg reti Ну и последнее, в подобных случаях предпочитаю использовать конструкцию subi r2,-1 ; sbci r3,-1 ; Вместо эквивалентной add R2,сonst1 ; adc R3,сonst0 ; что очевидно лучше, поскольку освобождаются два регистра сonst0 и сonst1. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 9 октября, 2006 Опубликовано 9 октября, 2006 · Жалоба mov temp,r4 ;с возможным переносом or temp,r5 ;во время захвата brne nocarry ;не было переноса Плохая идея. Хуже чем было. Там (r5:r4) может быть и 10 и 100, если например выполнялось третье высокоприоритетное прерывание. А после его завершения началось прерывание CAPT. ----------- PS. У кого длиннее? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться