- Код: Выделить всё
.include "tn15def.inc"
;Interrupt vector table
rjmp init
;* Объявление переменных
.def t1 = r19 ;счетчик времени задержки
;* Задание значений
.equ LOW = 80 ;короткий импульс
.equ MED = 150 ;средний импульс
.equ HIGH = 220 ;длинный импульс
;* Определения
.equ serv0 = PB1 ;серв0 на PB1
.org T0OVaddr ; Вектор прерывания по переполнению таймера0
rjmp start_pwm
;Main code
init:
; Установка таймера
; The Timer/Counter0 Control Register ? TCCR0
ldi r16, (1<<CS02) ; Установка timer0
out TCCR0, r16 ; CK/256 = 3906.25Гц = 0.000256 сек
; The Timer Counter 0 ? TCNT0
ldi r16, 0xB2 ; Загружаем счётчик числом 0xB2
out TCNT0, r16 ; получая переполнение каждые 20.032мс
; Output Compare Interrupt of Timer0
ldi r16,1<<TOIE0 ; Разрешение прерывания
out TIMSK,r16 ; по переполнению таймера0
; Установка ног
ldi r16, (1<<PB1) ; Устанавливаем ногу PB1 как выход
out DDRB, r16
sei ; Разрешение глобальных прерываний
idle: ; основной цикл
;-------- можно использовать сон когда ничего не делаем --
; ldi r16, (1<<SE) ; Enable sleep
; out MCUCR, r16
; sleep
;----------------------------------------------------------
NOP ; или отработку пустого цикла или других задач
rjmp idle
start_pwm:
; Установка таймера
; The Timer/Counter0 Control Register ? TCCR0
ldi r16, (1<<CS02) ; Установка timer0
out TCCR0, r16 ; CK/256 = 3906.25Гц = 0.000256 сек
; The Timer/Counter Interrupt Flag Register ? TIFR
ldi r16,1<<TOV0 ; Видимо признак обработанного прерывания, не знаю нужен ли
out TIFR,r16 ; Clear TOV0/ clear pending interrupts
; The Timer Counter 0 ? TCNT0
ldi r16, 0xB2 ; Загружаем счётчик числом 0xB2
out TCNT0, r16 ; получая переполнение каждые 20.032мс
; Output Compare Interrupt of Timer0
ldi r16,1<<TOIE0 ; Разрешение прерывания
out TIMSK,r16 ; по переполнению таймера0
; Пауза 1цикл=0.001мс , для управления сервом нужна задержка от 800 до 2200 циклов
; что равняется 0.8мс и 2.2мс соответственно
sbi PORTB, serv0 ;запускаем импульс
ldi t1, MED ;установка длительности задержки, собственно это значение
;и задаёт положение вала.
Delay:
NOP
NOP
NOP
NOP
NOP
NOP
NOP
dec t1 ;задержка по счетчику от t1 до 0
brne Delay ;т.е. t1*10 тактов
cbi PORTB, serv0 ;гасим импульc
reti
P.S. Здесь в примечаниях в принципе всё понятно, чуть позже оформлю в виде готовой обучающей статьи.
P.P.S ещё была версия с управлением сервы от 2х кнопочек право/лево, как найду выложу. Следующим логическим шагом приём значения положения вала по rs232 или i2с , до этого пока руки не дошли.