|
楼主 |
发表于 2010-8-8 12:05:18
|
显示全部楼层
I was asked how I would read a rotary encoder. so here is my solution.
a rotary encoder has two output, A and B. they go high / low, 90 degrees apart.
so if you turn a rotary encoder clock-wide, you will see the following output:
A:0110
B:0011
or '00, '10, '11, '01.
so if you see a sequency of '00 followed by '10, you know that the rotary encoder has been turned clock-wise by 1 click.
alternatively, if you see a sequence of '11 followed by '10, you know that the rotary encoder has been turned counter clock-wise by 1 click.
thus, you can use a table to detonate the value of those clicks, based on the previous and current read-outs of A and B pins:
==========code=============
const signed char ABs_states[]={0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
=========end of code=======
essentially, we are saying that if ABs = '0010 (0x02), we are go increment the encoder read-out by 1: ABs_states[ABs]=1, per the table above.
and if ABs='1110 (0x0e), ABs_states[ABs]=-1, and we are to decrement the encoder read-out by 1.
so here is the routine that returns the value of a rotary encoder:
========code=============
//determine increment / decrement of the encoder
unsigned char encoder_read(PORT_TYPE port, PORT_TYPE pins) {
const signed char ABs_states[]={0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
static unsigned char encoder_output=0x00;
static unsigned char ABs=0x00; //AB key read out, Previous in the high 2 bits and current in the low two bits;
unsigned char tmp;
ABs <<=2; //left 2 bits now contain the previous AB key read-out;
tmp=IO_GET(port, pins); //read ab pins
if (tmp & KEY_A) ABs |= 0x02; //set the 1st bit if A is high now;
if (tmp & KEY_B) ABs |= 0x01; //set the 0th bit if B is high;
ABs &= 0x0f; //only retain ABs' last 4 bits (A_previous, B_previous, A_current, B_current)
encoder_output += ABs_states[ABs];
return encoder_output;
//return ABs;
}
===========end of code==================== |
|