[an error occurred while processing this directive]
|
[pre]
;----------------------------------------------------------------------------
.include "m8def.inc"
.include "macros.mac"
.include "Header.asm"
;------------------------- Interrupt Vectors: -------------------------------
.CSEG ;code segment
.org 0
rjmp Init ;reset vector
.org OC1Aaddr
rjmp Timer ;Timer1 OC vector
.org SPMaddr+1 ;skip vector table
;-------------------- Program Execution Starts Here: ------------------------
Init: ldy RAMEND
out SPL,YL ;locate stack
out SPH,YH
rcall iWdog ;start internal watchdog
rcall iPorts ;ports init
rcall iVar ;variables init
rcall iTimer ;system timer init
rcall iEnc ;encoder subsystem init
sei ;interrupts enable
;Main loop:
Main: rcall mEnc ;read encoder
;... process encoder messages
rcall mWdog ;watchdog restart
rjmp Main ;loop
;------------------------- Subroutines area: --------------------------------
;Internal watchdog init:
iWdog: wdr ;Internal watchdog restart: mWdog: bbrc FLAGS,WUpd,nu ;---------------------------------------------------------------------------- ;Ports init: ldi temp,PUPD ;---------------------------------------------------------------------------- ;Variables init: iVar: clr FLAGS ;clear flags ;---------------------------------------------------------------------------- ;System timer init: iTimer: ldi temp,0 ldi temp,byte2(T1Div-1) in temp,TIMSK ;System timer interrupt: Timer: push temp stbr Flags,WUpd ;set watchdog update flag pop YH .include "Power.asm" ;link power control module ;Encoder support module ;---------------------------------------------------------------------------- ;Constantes: .equ ENDEB = 300 ;encoder debounce delay, uS ;---------------------------------------------------------------------------- ;Derivated constantes: .equ ENDEBV = ENDEB/100 .if ENDEBV > MAXBYTE .equ SWDEBV = SWDEB/100 .if ENDEBV > MAXBYTE ;---------------------------------------------------------------------------- ;Messages: .equ msgNop = 0x00 ;no operation ;---------------------------------------------------------------------------- .DSEG ;Data segment ;---------------------------------------------------------------------------- .CSEG ;Code segment ;---------------------------------------------------------------------------- ;Encoder subsystem init: iEnc: ldi Msg,msgNop ;no operation ;---------------------------------------------------------------------------- ;Encoder read: mEnc: rcall EScan ;scan encoder ldi temp,ENDEBV ;debounce delay for encoder rcall EScan ;scan encoder ;Switch button check: bbrc temp,2,s_0 q1x: bbrc temp,0,a_0 pls: ldi Msg,msgInc ;send increment message no_ch: ldi Msg,msgNop ;send no operation message ;---------------------------------------------------------------------------- ;Encoder timed task: tEnc: dec EncTm ;---------------------------------------------------------------------------- ;Scan encoder: EScan: clr temp ;---------------------------------------------------------------------------- ;Delay: Delay: push Cnt ;---------------------------------------------------------------------------- ;Header file ;---------------------------------------------------------------------------- ;Constantes: .equ FCLK = 10000000 ;Fclk, Hz ;---------------------------------------------------------------------------- ;Derivated constantes: .equ MAXBYTE = 0xFF .equ T1Div = ((((Fclk/1000)*Tsys)/100)+5)/10 ;CK/1 .if T1Div > MAXWORD ;---------------------------------------------------------------------------- ;Port Definitions: .equ DIRB = 0b11111111 ;Port B direction .equ DIRC = 0b11001111 ;Port C direction .equ DIRD = 0b11111110 ;Port D direction ;***** Ports lines control macros: .macro Skip_if_Port_EF1_0 ;skip if EF1 = 0 .macro Skip_if_Port_EF2_0 ;skip if EF2 = 0 .macro Skip_if_Port_ESB_0 ;skip if ESB = 0 ;---------------------------------------------------------------------------- ;Global Register Variables: ;r0, r1 used with mul instruction .def EncSt = r2 ;store encoder state .def temp = r16 ;temporary register temp .def FLAGS = r25 ;flags ;r26,r27 used as X-register ;---------------------------------------------------------------------------- [/pre]
E-mail:
info@telesys.ru
ldi temp,(1<
ldi temp,(1<
clbr FLAGS,WUpd
wdr ;internal watchdog restart
nu: ret
iPorts: ldi temp,PUPB
out PORTB,temp ;init PORTB and on/off pullup
ldi temp,DIRB
out DDRB,temp ;set PORTB direction
ldi temp,PUPC
out PORTC,temp ;init PORTC and on/off pullup
ldi temp,DIRC
out DDRC,temp ;set PORTC direction
out PORTD,temp ;init PORTD and on/off pullup
ldi temp,DIRD
out DDRD,temp ;set PORTD direction
ret
ret
out TCCR1A,temp ;OC disable, PWM disable
ldi temp,(1<
out OCR1AH,temp ;compare register load
ldi temp,byte1(T1Div-1)
out OCR1AL,temp
ori temp,(1<
out TIMSK,temp ;output compare interrupt enable
ret
in temp,SREG ;save status register
push temp
push YL
push YH
rcall tEnc ;encoder control
;...
pop YL
pop temp
out SREG,temp ;restore status register
pop temp
reti
;----------------------------------------------------------------------------
.include "Encoder.asm" ;link encoder control module
.include "Menu.asm" ;link menu processing module
.include "Display.asm" ;link display control module
.equ SWDEB = 50000 ;switch button debounce delay, uS
.equ ENCTMV = 100 ;encoder timer value, uS
.equ MAXV = 8 ;maximum encoder velocity
.error "out of range constant"
.endif
.error "out of range constant"
.endif
.equ msgInc = 0x01 ;increment
.equ msgDec = 0x02 ;decrement
.equ msgMax = 0x03 ;set maximum
.equ msgMin = 0x04 ;set minimum
.equ msgKdn = 0x05 ;key down
.equ msgKup = 0x06 ;key up
rcall EScan ;scan encoder
mov EncSt,temp ;save encoder state
clr EncS ;clear encoder step counter
clr EncV ;clear encoder velocity
ldi temp,ENCTMV ;encoder timer load
ret
mov Cnt,temp ;save encoder state
eor temp,EncSt ;check for changes
breq no_ch ;return, no changes
bbrc temp,2,no_sw
ldi temp,SWDEBV ;debounce delay for switch button
no_sw: rcall Delay
cp temp,Cnt ;check encoder state
brne no_ch ;return, bounce
mov temp,EncSt ;previous encoder state
mov EncSt,Cnt ;save new encoder state
bbrs Cnt,2,q1x ;no changes
ldi Msg,msgKdn ;key down message
rjmp e_ret
s_0: bbrc Cnt,2,q1x ;no changes
ldi Msg,msgKup ;key up message
rjmp e_ret
;1x quadrature decoder:
a_1: bbrc Cnt,0,a_10
rjmp no_ch
a_0: bbrs Cnt,0,a_01
rjmp no_ch
a_01: bbrc Cnt,1,pls
rjmp no_ch
a_10: bbrc Cnt,1,min
rjmp no_ch
inc EncS ;increment encoder step counter
mov temp,EncV
cpi temp,MAXV ;check encoder velocity
brlt e_ret
ldi Msg,msgMax ;if EncV > MAXV then max message
rjmp e_ret
min: ldi Msg,msgDec ;send decrement message
dec EncS ;decrement encoder step counter
mov temp,EncV
cpi temp,-MAXV ;check encoder velocity
brge e_ret
ldi Msg,msgMin ;if EncV < -MAXV then min message
rjmp e_ret
e_ret: ret
brne teret
ldi temp,ENCTMV
mov EncTm,temp ;encoder timer reload
mov EncV,EncS ;update encoder velocity
clr EncS
teret: ret
;Out: temp - encoder state
Skip_if_Port_EF1_0
stbr temp,0
Skip_if_Port_EF2_0
stbr temp,1
Skip_if_Port_ESB_0
stbr temp,2
ret
;Input: temp - delay [x100 uS]
de2: ldi Cnt,FCLK/100000
de1: dec Cnt ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
nop ;1 +
brne de1 ;2 = 10
dec temp
brne de2
pop Cnt
ret
.equ TSYS = 1000 ;time base, uS
.equ MAXWORD = 0xFFFF
.error "out of range constant"
.endif
.equ PUPB = 0b00000000 ;Port B pull-ups
.equ PUPC = 0b00110000 ;Port C pull-ups
.equ EF2 = PC4 ; Encoder F2
.equ EF1 = PC5 ; Encoder F1
.equ PUPD = 0b00000001 ;Port D pull-ups
.equ ESB = PD0 ; Encoder SB
sbic PINC,EF1
.endm
sbic PINC,EF2
.endm
sbic PIND,ESB
.endm
.def EncS = r3 ;encoder step counter
.def EncV = r4 ;encoder velocity
.def EncTm = r5 ;encoder timer
.def Cnt = r17 ;temporary register Cnt
.def Msg = r18 ;message code
.equ WUpd = 0 ;watchdog update flag
;r28,r29 used as Y-register
;r30,r31 used as Z-register
Ответы
Перейти к списку ответов
|||
Конференция
|||
Архив
|||
Главная страница
|||
Содержание