-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathrotary.c
87 lines (69 loc) · 2.05 KB
/
rotary.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
/************************************************************************/
/* */
/* Reading rotary encoder */
/* one, two and four step encoders supported */
/* */
/* Author: Peter Dannegger */
/* */
/************************************************************************/
#include <avr/io.h>
//#include <avr/pgmspace.h>
#include <avr/interrupt.h>
#include "rotary.h"
volatile int8_t enc_delta; // -128 ... 127
static int8_t last;
void encode_init( void )
{
int8_t new;
new = 0;
if( PHASE_A )
new = 3;
if( PHASE_B )
new ^= 1; // convert gray to binary
last = new; // power on state
enc_delta = 0;
TCCR0 = 1<<WGM01^1<<CS01^1<<CS00; // CTC, XTAL / 64
OCR0 = (uint8_t)(XTAL / 64.0 * 1e-3 - 0.5); // 1ms
TIMSK |= 1<<OCIE0;
}
ISR( TIMER0_COMP_vect ) // 1ms for manual movement
{
int8_t new, diff;
new = 0;
if( PHASE_A )
new = 3;
if( PHASE_B )
new ^= 1; // convert gray to binary
diff = last - new; // difference last - new
if( diff & 1 ){ // bit 0 = value (1)
last = new; // store new as next last
enc_delta += (diff & 2) - 1; // bit 1 = direction (+/-)
}
}
int8_t encode_read1( void ) // read single step encoders
{
int8_t val;
cli();
val = enc_delta;
enc_delta = 0;
sei();
return val; // counts since last call
}
int8_t encode_read2( void ) // read two step encoders
{
int8_t val;
cli();
val = enc_delta;
enc_delta = val & 1;
sei();
return val >> 1;
}
int8_t encode_read4( void ) // read four step encoders
{
int8_t val;
cli();
val = enc_delta;
enc_delta = val & 3;
sei();
return val >> 2;
}