Обычно вы выясняете, сколько тактов вам нужно сжечь, а затем пишете цикл. Обратитесь к своей таблице данных, чтобы определить, сколько циклов занимает ваш цикл, и рассчитайте, сколько итераций вам нужно.
ldi r16, x ; 1 cycle
loop: nop ; 1 cycle
dec r16 ; 1 cycle
brne loop1 ; 2 cycles when jumping, 1 otherwise
В зависимости от значения x
этот цикл займет x * 4
циклов. С платой 16 МГц 1 мс составляет 16000 циклов, поэтому 5 мс будет 80000 циклов. Это больше, чем может выдержать этот 8-битный цикл, поэтому нам нужно сделать 16-битный счетчик.
ldi r16, x ; 1 cycle
ldi r17, y ; 1 cycle
loop: nop ; 1 cycle
dec r16 ; 1 cycle
brne skip ; 2 cycles when jumping, 1 otherwise
dec r17 ; 1 cycle
skip: brne loop ; 2 cycles when jumping, 1 otherwise
Итак, наше тело цикла теперь занимает 6 циклов на итерацию. Обратите внимание, что это 6 циклов, независимо от того, переносится ли r16
или нет. Настройка занимает 2 такта, но последнее brne
возвращает нам 1 цикл назад, поэтому мы получили 1 цикл накладных расходов. Это означает, что нам нужно 79999 циклов, что составляет 13333 итерации и еще один цикл впустую. Таким образом, x=low(13333)=21
и y=high(13333)=52
и добавить nop
.
Это общая идея, надеюсь, я ничего не просчитал. Если вы собираетесь использовать это как функцию, учитывайте накладные расходы на вызов и возврат. Кроме того, вы можете сделать его параметризованным.
person
Jester
schedule
05.05.2014