At 00:25 6/10/99 +0200, you wrote:
>Hej a b. Tack fšr ditt meddelande 13:44 1999-10-05 -0700 enligt nedan:
>>Hello Picers...,
>>
>>Can anybody tell me how to read out a Rotary encoder with a pic (16f84)??
>
>There was recently a thread about this!
>Subject "Quadrature incremental pot decoding on PIC"
>Search the Piclist archive... I forgot where it is...
>
>.. Is there an up to date piclist archive?
>Where?
>
>
>goto table method:
>(Probably have (IMHO) the shortest max process time, but not smallest code)
>
>First get two phase bits into the same byte as the old ones, by rotating
them left into the storebyte position 0 and 1. The phase bits from previous
time this routine was called is now in bit 2 and 3, and the now new bits
will be used as old next time. (Also, earlier input states is now in bit
4:5 and 6:7, but whatfor?) : Total 8 cycles
>Then use theese four bits to telll what have happened:
> movf storebyte, W ;1 cycle
> andlw b'1111' ;1 cycle
> addwf PCL ,f ;2 cycles + 2 cycles for the goto selected in
table
{Quote hidden}> ;Change Old New
> goto isrBchange_NO ; 0 0 0 0
> goto isrBchange_UP ; 0 0 0 1
> goto isrBchange_DN ; 0 0 1 0
> goto isrBchange_ERR ; 0 0 1 1
>
> goto isrBchange_DN ; 0 1 0 0
> goto isrBchange_NO ; 0 1 0 1
> goto isrBchange_ERR ; 0 1 1 0
> goto isrBchange_UP ; 0 1 1 1
>
> goto isrBchange_UP ; 1 0 0 0
> goto isrBchange_ERR ; 1 0 0 1
> goto isrBchange_NO ; 1 0 1 0
> goto isrBchange_DN ; 1 0 1 1
>
> goto isrBchange_ERR ; 1 1 0 0
> goto isrBchange_DN ; 1 1 0 1
> goto isrBchange_UP ; 1 1 1 0
> goto isrBchange_NO ; 1 1 1 1
>
>
>Timing is total 14 cycles, isosynchronous, including goto appropriate
routine (count up/down/error/nochange)
>
>Then make ypur own routines, i.e
>isrBchange_DN for counting down your variable, etc
>
>The decode routine can be driven by interrupt on change on port B, or you
can call it regularly to poll signals if interrupt on change is not available.
>
>Regards
>/Morgan
>
This routine has the problem in that all possible changes of state for the
same direction produce a GOTO to the same routine, the function still needs
to know when a full cycle has been completed i.e. One full revolution, this
may be done by running a counter. Also the routine must see all chages of
state else an error is encounted. On a quadrature cycle only looking for a
complete rotation, the software only needs to check one line.
I hae included a high level respone to this, the code produced is not very
efficent and you can clean it up to make it faster, just done so that
people can see what I am on about
unsigned char
uc_Quadrature_check (unsigned char uc_do_what)
{
/*
----------------------------------------------------------------------------
---------
WARNING
Non portable function, remove bit vars
Quadrature encoder check for full cycle
----------------------------------------------------------------------------
---------
*/
static unsignedbit last_sine; /*bit values*/
static unsignedbit last_cosine
unsigned char i;
i = PORTB; /*read and hold, not realy required but makes th
ings nice*/
if (i& kuc_SINE_MASK)
sine = 1;
else
sine = 0;
if (i& kuc_COSINE_MASK)
cosine = 1;
else
cosine = 0;
/*I understand that there are other ways to do t
his, but written like*/
/*this for clarity*/
if (uc_do_what == kuc_RESET) /*Reset the static variables so
that we can
remove*/
{ /*the init routine from the comp
iler*/
last_sine = sine /*This may be removed if int is
used, please note*/
last_cosine = cosine; /*that the first cycle will be incorrect
in such
case*/
return (kuc_NO_CHANGE); /*as it may not match the encoder, but
this is to be*/
} /*expected*/
If (sine != last_sine) /*Not good code produced by this compare
*/
{
switch (sine)
{
case 0: if (last_cosine) i = quadrature_down() break;
case 1: if (last_cosine) i = quadrature_up() break;
default: i = kuc_NO_CHANGE; break;
}
last_sine = sine;
last_cosine = cosine;
return (i);
}
return (kuc_NO_CHANGE);
}
Dennis