|
|

8052 based quadrature counter
See
'Ladder macros' below.
8052 based quadrature counter example
Short
description:
A typical incremental quadrature encoder outputs two signals A, B at
90° (i.e. in quadrature) and a reference mark C. Output circuits could
be open collector, RS-422 etc.
Let’s assume a 2500 pulses per revolution (ppr) encoder, connected to
3600 rpm motor. Than the frequency of the output signal will be 3600/60
* 2500 * 4 = 600 kHz.
So, a 8052 running at more than 14.4 MHz will handle it.
The counting method I am describing here is based on counting up and
down direction pulses by two separate counters.
(Note: timer 2 as an up/down counter makes
counting errors and I have
not made more experiments to avoid them.)
Let see a block diagram of
the unit:
|

|
| Input
circuit |
x4 |
MCU |

|

|

|
I
will presume a Heidenhain® encoder with TTL RS-422 outputs.
The input circuit is
here just for reference, the fun comes later. We have to multiply the
AB series by four and separate two directional pulse streams. The x4 circuit shown
makes the full decoding. It was born somewhere in early 70’s, I can not
even remember where I have seen it first. Although old, a modification
with
1x7475+2x74138+1x7420 can be found in several contemporary counters.
Well, the cost of 4 TTL chips is <$1.
I personally prefer the PLD equivalent. The equation in pseudo language
is on the right.
Well, after the x4 circuit we will have the following signals:

|
I
:= PA;
J := I;
K := PB;
L := K;
UP :=((I'
& J' & K' & L)
#(I'
& J & K & L)
#(I & J' & K' & L')
#(I & J
& K & L'));
DOWN:=((I' & J' & K & L')
#(I'
& J & K' & L')
#(I & J' & K &
L)
#(I & J
& K' & L)); |
|
|
|
Tmod := $55;
{timer0 and timer1 – mode1-16
bit counters}
T2Con:= $00;
Th2 :=
$F3;
{1.6 ms@24Mhz=-3200}
Rcap2h := $f3;
Rcap2l := $80;
Tl2 :=
$80;
Tr2 :=
True;
Pt2 :=
True;
ET2 :=
True; |
The
MCU was AT89C52 running at 24MHz. As far as we do not use
external memory, the clock for the
x4 circuit will be derived from ALE and there will be no missed pulses.
The timer 0 and 1 should be initialized as counters:
Timer 2 will make an interrupt at let say 1.6 ms and will handle LED
display and velocity reading from the counters 0 and 1.
|
GetTimer0:
Mov A,TH0
Mov R1,TL0
Cjne A,TH0,GetTimer0
mov B,A
mov A,R1
mov R0,#UpCount
mov @r0,A
inc R0
mov @R0,B
ret
procedure TimerInt2; {Timer 2 Interrupt}
Begin
RefreshTm2;
OldCntU :=
UpCount;
OldCntD :=
DownCount; {remember old
values}
GetTimer0; GetTimer1; {read current counter values}
UpDfr :=
OldCntU - UpCount; {get
diff from
previous readng}
DnDfr :=
OldCntD - DownCount;
if dir then
Velo := UpDfr - DnDfr
else
Velo := DnDfr - UpDfr;
{dir flag
says initial + direction. Do not change on the fly!}
AbsPos:=AbsPos+Velo; {We’ve
got it}
KbdLed; {read
kbd and refresh display}
End; |
While quite old as a
method,
I think it was better explained by Tim Bucella in Microchip’s
AN532. One can find there also an
implementation of x4 PLD with direction/count outputs.
|
In ladder.phtml
file you can find simple ladder language macros.
These are based on FANUC syntax ladder language.
Example:
_RD StrtIono
; StrtIono TM3 IONO StrtIono STII
_OR STII
;|---][--+-]\[----][----][----()----|
_ANDNOT TM3
;
| STII |
_AND IONO
; |---][--+
_AND StrtIono
_WRT STII
....
_RD
NEG_B
; NEG_B
;
;
|---][------[BUTTON| btn2,Log1,NEG1]-|
BUTTON BTN2,Log1,NEG1
....
_RD NEG_B
; |NEG_B TM2
NEG1
NEG
_OR
NEG
;|---][---+---]/[--][---------( )------|
_ANDNOT TM2
;
|NEG |
_AND
NEG1
;|---][---+
_WRT NEG
;
....
IONVITPR:
clr
A ;
VITAL blnk28 BIMETAL IONVIT
_RD
VITAL ;--][--------]/[---+--]/[-------(/)---|
_ANDNOT
blnk28 ;
StrtIono VITAL |
_RDSTK
StrtIono ;--][----+---]/[---+
_ORNOT zeroiono
;zeroiono|
_ANDNOT
VITAL ;--]/[---+
_ORSTK
_ANDNOT BIMETAL
_WRTNOT IONVIT
RET
------------------------------------------------------
ladder.inc
------------------------------------------------------
COUNTER: .MACRO ARG1,ARG2,ARG3,ARG4,ARG5
;
| | | | +---- upper
limit
;
| | | +--------- work address
;
| | +------------- internal bit
variable-'stored
cond'
;
| +------------------- up=0/down=1
;
+------------------------ act
mov
C,ARG1
mov
F0,C
anl
C,/ARG3
jnc
exit#
jb
ARG2,godown#
mov
A,ARG4
inc A
;check for upper limit
cjne
A,ARG5,okup#
;loc1s#
;
loc1s# jc okup#
dec A
okup# mov ARG4,A
setb
changed
jmp exit1#
godown# dec A
;check for lower limit
cjne
A,#0,okdw#
inc A
okdw# mov ARG4,A
setb
changed
jmp exit1#
exit# mov C,F0
mov ARG3,C
clr changed
exit1#:
clr A
.endm
BUTTON: .macro ARG1,ARG2,ARG3
;
| | +-- output
;
| +------ reset 1-OK, 0-reset
;
+----------- stored cond.
mov F0,C
jnb
ARG2,endz#
anl C,/ARG1
jnc endb#
cpl ARG3
jmp endb#
endz#: clr ARG3
endb#: mov C,F0
mov ARG1,C
.endm
_TMR: .macro ARG1,ARG2
; ARG1 - WORKADRS
; ARG2 - Time
jC
GO# ;Up to 256 cycles
mov
ARG1,#ARG2
clr C
jmp
GO_OUT#
GO# clr C
djnz
ARG1,GO_OUT#
setb C
GO_OUT#:
.endm
_LTMR: .macro ARG1,ARG2
;Up to $FFFF+1 cycles
jC
GO#
mov
ARG1,
#<ARG2
mov
ARG1+1,#>ARG2
clr C
jmp GO_OUT#
GO# clr C
djnz ARG1,GO_OUT#
djnz
ARG1+1,GO_OUT#
setb C
GO_OUT#:
.endm
_SLTMR: .macro ARG1,ARG2
;arg1-3 bytes work adrs, arg2-3 bytes value
jc GO#
mov ARG1, ARG2
mov ARG1+1,ARG2+1
mov ARG1+2,ARG2+2
clr C
jmp GO_OUT#
GO#: clr C
djnz ARG1,GO_OUT#
djnz
ARG1+1,GO_OUT#
djnz
ARG1+2,GO_OUT#
setb C
GO_OUT#: .endm
_RD: .MACRO ARG1
mov C,ARG1
.ENDM
_RDNOT: .MACRO ARG1
CLR C
ORL C,/ARG1
.ENDM
_AND: .MACRO ARG1
anl C,ARG1
.ENDM
_ANDNOT: .MACRO ARG1
anl C,/ARG1
.ENDM
_OR: .MACRO ARG1
orl C,ARG1
.ENDM
_ORNOT: .MACRO ARG1
orl C,/ARG1
.ENDM
_WRT: .MACRO ARG1
mov ARG1,C
.ENDM
_WRTNOT: .MACRO ARG1
cpl C
mov ARG1,C
cpl C
.ENDM
_RDSTK: .MACRO ARG1
rrc A
mov C,ARG1
.ENDM
_RDSTKNOT: .MACRO ARG1
rrc A
clr C
orl C,/ARG1
.ENDM
_ORSTK: .MACRO ARG1
mov F0,C
rlc A
orl C,F0
.ENDM
_ANDSTK: .MACRO ARG1
mov F0,C
rlc A
anl C,F0
.ENDM
BLT .MACRO ARG1,ARG2
;arg1 - val , arg2 -lab
cjne
A,#ARG1,S1#
S1# jc ARG2
.ENDM
BGE .MACRO ARG1,ARG2
cjne
A,#ARG1,S2#
S2# jnc ARG2
.ENDM
------------------------------------------------------
fedia at pasat dot com |
(C) Copyright 1997 - 2008 by Vault Information Services LLC. All Rights Reserved.
Information provided "as-is" without warranty. Please see details.
Contact us for usage and copy permission.
|
|