.def _PvEnc = r14 ; предыдущие данные с энкодера .def _PvDir = r13 ; предыдущее направление с энкодера .def _PosH = r12 ; 24-bit счетчик текущего положения .def _PosM = r11 ; .def _PosL = r10 ; =================================================== ; ********* Таблица перехода от прерываний ********** RJMP INT_Encoder ; External Interrupt Request 0 ;--------------------------------------------------------------------------------------------------------------------------------- ; ************** Настройка прерывания от INT0 ************* ldi r16,0b00000001 ; INT0 по любому изменению (Encoder) sts EICRA, r16 ; ldi r16,0b00000001 ; разрешить прерывания от INT0 (B_Int Encoder) out EIMSK, r16 ; ;------------------------------------------------------------------------------------------------------------------------------- ;=========================================================== ; Обработчик прерывания от INT0 - Опрос энкодера ;=========================================================== INT_Encoder: cli push r0 push r16 push zl push zh in r0, SREG mov zl, _PvEnc ; старое состояние zl[1:0] clr r16 ; Проверить состояние sbic PINC,3 ; входов энкодера (РС3=А, PD2=B_Int) sbr r16,(1<<1) ; и установить соответсвующие sbic PIND,2 ; биты (А=1, B_Int=0) в sbr r16,(1<<0) ; регистре _PvEnc mov _PvEnc,r16 ; sub zl, _PvEnc ; Decode motion (zl = zl - _PvEnc) andi zl, 3 ; zl = zl and b11 breq enc_ext ; 00 - нет движения cpi zl, 1 breq enc_inc ; 01 - движение вправо cpi zl, 3 breq enc_dec ; 11 - движение влево ; 10 - неопределено mov zl, _PvDir mov zh, _PvDir ; Count by 2 for previous direction lsl zl ; zl=zl shl 1, bit0 cleared asr zh ; zh=zh shr 1, bit7=const, bit0 -> carry flag rjmp enc_add enc_dec: ldi zl, low(-1) ldi zh, high(-1) rjmp enc_setpvdir enc_inc: ldi zl, low(1) ldi zh, high(1) enc_setpvdir: mov _PvDir, zl enc_add: add _PosL, zl ; новая позиция adc _PosM, zh adc _PosH, zh enc_ext: out SREG, r0 pop zh pop zl pop r16 pop r0 sei reti