;=======================================================
; Проект 43. Управление сервоприводом SG90
; PIC16F84A, 4 МГц. Сигнальный провод серво — RB0
; Период 20 мс, импульс 1..2 мс задаёт угол 0..180 град.
; Кнопки RA0 (влево) и RA1 (вправо)
;=======================================================
        LIST    p=16F84A
        #include <p16f84a.inc>
        __CONFIG _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF

        cblock  0x0C
        d1, d2, pos, cnt
        endc

        ORG     0x000
        goto    Start

Start
        bsf     STATUS,RP0
        clrf    TRISB           ; RB0 — выход на серво
        movlw   b'00011111'
        movwf   TRISA           ; кнопки — входы
        bcf     STATUS,RP0
        movlw   .150            ; середина диапазона (1,5 мс)
        movwf   pos

Main
        call    ServoPulse      ; один импульс управления
        call    Delay20ms       ; пауза до следующего периода
        call    CheckKeys
        goto    Main

;--- импульс длительностью pos*10 мкс ---
ServoPulse
        bsf     PORTB,0
        movf    pos,w
        movwf   cnt
PLoop
        call    Delay10us
        decfsz  cnt,f
        goto    PLoop
        bcf     PORTB,0
        return

CheckKeys
        btfss   PORTA,0         ; уменьшить угол
        goto    PosDown
        btfss   PORTA,1         ; увеличить угол
        goto    PosUp
        return
PosDown
        movlw   .100            ; нижний предел (1,0 мс)
        subwf   pos,w
        btfsc   STATUS,C
        decf    pos,f
        return
PosUp
        movlw   .200            ; верхний предел (2,0 мс)
        subwf   pos,w
        btfss   STATUS,C
        incf    pos,f
        return

Delay10us
        movlw   .2
        movwf   d1
X10     nop
        decfsz  d1,f
        goto    X10
        return

Delay20ms
        movlw   .40
        movwf   d1
Y1      movlw   .165
        movwf   d2
Y2      nop
        decfsz  d2,f
        goto    Y2
        decfsz  d1,f
        goto    Y1
        return

        END
