Comments 43
нехватает фотографий, которые хорошо иллюстрируют
«8канальное АЦП» :)
Вроде бы АЦП всегда был мужского рода?
PS: А за «моё день рожденье» вообще убивать готов. Grammar Nazi
Вроде бы АЦП всегда был мужского рода?
PS: А за «моё день рожденье» вообще убивать готов. Grammar Nazi
Про деньрожденье — это не к автору претензия, сорри. Просто по поводу моего др меня сегодня с утра уже задолбали этим и я злой :)
Упс, извиянюсь! Благодарю, исправил!
Просто у меня с институтских времен было сокращение в конспекте АЦП — аналогово-цифровое преобразование. Посему ОНО…
Просто у меня с институтских времен было сокращение в конспекте АЦП — аналогово-цифровое преобразование. Посему ОНО…
«ДециМиллиСекунда» — это скорее 10 мс, чем 0.1, если уж быть точным :) Обычно эту величину называют «тиком» (SystemTick), в современных ARM-ах даже есть специальный аппаратный таймер под эту задачу. Как правило, помимо инкремента переменной в этом прерывании выполняется еще перепланирование задач в случае использования ОС.
«ДециМиллиСекунда» — это скорее 10 мс, чем 0.1
Нет уж, извините :-)Р! Секунда — 1 сек. Миллисекунда — 1e-3 сек. «Деци» — 1e-1 (как дециметр). Посему получаем 1e-4.
По поводу тика — да, в Windows тоже явно оперируют тиками. Только тик там 1 мсек, если не ошибаюсь (т. к. функция GetTickCount() переполняется за 49 суток, если не ошибаюсь)
Нет уж, извините :-)Р! Секунда — 1 сек. Миллисекунда — 1e-3 сек. «Деци» — 1e-1 (как дециметр). Посему получаем 1e-4.
По поводу тика — да, в Windows тоже явно оперируют тиками. Только тик там 1 мсек, если не ошибаюсь (т. к. функция GetTickCount() переполняется за 49 суток, если не ошибаюсь)
Точность 1 мкс на интервале 5 суток вы никак не получите — намного раньше упретесь в точность кварцевого генератора.
UFO just landed and posted this here
Да ничего не мешает. Просто все зависит от конкретной реализации — у автора она упрощенная, а это важно для микроконтроллеров, так как у них нет лишних ресурсов ни по коду, ни по памяти, ни по быстродействию.
Кстати, ИМХО, глобальный счетчик времени лучше делать не микросекундным, а миллисекундным. Для пользовательского интерфейса (мигания, опросов кнопок, клавиатуры, отсчета выдержек времени и т. п.) этого часто вполне достаточно, и уменьшается нагрузка на ядро микроконтроллера. В специальных случаях можно сделать счетчик более точным.
Кстати, ИМХО, глобальный счетчик времени лучше делать не микросекундным, а миллисекундным. Для пользовательского интерфейса (мигания, опросов кнопок, клавиатуры, отсчета выдержек времени и т. п.) этого часто вполне достаточно, и уменьшается нагрузка на ядро микроконтроллера. В специальных случаях можно сделать счетчик более точным.
Ну-у, вначале я и хотел делать миллисекундным, но с моим контроллером и моим кварцем оптимальным получился как раз 0.1 миллисекундный. Им я в основном и пользуюсь — однажды, впрочем, пригодилось значение таймера
Что легче сравнить на предмет «что больше?» — одну числовую переменную или структуру?
память в 256-4096 байт, в основном :)
А можно поподробнее про то, что такое «Коммутатор фехтовальных ситуаций»? Что этот девайс делает?
UFO just landed and posted this here
Вы серьезно? А что там коммутировать-то?
UFO just landed and posted this here
Дело не в этом. В фехтовании (к слову, не только шпага — там еще рапира и сабля) наличествует 2 цепи наконечника в клинке, цепь электропроводящей куртки и цепь дорожки. Соответственно, распознаются ситуации укола в непроводящую поверхность, в куртку, в дорожку и в клинок (точнее, в гарду). Все эти ситуации — их всевозможные комбинации, длительность нажатия/касания (от 0.7 мсек в сабле до 15мсек в рапире) — надо анализировать. Скажем, скользящий укол в гарду, с которого перепрыгивает на куртку, а противник в это время уколол в гарду. И все это надо закоммутировать и убедиться, что все отрабатывается корректно.
обязательно счетчик меняемый в прерывание пометьте как
volatile dword dmsec;
а то может возникнуть ситуация когда оптимизатор ее проигнорирует например в такой ситуации
volatile dword dmsec;
а то может возникнуть ситуация когда оптимизатор ее проигнорирует например в такой ситуации
while(1){
if(dmsec == 0) fun();
}
Согласен. Исправил
И еще использование оператора goto ведет к непредсказуемым ошибкам, да и выглядит как то не профессионально :)
А вот с этим можно поспорить. У меня опыт программирования 20 лет и в С++ у меня еще не было ситуации, когда подходил ТОЛЬКО goto. В С тоже, в общем-то, всегда можно было выкрутиться.
НО в микроконтроллерах он иногда здорово облегчает жизнь! Потому что дает более простой код.
А вообще — какая разница, на самом-то деле? Главное, чтобы было читаемо и работало как надо. «Читаемо» — категория субъективная. «Работает как надо» — тут не важно, goto или while ().
IMHO :-)
НО в микроконтроллерах он иногда здорово облегчает жизнь! Потому что дает более простой код.
А вообще — какая разница, на самом-то деле? Главное, чтобы было читаемо и работало как надо. «Читаемо» — категория субъективная. «Работает как надо» — тут не важно, goto или while ().
IMHO :-)
Вместо самодельного dword используйте стандартный uint32_t.
А вы не думали, что таймер у вас в синхронном режиме и пользовательские прерывания (по нажатию кнопок или завершения преобразования АЦП и т.д.) будут нарушать работу таймера?
Для тех целей, что вы преследуете все давным давно придумано и называется это асинхронный режим работы таймера.
Для тех целей, что вы преследуете все давным давно придумано и называется это асинхронный режим работы таймера.
А вы меня нарочно запутать решили, но начнем с исходных данных
Для того, чтобы отсчитывать время в устройствах на AVR делают примерно так.
Вешают внешний часовой кварц на 32768Hz для запуска асинхронного таймера и пишут примерно такой код для настройки таймера.
В данном случае делитель 256, значит прерывание по таймеру возникает с частотой 32768/256=128Hz
А в регистр счетчика TCNT2 записано значение 0xC0, следовательно до переполнения произойдет 256-192=64 тактов что соответствует времени 0.5 секунды.
А потом обработчик прерывания вызываемый каждые пол секунды.
И всё! Все ваши измерения времени теперь не зависят от остальной части программы и от прерываний, а точность измерения временных промежутков выше примерно в 360 раз.
Часто при работе микроконтроллерного устройства есть необходимость отсчитывать «антропоморфное» время – сколько долей секунды светиться светодиоду, максимальный промежуток времени double-click
Для того, чтобы отсчитывать время в устройствах на AVR делают примерно так.
Вешают внешний часовой кварц на 32768Hz для запуска асинхронного таймера и пишут примерно такой код для настройки таймера.
В данном случае делитель 256, значит прерывание по таймеру возникает с частотой 32768/256=128Hz
А в регистр счетчика TCNT2 записано значение 0xC0, следовательно до переполнения произойдет 256-192=64 тактов что соответствует времени 0.5 секунды.
/* -------------------------------------------------------------------------- */
//TIMER2 initialize - prescale:256
// WGM: Normal
// desired value: .5Sec
// actual value: 0,500Sec (0,0%)
void timer2_init(void)
{
TCCR2 = 0x00; //stop
ASSR = 0x08; //set async mode
TCNT2 = 0xC0; //setup
OCR2 = 0x40;
TCCR2 = 0x06; //start
}
/* -------------------------------------------------------------------------- */
А потом обработчик прерывания вызываемый каждые пол секунды.
#pragma interrupt_handler timer2_ovf_isr:5
void timer2_ovf_isr(void)
{
TCNT2 = 0xC0; //reload counter value
TCCR2 = 0x06; //start
//тут полезный код
}
/* -------------------------------------------------------------------------- */
И всё! Все ваши измерения времени теперь не зависят от остальной части программы и от прерываний, а точность измерения временных промежутков выше примерно в 360 раз.
А зачем вешать часовой кварц, когда такая точность просто не нужна?
Если делать высокоточный секундомер или часы — то это будет оправданно.
Но если необходимо просто отмерять различные отрезки времени, незавязанные на реальное время — то какой в этом смысл?
Считаю что в заголовке слово точность будет логичнее заменить на слово шаг.
Если делать высокоточный секундомер или часы — то это будет оправданно.
Но если необходимо просто отмерять различные отрезки времени, незавязанные на реальное время — то какой в этом смысл?
Считаю что в заголовке слово точность будет логичнее заменить на слово шаг.
Можно ли для этого использовать таймер не на 32768, а, скажем, как у меня, 12 MHz?
Хм… А как влияет на точность изменение счетчика в прерывании? Или все делается с расчетом на то, что это выполнится до следущего такта таймера?
Не проще поставить предделитель на 64, тогда счетчик сам по себе будет переполняться ровно 2 раза в секунду?
Не проще поставить предделитель на 64, тогда счетчик сам по себе будет переполняться ровно 2 раза в секунду?
Вы имеете в виду изменение программного счетчика dmsec? Операция сложения занимает совсем немного времени.
Что касается периода таймера, то меня 1) интересовала точность в пределах 1 мсек, 2) хотелось занять 8-ми битный таймер, а не 16-ти битный.
Что касается периода таймера, то меня 1) интересовала точность в пределах 1 мсек, 2) хотелось занять 8-ми битный таймер, а не 16-ти битный.
Рядом с комментарием есть стрелочка вверх. Комментарий был обращен к Zak по поводу кода асинхронного таймера.
Как видно, он настроен на прерывание не при совпадении, а при переполнении. Притом каждое прерывание счетчик таймера вручную устанавливается на фиксированное значение. А значит есть вероятность того, что действие установки счетчика будет выполнено при ненулевом его значении, что приведет к ошибкам измерения времени.
В данном конкретном случае (128Hz при тактовой 12MHz, 1 прерывание, 2 строчки кода) — этого явно не произойдет. Но не всегда все так просто.
Как видно, он настроен на прерывание не при совпадении, а при переполнении. Притом каждое прерывание счетчик таймера вручную устанавливается на фиксированное значение. А значит есть вероятность того, что действие установки счетчика будет выполнено при ненулевом его значении, что приведет к ошибкам измерения времени.
В данном конкретном случае (128Hz при тактовой 12MHz, 1 прерывание, 2 строчки кода) — этого явно не произойдет. Но не всегда все так просто.
Sign up to leave a comment.
Начинающим: счетчик на микроконтроллере с шагом 2/3 микросекунды и переполнением в несколько суток