attiny13 и millis()

Тема в разделе "Микроконтроллеры AVR", создана пользователем DrProg, 17 авг 2015.

  1. Unixon

    Unixon Оракул Модератор

    А кто тогда время то вам отсчитывать будет? Где код функции millis(), которой вы пользуетесь? Где и как формируется величина, которую она возвращает?

    8-битный таймер переполнится через 256*prescaler тактов, по прерыванию нужно отсчитывать количество переполнений и переводить его в микро-/миллисекунды. Где код, который это делает?
     
  2. DrProg

    DrProg Вечный нерд

    Функция millis() библиотечная ардуиновская, возвращает кол-во миллисекунд прошедших с начала запуска МК. Работа с ней не ранее вызывала проблем , не вызвала бы и сейчас, заполняйся переменная типа long на tiny13 правильно, чего она не делает. В этой связи я использую не полное кол-во миллисекунд, а остаток от их деления на 60000 (чтобы гарантированно уложиться в unsigned int).

    Понимаю, что можно использовать функцию прерывания по таймеру, но во первых я с этим еще не до конца разобрался, хочу сначала понять как оно работает а не просто копировать примеры (которых, кстати, еще поискать), а во-вторых единственный таймер мне в перспективе понадобится для ШИМ, который навреное будет конфликтовать с прерыванием по нему же.

    То что программа делает в цикле не так уж сильно нагружает МК, гораздо больше его грузит функция динамического вывода инфо на регистры, но этого не избежать при такой схеме подключения индикаторов. Кроме этого происходит несколько сравнений (или одно, если кроме секунд менять нечего), машинное время дешево, а нагрузка не так уж велика.

    Единственной явной выгодой от прерываний по таймеру могло бы стать, возможно, сокращение объема hex, но для того что есть памяти хватает, а для дополнительных функций все равно не хватит, проще купить tiny85 например.

    Но прерывания по таймеру освоить надо, тут я согласен полностью. В конце концов даже псевдо ватч дог можно сделать, если бутлоадер обычного не понимает.

     
    Последнее редактирование: 18 авг 2015
    ИгорьК нравится это.
  3. Unixon

    Unixon Оракул Модератор

    Загляните в код библиотеки (файл wiring.c) и поймите откуда millis берет свои миллисекунды, зачем там таймер с прерываниями, и откуда возникают проблемы со временем, если потрогать этот таймер.
     
    DrProg нравится это.
  4. DrProg

    DrProg Вечный нерд

    Примерно представляю, что берет из регистра TCNT0, если таймер первый, TCNT1 - второй (если есть) и так далее. Даже знаю про регистр который регулируют скорость тикания и источник тактов, а так же регистр обработки прерываний (самый пока что мутный для меня). Это все очень важно и нужно, но в данном случае мало связано с темой этого поста. Тут проблема была не в задании прерывания с таймера, а с неправильным представлением переменной типа long, которая ведет себя очень странно, то есть значение попадающее в такую переменную портится и становится, можно сказать, случайным. Причину этого мы так и не выяснили даже совместными усилиями.

    За подпинывание в сторону изучения таймеров спасибо, форсирую. Особенно буду признателен за ссылки на человеческом языке которые толкуют как пользоваться регистром OCR0.
     
    ИгорьК нравится это.
  5. Unixon

    Unixon Оракул Модератор

    Т.е. если вы запишете цикл с переменной long, то он не выполнится корректно?
    Или речь о том, что значение, возвращаемое millis(), ведет себя нерегулярно?

    p.s. millis() возвращает unsigned long (тоже что uint32_t), нужно использовать именно этот тип.
     
  6. DrProg

    DrProg Вечный нерд

    millis() ведет себя хорошо (что доказано его работой с переменными int), виновата переменная long, в которой данные сохраняются не верно.
     
    ИгорьК нравится это.
  7. Unixon

    Unixon Оракул Модератор

    Можете привести пример вывода (значение millis(), значение переменной типа long, в которую оно записано) ?
     
  8. DrProg

    DrProg Вечный нерд

    Как вывести значение? Serial на tiny13 не поддерживается. Я вижу некорректную работу по результату, вместо того чтобы обрабатывать таймеры как это делается на Меге или Уно, Тиня оперирует случайными числами, то есть часть равных периодов проскакивает мгновенно, на других зависает насмерть. Это можно проверить на моем же скетче заменив unsigned int timerSekond; на long timerSekond; в первом случае все работает как положено (часы тикают с 20 до 0), во втором они зависают на положении 17, проскочив предыдущие за доли секунды, что говорит о некорректности long переменной.
     
    ИгорьК нравится это.
  9. Unixon

    Unixon Оракул Модератор

    По паре проводов на дисплей или на ардуину.

    А макрос F_CPU у вас правильный, виртуальная частота соответствует реальной?
     
  10. DrProg

    DrProg Вечный нерд

    Скорее всего да. Я генерю код для частоты 1,2 МГц, millis() таймера выдает верные значения. Когда попробовал сгенерить на 4,8МГц паузы были дольше в 4 раза от нормального.
     
    ИгорьК нравится это.