Официальный сайт компании Arduino по адресу arduino.cc
Таймеры , кварцы , или почему оно не работает ))
- Войдите или зарегистрируйтесь, чтобы получить возможность отправлять комментарии
Втр, 07/07/2015 - 21:13
Помогите разобраться с маленьким девайсом на Atmega16а-AU
Сделать решели на МК Atmega16A-AU (tqfp64) , нашли PinMap на нее , добавили в Boards запись , https://github.com/sudar/arduino-extra-cores/blob/master/boards.txt , изменили Fuse LOW = 0xFF, HIGH 0x99 в boards указали новый кварц , вроде все хорошо но не работает , после прошивки ничего не происходило начал разбараться ( насколько умею) , убрал все из скеча кроме светодиода и LCD1602 и вот тут мозг сдался , ситуация в следующем
void loop() { N++; digitalWrite(led,HIGH); delay(500); digitalWrite(led,LOW); delay(500); lcd.setCursor(0,0); lcd.print(N); }
Светодиод моргает через Delay(500) раз в пол секунды - но по факту проходит около 6-7 секунд !!! О_о
Хотя при этом дисплей вроде нормально работает.....
у меня atmega16 с такими фьюзами работают
попробовал :
Delay(1000) занимает примерно 11 секунд реального времени .....
попробовал вот так
Результат тотже ... вместо 100мс проходит около 1сек
Где еще порыть ....
Таймер в Wiring находится в файле wiring.c. Там есть дефайны для разных машинок, и в каком-то варианте он понижает тактовую в два раза ... или повышает. Внимательно не смотрел, ибо мне было не надо.
... но в два раза, а не 10.
Сам по себе он прост: счетчик програмируется в режим FAST-PWM с делителем на 64 от тактовой 16Мгц и инкрементирует значение счетчика переполнения таймера (там пользуется нулевой счетчик - 8-битный, счет до 255). В таком разе получаем 1024 микросекунды на переполнение. Значения для millis() считаются в нем же, соответственно не всегда "верно": millis() "периодически" (каждое 42 переполнение) отстает примерно на 2 миллисекунды и их перепрыгивает... что не позволяет корректно пользовать выражение millis() % const ... запросто можно не получить ожидаемый остаток. К сожалению "в доке" эта фича не прописана...
У вас точно проц тактирован 16 мегагерцами, а не 1.6? Просто там практически негде потерять в 10 раз.
Хотя ... у меня был похожий глюк, когда писал свой таймер. Но у меня проблема заключалась в том, что я пытался отдать точное время в micros() ... а именно через неё работает типовой delay() ... глюк заключался в том, что я не обрабатывал (как в типовом micros) ситуацию "текущее значение счетчика равно 255 и флаг прерывания выставлен, но ещё не обработан таймером" ... в результате у меня micros() регулярно заскакивал на +1020мксек, что иногда давало похожий эффект в delay() - задержки периодически считались значительно дольше...
Кварц 16MHz , тоже в начале думал что не так заводится , менял 3 раза , в послдений раз выдрал из живой схемы на Atmaga8 , в прерывания не лазил , вчера пробовал заведомо выставить в настройках 1,6 MHz а Кварц поставить 16MHz думал где то ошибка но тут все получилось еще веселее выставил задержку между включением свето диода 25сек delay(25000) , засекаю время на секундомере и вижу 38 секунд....
Пробовал так же перевести все на 8mhz результат тотже
попробуйте посчитать задержку напрямую через счетчик переполнений не используя ни delay() ни micros() ни millis(). Что получается?
Для этого: откройте wiring.c и посмотрети КАК у них называется та переменная, что просто инкрементируется в обработчике прерывания по переполнению... типа timeOvfCount ...
Сделайте себе функцию её консистентного чтения типа так:
решилось прошивкой OptiBoot !!! После записи загрузчика , и последующей прошивкой програматором проблема ушла.
за самодельный таймер спасибо попробую , я только начал выходить за базис ардуино и потихоньку изучать чистый С
Там только для Меги. Остальные машинки надо прописывать в отдельных файлах и подключать ... у меня их нет, кроме УНЫ ... но и до неё "руки не доходят". :)
Если хотите поиграться, то смотрите заголовочный файл, где прописано #error ... - это блокиратор от использования на не Мегах. :)
Решилось не прошивкой OptiBoot, а теми фьюзами которые он за собой потянул.
А Вас предупреждали!
Можете покопаться и сравнить их.
А загрузчик вообще никак не влияет на работу программы
Извените меня конечно , но мне не хватает знаний понять какие Fuse он за собой потянул, из моего скудного набора знаний я лишь понял что настройка счетчиков для Millis() и Delay() происходит при помощи Optiboot , если не затруднит не могли бы пояснить что пошло не так , и почему до этого при прошивки Atmega8a и Atmega168P-PU , без загузчика работали корректно а данный МК без него отказывался нормально работать.
Заранее благодарен.
Нет. Скорее всего потянулись базовые настройки прескалера и тактирования.
то есть при простой загрузке через програматор (без записи загрузчика) он не програмировал Fuse отвечающие за тактирование .... а только компилировал скейтч под Fuse которые указаны в Boards. я правильно понял ?
то есть при простой загрузке через програматор (без записи загрузчика) он не програмировал Fuse отвечающие за тактирование .... а только компилировал скейтч под Fuse которые указаны в Boards. я правильно понял ?
при простой загрузке чего? флеша? - да, шьётся флеш.
фьюзы шьются так:
.............Arhat109 ......базовые настройки прескалера........
У 16 меги нет отдельного фьюза CKDIV8
И только внутренний генератор можно включать на 1 2 4 8 Мгц
Клапауций 999 - спасибо за разжовавание !!!
Вывод 1 : При варианте заливке скейча в МК через програматор он по умолчанию не трогает Fuse
Вывод 2 : Fuse выставляются через параметр avrdude или "записать загрузчик"
но остался все равно не понятным тот факт что с коробки вытащенные Меги 8 и 168P шились простой загрузкой во флеш через Файл-> Загрузить с помощью программатора и все ОК , а mega16а потребоволось отдельно прошивать Fuse так как решением было залить OptiBoot дописав его в Boards и потом через Сервис->Записать загрузчик после чего она начала норально работать .
как связан BootLoader и Fuse ?
И почему 8 и 168P работают на 16MHz с коробки если в них залить скейч через програматор без загрузчика/параметров avrdude
P.S Сильно не пинайте правда не получается разобраться , если в чем то мои выводы не верны прокоментируйте.
кароче, что бы не впадать в ересь и на основе полученных, непонятных вам результатов и не начинать строить храмы новым богам:
Arduino IDE представляет из себя сборку из интерпретатора языка Wiring , компилятора исходного кода в машинный код AVR GCC , консольного прошивальщика всего, что можно записать в контроллер avrdude , встроенного текстового редактора и прочих плюшек.
как это работает?:
вы пишете код, жмёте кнопку "загрузить", код компилируется, затем передаётся прошивальщику для записи в железо контроллера - всё!
т.е.если чего-то не произошло - значит, вы этого не сделали или сделали не то или не так.
по сути вопросов:
Вывод 1 : При варианте заливке скейча в МК через програматор он по умолчанию не трогает Fuse
*скетча
при заливке скетча код пишется в область флеш контроллера - перечислять всё, чего не делает программатор, нет смысла.
Вывод 2 : Fuse выставляются через параметр avrdude или "записать загрузчик"
avrdude - софт для непосредсвенной работы с контроллером.
доступны опции чтения и записи в области eprom, eeprom и fuse.
во время записи загрузчика так же конфигуриуются и фьюзы.
но остался все равно не понятным тот факт что с коробки вытащенные Меги 8 и 168P шились простой загрузкой во флеш через Файл-> Загрузить с помощью программатора и все ОК , а mega16а потребоволось отдельно прошивать Fuse так как решением было залить OptiBoot дописав его в Boards и потом через Сервис->Записать загрузчик после чего она начала норально работать .
прекратите употреблять слово "факт" во время неосознанных телодвижений.
как связан BootLoader и Fuse ?
в контексте сабжа - Дуино ИДЕ при прошивке загрузчика конфигурирует фьюзы.
а, по сути - никак.
И почему 8 и 168P работают на 16MHz с коробки если в них залить скейч через програматор без загрузчика/параметров avrdude
это есть еретическое утверждение и за его публикацию, вы наказываетесь штудированием гугла с поисковым запросом "AVR заводские настройки".
т.к.
ATmega8 заводские настройки внутренний RC генератор на 1.0МГц
ATmega48/88/168 заводские настройки внутренний RC генератор на 1.0МГц
светодиод моргает через Delay(500) раз в пол секунды - но по факту проходит около 6-7 секунд !!! О_о
по факту было 8 секунд = (16МГц/1МГц)*0,5сек
*расходимся - нас обманули, чюда не было, это была не божья слеза, а поп чихнул на икону.
Спасибо за развернутый ответ !
Многое расставили по своим местам