Создайте задержку в Arduino Uno с помощью языка ассемблера без использования таймера

Я только начал изучать микроконтроллеры и не мог понять, как можно вводить задержки в код без использования таймеров. Моя плата имеет часы 16 МГц. Допустим, я хочу ввести задержку в 5 мс, прежде чем я проверю, нажата ли кнопка. Как мне определить, сколько инструкций мне нужно выполнить, чтобы получить задержку в 5 мс, и как мне ее запрограммировать? Есть ли стандартизированный способ сделать это? Это выглядит очень стандартно, но я не могу понять, как это делается.

Я программирую на языке ассемблера на Atmega 328 Arduino uno.


person user3605100    schedule 05.05.2014    source источник


Ответы (1)


Обычно вы выясняете, сколько тактов вам нужно сжечь, а затем пишете цикл. Обратитесь к своей таблице данных, чтобы определить, сколько циклов занимает ваш цикл, и рассчитайте, сколько итераций вам нужно.

       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