Реалізація Затримки в AVR assembler без таймерів

Крок за кроком

Натхненний своєю ідеєю, звичайно ж, відразу кинувся в бій, особливо нічого не продумуючи, вирішив відразу відміряти в мілісекундах. Код був успішно написаний,

Для розробки використовую AVR Studio 4+gcc, відповідно і тестував код теж там. Результат після налагодження:

assembler

… .equ F_CPU = 8000000; Частота Гц … DELAY_MS 4, F_CPU; підстановка макросу для 4 мс …

Занадто велика похибка, що зростає зі збільшенням величини затримки, прямо вдарила по оці, оптимізувати написане стало більше неможливо. Вирішив піти по порядку, написати спочатку лічильник Циклів для 1 байта, 2 байтів, і вже після, склеївши все це, отримати затримку в мілісекундах.

Результатом стало 3 макроси:

Цикли у відповідних діапазонах вважається точно.

Результати цього коду успішніші:

Для 1 мс (Atmega8535, F_CPU = 8001000 Hz)

assembler
Для 300мс (Atmega8535, F_CPU = 8001000 Hz)
assembler
Для 32с (Atmega8535, F_C 7>
затримки
Для 300мс (Atmega6490, F_CPU = 4000000 Hz)
реалізація
Для 300мс (ATtiny43U, F_CPU = 2000000 Hz)
затримки

Похибка лежить у діапазоні

4-150 мікросекунд. Цього цілком достатньо. Хотів би змінити макрос DELAY_MS на підпрограму (логічно, вбудовувати при кожному виклику стільки коду не розумно), але з асемблером копирсаюся 2 тижня, і поки не зрозумів, як винести все це в окремий модуль, і зробити функцію в ньому відповідну.

А у нас тут можна отримати грант на тестовий період Яндекс.Хмари. Варто лише у полі «секретний пароль» запровадити «Хабр»