Как релизовать задержку времени на секунды, миллисекунды, микросекунды на attiny13a
Для полного понимания как задать задержку времени в любых микроконтроллерах необходимо четко уяснить сколько в одной секунде миллисекунд, а в одной миллисекунде сколько микросекунд. Поэтому смотрим для начала таблицу и запоминаем как она выглядит.
Таблица 1. Зависимость частоты от времени одного полного колебания.
Частота | Время | Коментарий |
1 Герц (Hz) | 1 секунда (s) | Одно полное колебание за секунду |
1 Килогерц (kHz) | 1 миллисекунда (ms) | В одной секунде 1000 миллисекунд |
1 Мегагерц (mHz) | 1 микросекунда (us) | В одной миллескунде 1000 микросекунд |
Как организовать задержу на 0,5 секунд в микроконтроллере attiny13?
1. Нам нужна частота, на которой работает микроконтроллер, для простоты возьмем 1 Мегагерц (миллион операций в секунду), тогда делаем константу
F_CPU = 1000000;
2. Возьмем заданное количество секунд, 0,5 с. для того чтобы вычислить глубину задержки умножить на секунды.
delayTime = F_CPU * 0,5;
// delayTime = 500000;
3. Оценка памяти, в которое можно запихнуть предыдущее константное число
1 байт занимают числа от 255, 2 байта занимают числа от 65 536, пролетаем и тут, в три байта 16 777 216, то что нужно!
Так как 500 000 < 16 777 216, то нам нужно 3 байтовый счетчик
4. Составляем программу на ассемблере
.include "tn13Adef.inc"
.equ Z_CPU=1000000
.cseg
.org 0x00
ldi r16,(1<<PINB0) ; load 00000001 into register 16
out DDRB, r16 ; write register 16 to DDRB
out PORTB, r16 ; write register 16 to PORTB
; Настройка стека (онли attiny13)
ldi r16,LOW(RAMEND)
out SPL,r16
; END настройка стека
loop:
rcall delay05s
; Сделать регистр пустым и записать в порт
clr r16
out PORTB, r16
rcall delay05s
; Сделать ругистр полным и записать в порт
ser r16
out PORTB, r16
rjmp loop ; stay in infinite loop
delay05s:
; 500 000 делим на количество тактов (на 5 тактов задержки) и получаем 100 000 в десятичной системе
; Переводим 100 000 в hex 1 86 A0 и загружаем в памят
ldi r16, 0xA0
ldi r17, 0x86
ldi r20, 0x01
ldi r18, 1
ldi r19, 0
subCount:
sub r16, r18 ; минус старший разряд
sbc r17, r19 ;
sbc r20, r19 ;
brne subCount
ret
Как организовать задержку на 20 миллисекунд на микроконтроллере attiny13?
1. Все нижесказанное актуально для частоты attiny13 1 мегагерц (Z_CPU=1000000)
2. Возьмем заданное количество миллисекунд в тактах, это 20 000 тактов.
3. Оценка памяти, в которое можно запихнуть предыдущее константное число
1 байт занимают числа от 0 до 255, 2 байта занимают числа от 65 536, то что нужно!
Так как 20 000 < 65 536, то нам нужно 2 байтовый счетчик
4. Составляем программу на ассемблере
.include "tn13Adef.inc"
.equ Z_CPU=1000000
.equ ms20delay=(20000/4) ; 4 это 4 инструкции выполняется задержка
.cseg
.org 0x00
ldi r16,(1<<PINB0) ; load 00000001 into register 16
out DDRB, r16 ; write register 16 to DDRB
out PORTB, r16 ; write register 16 to PORTB
; Настройка стека (онли attiny13)
ldi r16,LOW(RAMEND)
out SPL,r16
; END настройка стека
loop:
rcall delay20ms
; Сделать регистр пустым и записать в порт
clr r16
out PORTB, r16
rcall delay20ms
; Сделать ругистр полным и записать в порт
ser r16
out PORTB, r16
rjmp loop ; stay in infinite loop
delay20ms:
; если там че-то было то сохраним, а потом восстановим
mov r0, r16
mov r1, r17
mov r2, r18
mov r3, r19
;
ldi r16, low(ms20delay)
ldi r17, high(ms20delay)
ldi r18, 1
ldi r19, 0
;
subCount:
sub r16, r18
sbc r17, r19 ; есть sbci с переносом за 1 такт
brne subCount
ret
Как организовать задержку 5 микросекунд на микроконтроллере avr attiny13a?
1. Все нижесказанное так же актуально для частоты attiny13 1 мегагерц (Z_CPU=1000000)
2. Программа выполняется на принципе использования оператора NOP которая ничего не делает 1 такт
3. Проверим в симуляторе программу ниже. Вышило примерно 5 пульсаций за 50 микросекунд.
Делим 50 / 5 = 10. Это значит что у нас произошло 10 задержек, что и требовалось. Так как команды в теле цикла loop выполняются за один такт, кроме rjmp, она за два такта выполняется.
.include "tn13Adef.inc"
.cseg
.org 0x00
ldi r16,(1<<PINB0)
out DDRB,r16
out PORTB,r16
loop:
nop
clr r16
out PORTB,r16
; 5 микросекундный цикл
nop
nop
nop
ser r16
out PORTB,r16
; 5 микросекундный цикл
rjmp loop
Вывод, какой промежуток можно задавать с помощью примеров выше?
С помощью этих трех программ можно задавать задержку для получения меандра от 4 микросекунд до 17 секунд с минимальной модификацией. После того как добавить еще 4тый бит в программе задержки секунд, можно будет делать задержки до 70 минут и выше, чисто теоретически добавить в цикл задержки 5 nop инструкций выростет задержка до двух часов без добавления еще одного регистра.