Comments 19
UFO just landed and posted this here
UFO just landed and posted this here
Как сказать…
Например, вместо того, что-бы получить увеличение периода до 2 сек (Сейчас светодиод будет зажигаться и гаснуть ровно на одну секунду) записью в TCTNT1 соответствующего значения (0x10000 — F_CPU(Гц)*1(сек)/1024 = 0xC2F7, что вызовет переполнение за меньшее время) зачем-то используется режим CTC.
Например, вместо того, что-бы получить увеличение периода до 2 сек (Сейчас светодиод будет зажигаться и гаснуть ровно на одну секунду) записью в TCTNT1 соответствующего значения (0x10000 — F_CPU(Гц)*1(сек)/1024 = 0xC2F7, что вызовет переполнение за меньшее время) зачем-то используется режим CTC.
UFO just landed and posted this here
Пока в прерывание попадете,
Вполне детерминированное время. ЕМНИП, 2..3 такта на переход к таблице и 2..3 такта на [R]JMP из таблицы.
Раз уж заходите с козырей — добавьте конкретики. Какой джиттер считаете неприемлемым для периода 2 сек.?
Считая вызов и пролог ISR примерно 30 тактов (называю по памяти для WinAVR) — ошибка получится 0,0001875 % для указанных в статье тактовой частоты 16 МГц и выходного периода 2 сек.
А если нужно ваще-точно — никто не мешает писать ISR на ассемблере и корректировать константу таймера на число тактов вызова и пролога (если, конечно, эта поправка не будет «съедена» предделителем). А можно скатиться до dithering и прочей паранойи.
Статья должна называться «ATMEGA32 и прерывания таймера» ;) От ардуины тут только digitalWrite.
Вызывать в прерывании readSensor() вообще не хорошая идея да и вообще не инлайн функции… Это может занять офигенно большое время плюс фиг его знает, что там в этой фукнции еще вызывается.
UFO just landed and posted this here
Я как-то осваивал arduino и делал часы на самодельных 7-сегментниках. С регулировкой яркости. Яркость изменял как раз используя самодельный ШИМ на таймере2 (arduino nano). По совпадению включал разряд, по переполнению выключал.
Подсмотрел код в похожем проекте из интернета и «настроил» таймер вот так:
Код, который я брал за основу был на С++ но не использовал фреймворк ардуино. То есть никаких setup'ов и loop'ов. Он был очень похож на тот, что в статье, но в нём отсутствовала первая часть, где обнуление регистров.
Измерил частоту осциллографом. Получил ~245 Гц. С предделителем 0 — ~490Гц. Методом «тыка» дошёл до того, что нужно обнулить регистры!
Ещё немного поэкспериментировал и получил такое:
Мне так проще воспринимать. Я открыл даташит и смотрю в регистры, как они там написаны. Вижу, где стоят «единички» и что они означают. И места меньше занимает.
Подсмотрел код в похожем проекте из интернета и «настроил» таймер вот так:
void setup() {
TCCR2A |= (1 << WGM20)|(1 << WGM21); // Установка режима Fast PWM (WGM20 и WGM21)
TCCR2B |= (1 << CS21); // Установка предделителя на 8 (CS21)
TIMSK2 |= (1 << TOIE2)|(1 << OCIE2A); // Разрешение прерываний по переполнению (TOIE) и по совпадению (OCR2A)
OCR2A = 1; // Начальное значение по совпадению
sei();
}
Код, который я брал за основу был на С++ но не использовал фреймворк ардуино. То есть никаких setup'ов и loop'ов. Он был очень похож на тот, что в статье, но в нём отсутствовала первая часть, где обнуление регистров.
Измерил частоту осциллографом. Получил ~245 Гц. С предделителем 0 — ~490Гц. Методом «тыка» дошёл до того, что нужно обнулить регистры!
Ещё немного поэкспериментировал и получил такое:
TCCR2A = 0b00000011; // waveform generation mode (fast PWM)
TCCR2B = 0b00000100; // prescaler (*100 => 64, ~970 Hz)
TIMSK2 = 0b00000011; // interrupts (0 => compare B; 1 => compare A; 1 => overflow)
OCR2A = 1; // compare
Мне так проще воспринимать. Я открыл даташит и смотрю в регистры, как они там написаны. Вижу, где стоят «единички» и что они означают. И места меньше занимает.
а мне не понятна сама суть затеи, если человек понимает начинку и может писать на WinAVR, то зачем Arduino код, зачем смешивать, не проще написать какую то сложную вещь чисто на AtmelStudio, а простые вещи, ну или просто поиграться для экономии времени писать на Arduino?
Sign up to leave a comment.
Arduino и прерывания таймера