Nikolai Golovchenko says:
; Encoder input test program.
;
; Board: SX Demo/Proto Board
;
DEVICE SX28L, OSC32KHZ, TURBO, STACKX, OPTIONX
RESET start
ORG $08 ;global bank
leds DS 1 ;state of leds (port B), bits 2-7
enc_state
DS 1 ;state of encoder, bits 0-1 (coincides with port assignment)
temp DS 1
ORG $10 ;bank0
ORG $30 ;bank1
ORG $50 ;bank2
ORG $70 ;bank3
ORG $90 ;bank4
ORG $B0 ;bank5
ORG $E0 ;bank6
ORG $F0 ;bank7
RA_DIR EQU %00000000
RB_DIR EQU %00000011
;RB.0, RB.1 - encoder inputs
;RB.2 .. RB.7 - LED outputs
RC_DIR EQU %00000000
OPTION_INIT EQU %01001111
; |||||\_/
; ||||| |
;Reg 0 is WREG ______||||| |
;RTCC int is dis______|||| |
;RTCC clock int._______||| |
;RTCC edge 1/0__________|| |
;Prescaler to WDT _______| |
;Prescaler (WDT) 1:128_____|
ORG $000
start
;init ports
clr RA
clr RB
clr RC
mov w, #RA_DIR
mov !RA, w
mov w, #RB_DIR
mov !RB, w
mov w, #RC_DIR
mov !RC, w
;init vars
clr leds
mov w, RB ;save initial encoder state
mov enc_state, w
;****************************************************************************
;main loop:
;1) read encoder state
;2) compare to old state
;3) if step forward, light one more led (a bar display)
; if step backward, dim one led
; if same, don't change
;4) update state
;5) repeat
;
;Note: keys are not debounced.
;****************************************************************************
read_enc
mov w, RB ;get change between current and previous
;encoder state in w
xor w, enc_state ;
xor enc_state, w ;update state and preserve difference in w
and w, #$03 ;check if there is change
snz
jmp read_enc ;no change, read encoder again
;if both bits changed, this will be an error, but we ignore it here
;xor w, #$03
;skpnz
; jmp enc_error
;calculate direction in temp.1
mov temp, w
mov w, <<enc_state
xor w, enc_state
xor temp, w
sb temp.1
call inc_bar ;light one more led
snb temp.1
call dec_bar ;dim one led
jmp read_enc ;repeat
;****************************************************************************
;increase the bar indicator
dec_bar
clc
rr leds
mov w, leds
mov RB, w
retp
;****************************************************************************
;decrease the bar indicator
inc_bar
rl leds
setb leds.2 ;set lower bit
mov w, leds
mov RB, w
retp
;****************************************************************************
ORG $200
ORG $400
ORG $600
Matthew Ballinger [MattBeck at AOL.COM] says:
Or a much more efficient routine would be (in parallax mnemonics):ChkEnc mov new,Enc ;get new input and new,#%00000011 ;get rid of all but 2 enc bits mov temp,new ;make copy xor temp,old ;is old = new jz ChkEnc ;then no change, go back cje temp,#3,err ;goto "error" if both bits changed clc ;get ready for right shift rl Old ;align bits xor old,new ;check for direction jb old.1,up ;if 1 then up direction, if 0 then down direction
Alvaro Deibe Diaz [adeibe at CDF.UDC.ES] says:
; Encoder read #define encx PORTA,1 ; Encoder inputs #define ency PORTA,2 ; ; ; Inic (usually needless) clr auxint ; Clear aux var snb encx ; and get encoder inputs setb auxint.0 ; in bit 0... snb ency setb auxint.1 ; ...and 1 ; ; Here starts the hard work mov W, auxint ; encod <- (actual state) xor (previous one) xor encod, W ; (only bits 0 and 1 affected) ; rr auxint ; XOR results, reordered, get rl encod ; into encod, in bits 0 and 1. rr auxint ; This bits are the motion indicators rl encod ; At this point you have a new read of the encoder. Bits 2 and 3 of 'encod' have the information about the direction of movement of the encoder. If you have to translate this information into a variable, then you can do something like this: ; snb encod.2 ; Direction 'X' motion inc posenc snb encod.3 ; ...or 'Y' dec posenc ; Bits 4,5 and 6,7 of 'encod' have the previous reads.
Lance Allen says:
The easiest way (in my opinion) is to feed one of the two outputs (I assume its a quadrature type) to B0 and the other one to any other input (probably B1). Set the B0 input to ext interrupt enabled . Whenever an interrupt is detected by an edge presenting itself (rising or falling .. its all programable) a movement of (pulses-per-rev divided by 360) deg has been made and if you read B1and there is a 1 there the encoder turned one way, if a 0 then it turned the other.If no interrupts are available (B0 is the only ext one) then you will need to poll one input and read the other on a change.... instead.
Morgan Olsson says:
Encoders use to have between 32 to several thousands cycles per revolution.If you want perfect synchornization to a 0° sync signal, set the two gotos that you wish will count into the zero position to point to specialized count up/down routines that also checks the sync signal.
This will give the best possible zero position synchronization, with a resolution of four steps per cycle, making the most out of the encoder.
Using interrupt on change for the two lines is the best.
If you need to poll for changes instead, we we might want to add a few lines of code before my example that just check if any line has changed, thus minimizing the cycles needed when no change. (but will add total cycles when a change has occurred)
| file: /Techref/scenix/lib/io/osi1/sensor/qenc_sx.htm, 6KB, , updated: 2004/6/10 14:40, local time: 2025/10/23 20:26,
216.73.216.53,10-2-207-162:LOG IN
|
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://massmind.org/techref/scenix/lib/io/osi1/sensor/qenc_sx.htm"> Quadrature Encoders</A> |
| Did you find what you needed? |
Welcome to massmind.org! |
Welcome to massmind.org! |
.