Таймеры , кварцы , или почему оно не работает ))

XTDoctor
Offline
Зарегистрирован: 07.07.2015

Помогите разобраться с маленьким девайсом на 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 секунд !!! О_о

Хотя при этом дисплей вроде нормально работает.....

 

 

 

 

 

 

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

у меня atmega16 с такими фьюзами работают

hfuse:0xc0
lfuse:0x9f
не помню, в чём выражался глюк, но фейс JTAG нужно было отключить - у тебя он включен. проверь.
 
XTDoctor
Offline
Зарегистрирован: 07.07.2015

попробовал :

##############################################################
atmega16-8.name=Atmega16 (ext 16 MHz ST edit)
 
atmega16-8.upload.protocol=stk500v1
atmega16-8.upload.maximum_size=14336
atmega16-8.upload.speed=19200
 
atmega16-8.bootloader.low_fuses=9F
atmega16-8.bootloader.high_fuses=0xC0
 
atmega16-8.build.mcu=atmega16
atmega16-8.build.f_cpu=16000000L
atmega16-8.build.core=arduino:arduino
atmega16-8.build.variant=mega16
 
##############################################################

  Delay(1000) занимает примерно 11 секунд реального времени .....    

 

попробовал вот так 

  
if(millis()- start> 100){
   if(LED){ digitalWrite(Lpin, HIGH);}
      else{digitalWrite(Lpin,LOW);}
      LED= !LED;
  start=millis();
} 

Результат тотже ... вместо 100мс  проходит около 1сек

 

Где еще порыть ....

Arhat109
Offline
Зарегистрирован: 26.05.2015

Таймер в 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() - задержки периодически считались значительно дольше...

XTDoctor
Offline
Зарегистрирован: 07.07.2015

Кварц 16MHz , тоже в начале думал что не так заводится , менял 3 раза , в послдений раз выдрал из живой схемы на Atmaga8 , в прерывания не лазил , вчера пробовал заведомо выставить в настройках 1,6 MHz а Кварц поставить 16MHz думал где то ошибка но тут все получилось еще веселее выставил задержку между включением свето диода 25сек delay(25000) , засекаю время на секундомере и вижу 38 секунд.... 

Пробовал так же перевести все на 8mhz результат тотже

Arhat109
Offline
Зарегистрирован: 26.05.2015

попробуйте посчитать задержку напрямую через счетчик переполнений не используя ни delay() ни micros() ни millis(). Что получается?

Для этого: откройте wiring.c и посмотрети КАК у них называется та переменная, что просто инкрементируется в обработчике прерывания по переполнению... типа timeOvfCount ...

Сделайте себе функцию её консистентного чтения типа так:

uint32_t     getOvfCount(){
    uint8_t      sReg = SREG;
    uint32_t   res;

    cli();
    res = ... имя счетчика;
    SREG = sReg;

    return res;
}
XTDoctor
Offline
Зарегистрирован: 07.07.2015

решилось  прошивкой OptiBoot !!! После записи загрузчика , и последующей прошивкой програматором проблема ушла.

 за самодельный таймер спасибо попробую , я только начал выходить за базис ардуино и потихоньку изучать чистый С

Arhat109
Offline
Зарегистрирован: 26.05.2015

Там только для Меги. Остальные машинки надо прописывать в отдельных файлах и подключать ... у меня их нет, кроме УНЫ ... но и до неё "руки не доходят". :)

Если хотите поиграться, то смотрите заголовочный файл, где прописано #error ... - это блокиратор от использования на не Мегах. :)

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Решилось не прошивкой OptiBoot, а теми фьюзами которые он за собой потянул.
А Вас предупреждали!
Можете покопаться и сравнить их.
А загрузчик вообще никак не влияет на работу программы

XTDoctor
Offline
Зарегистрирован: 07.07.2015

Извените меня конечно , но мне не хватает знаний понять какие Fuse он за собой потянул, из моего скудного набора знаний я лишь понял что настройка  счетчиков для Millis() и Delay() происходит при помощи Optiboot , если не затруднит не могли бы пояснить что пошло не так , и почему до этого при прошивки Atmega8a и Atmega168P-PU , без загузчика работали корректно а данный МК без него отказывался нормально работать.

Заранее благодарен.

Arhat109
Offline
Зарегистрирован: 26.05.2015

Нет. Скорее всего потянулись базовые настройки прескалера и тактирования.

XTDoctor
Offline
Зарегистрирован: 07.07.2015

то есть  при простой загрузке через програматор (без записи загрузчика) он не програмировал Fuse  отвечающие за тактирование ....   а только компилировал скейтч под Fuse которые указаны в Boards.  я правильно понял  ?

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

XTDoctor пишет:

то есть  при простой загрузке через програматор (без записи загрузчика) он не програмировал Fuse  отвечающие за тактирование ....   а только компилировал скейтч под Fuse которые указаны в Boards.  я правильно понял  ?

при простой загрузке чего? флеша? - да, шьётся флеш.

фьюзы шьются так:

avrdude -p atmega16 -c USBasp -U hfuse:w:0xc0:m -U lfuse:w:0x9f:m

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

.............Arhat109  ......базовые настройки прескалера........

У 16 меги нет отдельного фьюза CKDIV8
И только внутренний генератор  можно включать на    1   2  4   8  Мгц

XTDoctor
Offline
Зарегистрирован: 07.07.2015

Клапауций 999 - спасибо  за разжовавание !!!

Вывод 1 : При варианте заливке скейча в МК через програматор он по умолчанию не трогает Fuse

Вывод 2 : Fuse выставляются через параметр avrdude или "записать загрузчик"

но остался все равно не понятным тот факт что с коробки вытащенные Меги 8 и 168P шились простой загрузкой во флеш  через  Файл-> Загрузить с помощью программатора и все ОК   , а  mega16а потребоволось отдельно прошивать Fuse так как решением было залить OptiBoot дописав его в  Boards  и потом   через Сервис->Записать загрузчик  после чего она начала норально работать .

 как связан BootLoader и Fuse ?

И почему 8 и 168P работают на 16MHz с коробки если в них залить скейч через програматор  без загрузчика/параметров avrdude

P.S Сильно не пинайте правда не получается разобраться , если в чем то мои выводы не верны прокоментируйте.

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

кароче, что бы не впадать в ересь и на основе полученных, непонятных вам результатов и не начинать строить храмы новым богам:

Arduino IDE представляет из себя сборку из интерпретатора языка Wiring , компилятора исходного кода в машинный код AVR GCC , консольного прошивальщика всего, что можно записать в контроллер avrdude , встроенного текстового редактора и прочих плюшек.

как это работает?:

вы пишете код, жмёте кнопку "загрузить", код компилируется, затем передаётся прошивальщику для записи в железо контроллера - всё!

т.е.если чего-то не произошло - значит, вы этого не сделали или сделали не то или не так.

 

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

по сути вопросов:

XTDoctor пишет:

Вывод 1 : При варианте заливке скейча в МК через програматор он по умолчанию не трогает Fuse

*скетча

при заливке скетча код пишется в область флеш контроллера - перечислять всё, чего не делает программатор, нет смысла.

XTDoctor пишет:

Вывод 2 : Fuse выставляются через параметр avrdude или "записать загрузчик"

avrdude - софт для непосредсвенной работы с контроллером.

доступны опции чтения и записи в области eprom, eeprom и fuse.

во время записи загрузчика так же конфигуриуются и фьюзы.

XTDoctor пишет:

но остался все равно не понятным тот факт что с коробки вытащенные Меги 8 и 168P шились простой загрузкой во флеш  через  Файл-> Загрузить с помощью программатора и все ОК   , а  mega16а потребоволось отдельно прошивать Fuse так как решением было залить OptiBoot дописав его в  Boards  и потом   через Сервис->Записать загрузчик  после чего она начала норально работать .

прекратите употреблять слово "факт" во время неосознанных телодвижений.

XTDoctor пишет:

как связан BootLoader и Fuse ?

в контексте сабжа - Дуино ИДЕ при прошивке загрузчика конфигурирует фьюзы.

а, по сути - никак.

XTDoctor пишет:

И почему 8 и 168P работают на 16MHz с коробки если в них залить скейч через програматор  без загрузчика/параметров avrdude

это есть еретическое утверждение и за его публикацию, вы наказываетесь штудированием гугла с поисковым запросом "AVR заводские настройки".

т.к.

ATmega8 заводские настройки внутренний RC генератор на 1.0МГц

ATmega48/88/168 заводские настройки внутренний RC генератор на 1.0МГц

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

XTDoctor пишет:

светодиод моргает через Delay(500) раз в пол секунды - но по факту проходит около 6-7 секунд !!! О_о

по факту было 8 секунд = (16МГц/1МГц)*0,5сек

*расходимся - нас обманули, чюда не было, это была не божья слеза, а поп чихнул на икону.

 

XTDoctor
Offline
Зарегистрирован: 07.07.2015

Спасибо за развернутый ответ ! 

Многое расставили по своим местам