GetSmart 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба i - переход на длительный обработчик (пусть будет Uart0) TCNT1 = 0x7FFE i + 0x1 - срабатывание захвата TIF1 = 1, ICR = 0x7FFF, TOV1 = 0. i + 0x7FF8 - Uart0 обработка завершена выполнение RETI (4 такта), TCNT1 = FFF6, TOV1 = 0 i + 0x7FFC - возврат в основную, выполнение хотя бы одной команды, TCNT1 = 0xFFFA i + 0x7FFD - начало входа в обработчик (11 тактов) T1_ICAP, TCNT1 = 0xFFFB, TOV1 = 0 i + 0x8008 - первая команда обработчика T1_ICAP, TOV1 = 1 <------ ! ну и коррекция рез-тата +0x10000, т.к. попадаем под условие коррекции (ICR < 32k, TOV=1). Ну зачем же такой "экстремальный" пример приводить? Который, кстати, алгоритм-то не дискредитирует :) Я же не обещал ровно до 32К тактов дополнительного прерывания. Ваш пример всего-лишь указывает, что максимальное время прерывания = 32К-хх тактов. Скажем 31К или 32000 такта 100% хватит для работоспособности проги. А в Вашей версии будет то же самое = 256-хх тактов. Вобщем недостатка как такового в моей версии и нету. Блин :( Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Еще подправил код: Что-то мне разонравилось измерение по прерыванию. Наверное, надо делать без всяких прерываний, в фоне(:-). Вам больше не нравятся прерывания ? - Вы просто не умеете их правильно готовить (с) (не мой) :) А что там уметь? Прерывание, оно и в Африке-прерывание(:-). По делу. Выразился не так, как хотел. Мне не нравится длинное прерывание, которое вдруг стало накладываться на наши два. Откуда бы ему взяться в задаче по измерению временного интервала? Поэтому предлагаю сделать откат назад и исключить третье прерывание. Теперь поясню, почему пропал мой предыдущий текст, а то народ уже и этим тычет(:-). Вчера к концу рабочего дня набрал почти ведро маслят, представьте, в октябре! Ну я разволновался, как же дилишез(:-), вследствие такого события случайно удалил почти весь текст. А хотел ведь просто добавить то, что вы увидели. Вот еще один вопросик, требующий внимания. Автор топика намеревался измерять длительность секундных импульсов, а не период. Т.е., есть передний фронт импульса, длительность импульса и задний фронт импульса. Время начала импульса наша программа измерит, а как быть со спадом? Может быть перенастраивать ICES1 при первом входе в прерывание TIM_CAPT или есть более короткий путь? И моим оппонентам на будущее. Я говорю то, что говорю, не надо искать второго смысла, ОК? И замечайте смайлики иногда. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Мне кажется, зря вы здесь используете повторно r7, r6. Вдруг основная программа не успеет их обработать, а уже возникнет новое прерывание TIM1_CAPT. Понятно, что хочется съэкономить, но такая экономия может выйти боком(:-) Нет, c R6,R7 там все в порядке. вот этот код будет выполнен в конце прерывания TIM1_CAPT при любых условиях: mov R6,R2 mov R7,R3 так что здесь, ИМХО все ОК. Ну раз так, вот вам еще экономия. Не используйте регистры r5-r4 в прерывании, храните результат непосредственно в регистрах icr1h-icr1l. Будет сохранно, как в банке ... до следующего захвата. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Ну раз так, вот вам еще экономия. Не используйте регистры r5-r4 в прерывании, храните результат непосредственно в регистрах icr1h-icr1l. Будет сохранно, как в банке ... до следующего захвата. А как Вы в основной программе планируете узнавать что произошел второй захват ? :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Автор топика намеревался измерять длительность секундных импульсов, а не период. Т.е., есть передний фронт импульса, длительность импульса и задний фронт импульса. Время начала импульса наша программа измерит, а как быть со спадом? Может быть перенастраивать ICES1 при первом входе в прерывание TIM_CAPT или есть более короткий путь?Ну дык у АВР есть возможность вызывать прерывание по любому изменению состояния входа. Надо только при запуске правильно инициализироваться (учесть текущее состояние), а дальше - понеслась. Ведро маслят... Это многое объясняет... Как-нить при случае тоже ляпну такое :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
1891ВМ12Я 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Прошу прощения за оффтоп, но для самого автора темы проблема давно уже как не актуальна (1-й пост - 2-го июня)... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Прошу прощения за оффтоп, но для самого автора темы проблема давно уже как не актуальна (1-й пост - 2-го июня)... ну точно OFF - в топку :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Прошу прощения за оффтоп, но для самого автора темы проблема давно уже как не актуальна (1-й пост - 2-го июня)... ___________ Please, don't kill me :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
CD_Eater 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Минус только в отсутствии аппаратного запоминания текущего приоритета и запрета низкоприоритетных прерываний и текущего.Это не минус, это фича ;) Для многих задач это плюс т.к. одноуровневый КП избавляет программиста от некоторых проблем синхронизации. Конечно, гарантия непрерываемости текущего обработчика прерываний даёт возможность, например, использовать некоторые регистры или ячейки памяти в качестве общих временных для всех обработчиков прерываний без сохранения их предыдущего состояния, а также ограничивает размер стека - это удобно. С другой стороны, на ранних AVR-ках с аппаратным стеком (на 3 вложенных вызова подпрограмм и прерываний) иначе и быть не могло. А далее памяти прибавили, но основу ядра менять не стали... При большом желании можно легко (!) сделать двухуровневой КП (трёх) если вручную запрещать текущее прерывание, а потом устанавливать флаг I. Плохо только что стека маловато. Можно, но не нужно. Проще просто подобрать другой камень когда это действительно надо. Зачем выбирать другой камень, если вопрос лишь в доработке софта ? Менять камень нужно лишь в случае, если он не удовлетворяет требованиям к железу. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
singlskv 0 11 октября, 2006 Опубликовано 11 октября, 2006 · Жалоба Так... Вы - против, я - за. Что будем с этим делать? Ничего :) оставим как есть - 2 варианта. Не бывает единственно верных решений. Осмелюсь предложить следующее решение: .def ConstFF = R8 .def _TOV1 = R9 .def _Sreg = R10 .... clr ConstFF dec ConstFF ldi R16, (1 << TOV1) mov _TOV1, R16 .... ; Input Capture: TIM1_CAPT: in _Sreg,SREG in R4, ICR1L in R5, ICR1H cp R5, _TOV1 brsh _do_not_correct_result in R6, TIFR and R6, _TOV1 breq _do_not_correct_result out TIFR, R6 sub R2, ConstFF sbc R3, ConstFF _do_not_correct_result: mov R6, R2 mov R7, R3 out SREG,_Sreg ; <-- 32bit Result R7-R6-R5-R4 (MSB R7) reti Здесь уже кому как повезет, куда _TOV1 попадет в TIFR, такой и будет запас для длинных прерываний. Да и код, ИМХО становится намного понятнее А если серьезно, то запас для других прерываний нужно оставлять в зависимости от конкретной задачи. Например, вместо TIM1_OVF мы можем использовать TIM1_CAPTA со значением OCR1A<32K и тогда запас должен быть другим, тогда будет рулить такой код: in R4, ICR1L in R5, ICR1H in R7, OCR1AH lsr R7 cp R5, R7 brsh _do_not_correct_result Ну конечно на определенном диапазоне значений OCR1A Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 12 октября, 2006 Опубликовано 12 октября, 2006 · Жалоба Ну раз так, вот вам еще экономия. Не используйте регистры r5-r4 в прерывании, храните результат непосредственно в регистрах icr1h-icr1l. Будет сохранно, как в банке ... до следующего захвата. А как Вы в основной программе планируете узнавать что произошел второй захват ? :) А вы у GetSmart спросите, он всё знает(:-). Спокойно, GetSmart, шютю я(:-) Чуть посерьёзнее. Я вам про экономию регистров в прерывании говорю, "которых всегда не хватает", а вы плавно меняете тему. Какая разница, где хранить время текущего захвата, в регистрах r7-r6-r5-r4 или в r7-r6-icr1h-icr1l? Никакой разницы нет. Почти. Зато экономится два регистра! Ну а по делу, думаю есть несколько подходов. 1) Есть две переменные, скажем, oldTime и newTime (ваши r7-r6-r5-r4). Прерывание захвата должно переписывать содержимое newTime в oldTime, и только затем обновлять newTime. Основная программа в любое удобное для себя время(:-) определяет длительность интервала, просто вычитая содержимое oldTime из newTime. 2) Прерывание захвата чередует признак начала измерения и конца измерения, (можно просто счетчик на регистре, признак-младший бит), а основная программа доделывает остальное. Автор топика намеревался измерять длительность секундных импульсов, а не период. Т.е., есть передний фронт импульса, длительность импульса и задний фронт импульса. Время начала импульса наша программа измерит, а как быть со спадом? Может быть перенастраивать ICES1 при первом входе в прерывание TIM_CAPT или есть более короткий путь?Ну дык у АВР есть возможность вызывать прерывание по любому изменению состояния входа. Надо только при запуске правильно инициализироваться (учесть текущее состояние), а дальше - понеслась. Неправильно. В том то и дело, что не один раз при запуске программы надо инициализироваться, а каждый раз при входе в захват(:-(. Потому что на четных захватах вы ловите переход 0-1 (начало импульса), а на нечетных захватах вы ловите 1-0 (конец импульса). Я и спрашивал, перенастраивать ICES1 каждый раз или есть другой способ, попроще? Ведро маслят... Это многое объясняет... Как-нить при случае тоже ляпну такое :) GetSmart, хорош бурчать, это у вас так что проявляется(:-)? Не злитесь, ляпните что-нибудь или тяпните, разрядка придёт, поверьте(:-). Добавлю специально для вас. Напротив моих окон стоит бангало, под ним живет более 20 диких кроликов, смешные такие...А недавно видел как ворона ссорилась с белкой, наскакивали друг на друга, прям как вы на меня(:-). GetSmart, жена маслята уже посолила, вот. Белые тут тоже водятся, но ехать далеко, в Нью Форист, неохота... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
GetSmart 0 12 октября, 2006 Опубликовано 12 октября, 2006 · Жалоба GetSmart, хорош бурчать, это у вас так что проявляется(:-)?Это веселуха. Заметьте, над другими тоже. А вообще, люблю "поржать" над чужими глупостями. Это после длииинного отпуска у меня такой бзик. Должен пройти. Я и спрашивал, перенастраивать ICES1 каждый раз или есть другой способ, попроще?Нету.А вы у GetSmart спросите, он всё знает(:-)Нее, я мало знаю. На всём форуме я очень мало где появляюсь. То есть знаю совсем немного тем, но обычно очень глубоко. Больше всего меня прикололо это: когда вам показали как безболезненно доработать прогу возможностью обработки дополнительных прерываний вы выдали фразу, что вам прерывания не нравятся и надо делать вообще без них. Надо было видеть моё лицо :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 15 октября, 2006 Опубликовано 15 октября, 2006 · Жалоба А недавно видел как ворона ссорилась с белкой, наскакивали друг на друга, прям как вы на меня(:-). Дык, эта, если смотреть со стороны, здесь все замечания вам по делу были сказаны, а вы все в шутку да в обидку воспринимаете.. Что ни пост - то перл: особливо это: Какая разница, где хранить время текущего захвата, в регистрах r7-r6-r5-r4 или в r7-r6-icr1h-icr1l? Ну уж никак не в аппаратно зависимых регистрах, которые нам абсолютно неподконтрольны. Вы что, правда не понимаете, что можно не успеть вычитать icr1h-icr1l до того как случится следующий захват? либо например наткнуться на ситуацию когда в момент вычитки L, произойдет следующий захват. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
=GM= 0 16 октября, 2006 Опубликовано 16 октября, 2006 · Жалоба Что ни пост - то перл: особливо это: Какая разница, где хранить время текущего захвата, в регистрах r7-r6-r5-r4 или в r7-r6-icr1h-icr1l? Ну уж никак не в аппаратно зависимых регистрах, которые нам абсолютно неподконтрольны. Вы что, правда не понимаете, что можно не успеть вычитать icr1h-icr1l до того как случится следующий захват? либо например наткнуться на ситуацию когда в момент вычитки L, произойдет следующий захват. Я и не такие перлы могу выдавать(:-). Но вообще-то, в нашем случае никакой разницы на самом деле нет, посудите сами, как только произошел захват, возникло прерывание, в котором регистры icr1h-icr1l читаются и переписываются в r5-r4, т.е. и icr1h-icr1l, и r5-r4 изменяются практически одновременно (макс разница 32 мс, если есть длинное прерывание). Естественно предполагается, что вы должны успеть обработать r7-r6-r5-r4 до следующего захвата, который может случиться через секунду (по условию задачи). Ну и спрашивается, зачем тратить два регистра МК, если можно с таким же успехом хранить данные в регистрах захвата? Если же вы не успели, то произойдет новый захват, r5-r4 тоже испортятся, так что тут ничто не поможет, какая разница, что испорчено? Как меру борьбы, в прерывании можно сразу сохранять время захвата в озу, но опять же сохранять можно прямо из регистров захвата, r5-r4 тут не нужны. Вы-то сами понимаете, что при наличии длинного прерывания наступит крах вашей системы прерываний, если, скажем, возникнет два прерывания захвата в течение 65 мс? По существу, во время дискуссии выплеснули ребеночка, стали решать задачу измерения интервала при наличии длинного прерывания и меры по его устранению, хотя автор просил совета по измерению длительности секундных импульсов, а не периода, следовательно, по моему мнению, время между импульсами может быть любым, пусть, скажем, будет допустимый минимум 50 мкс между спадом одного импульса и фронтом другого, ну и где будут длинные прерывания? Или другими словами, минимальное время между двумя захватами должно составлять 50 мкс, что означает отказ от других прерываний, будь они длинные или короткие... Возможно, кому-то достаточно измерять импульсы от 32 мс до секунд и с длинными прерываниями, согласен, тогда забудьте о сказанном выше. Я бы сказал так, что постановка первоначальной задачи была нечеткой, отсюда все недоразумения. Что ещё? На справедливую критику не обижаюсь, с несправедливой борюсь по мере сил(:-), и посмеяться и пошутить люблю, но по-доброму. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
defunct 0 18 октября, 2006 Опубликовано 18 октября, 2006 · Жалоба Я и не такие перлы могу выдавать(:-). Но вообще-то, в нашем случае никакой разницы на самом деле нет, посудите сами, как только произошел захват, возникло прерывание, в котором регистры icr1h-icr1l читаются и переписываются в r5-r4, т.е. и icr1h-icr1l, и r5-r4 изменяются практически одновременно (макс разница 32 мс, если есть длинное прерывание). Естественно предполагается, что вы должны успеть обработать r7-r6-r5-r4 до следующего захвата, который может случиться через секунду (по условию задачи). Ну и спрашивается, зачем тратить два регистра МК, если можно с таким же успехом хранить данные в регистрах захвата? Если же вы не успели, то произойдет новый захват, r5-r4 тоже испортятся, так что тут ничто не поможет, какая разница, что испорчено? Затем, что прерывание может произойти именно в момент вычитки значения, и мы можем прочитать недостоверные данные. Если же рез-тат будет храниться в r7-r6-r5-r4, то мы можем запретить флаг I при обращении к этой 32х битной переменной, и тем самым обезопасить себя от последствий описанного случая. Учить матчасть :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться