Line No. | Rev | Author | Line |
---|---|---|---|
1 | 6 | kaklik | /*! \file encoder.h \brief Quadrature Encoder reader/driver. */ |
2 | //***************************************************************************** |
||
3 | // |
||
4 | // File Name : 'encoder.h' |
||
5 | // Title : Quadrature Encoder reader/driver |
||
6 | // Author : Pascal Stang - Copyright (C) 2003-2004 |
||
7 | // Created : 2003.01.26 |
||
8 | // Revised : 2004.06.25 |
||
9 | // Version : 0.3 |
||
10 | // Target MCU : Atmel AVR Series |
||
11 | // Editor Tabs : 4 |
||
12 | // |
||
13 | /// \ingroup driver_hw |
||
14 | /// \defgroup encoder Quadrature Encoder Driver (encoder.c) |
||
15 | /// \code #include "encoder.h" \endcode |
||
16 | /// \par Overview |
||
17 | /// This library allows easy interfacing of standard quadrature encoders |
||
18 | /// (used for sensing shaft rotational position and speed) to the Atmel |
||
19 | /// AVR-series processors. The library uses external interrupts to sense |
||
20 | /// and keep track of the encoder's movements. The library is extendable |
||
21 | /// with the maximum number of encoders equal to the total number of |
||
22 | /// external interrupts available on the target AVR processor. |
||
23 | /// |
||
24 | /// \note Due to the wide range of external interrupt capability on |
||
25 | /// AVR processors, it is difficult for this library to automatically |
||
26 | /// adapt to different processors. For this reason, much of the |
||
27 | /// configuration responsibility has been left with the user. See |
||
28 | /// the encoderconf.h configuration file. |
||
29 | // |
||
30 | /// \par Operation: |
||
31 | /// Quadrature encoders have two digital outputs usually called PhaseA and |
||
32 | /// PhaseB. When the encoder rotates, PhaseA and PhaseB produce square wave |
||
33 | /// pulses where each pulse represents a fraction of a turn of the encoder |
||
34 | /// shaft. Encoders are rated for a certain number of pulses (or counts) per |
||
35 | /// complete revolution of the shaft. Common counts/revolution specs are 50, |
||
36 | /// 100,128,200,250,256,500,etc. By counting the number of pulses output on |
||
37 | /// one of the phases starting from time0, you can calculate the total |
||
38 | /// rotational distance the encoder has traveled. |
||
39 | /// |
||
40 | /// Often, however, we want current position not just total distance traveled. |
||
41 | /// For this it is necessary to know not only how far the encoder has traveled, |
||
42 | /// but also which direction it was going at each step of the way. To do this |
||
43 | /// we need to use both outputs (or phases) of the quadrature encoder. |
||
44 | /// |
||
45 | /// The pulses from PhaseA and PhaseB on quadrature encoders are always aligned |
||
46 | /// 90 degrees out-of-phase (otherwise said: 1/4 wavelength apart). This |
||
47 | /// special phase relationship lets us extract both the distance and direction |
||
48 | /// the encoder has rotated from the outputs. |
||
49 | /// |
||
50 | /// To do this, consider Phase A to be the distance counter. On each rising |
||
51 | /// edge of PhaseA we will count 1 "tic" of distance, but we need to know the |
||
52 | /// direction. Look at the quadrature waveform plot below. Notice that when |
||
53 | /// we travel forward in time (left->right), PhaseB is always low (logic 0) at |
||
54 | /// the rising edge of PhaseA. When we travel backwards in time (right->left), |
||
55 | /// PhaseB is always high (logic 1) at the rising edge of PhaseA. Note that |
||
56 | /// traveling forward or backwards in time is the same thing as rotating |
||
57 | /// forwards or bardwards. Thus, if PhaseA is our counter, PhaseB indicates |
||
58 | /// direction. |
||
59 | /// |
||
60 | /// Here is an example waveform from a quadrature encoder: |
||
61 | /* |
||
62 | /// /---\ /---\ /---\ /---\ /---\ /---\ |
||
63 | /// Phase A: | | | | | | | | | | | | |
||
64 | /// ---/ \---/ \---/ \---/ \---/ \---/ \- |
||
65 | /// -\ /---\ /---\ /---\ /---\ /---\ /--- |
||
66 | /// Phase B: | | | | | | | | | | | | |
||
67 | /// \---/ \---/ \---/ \---/ \---/ \---/ |
||
68 | /// Time: <---------------------------------------------------> |
||
69 | /// Rotate FWD: >----------------------------------------------> |
||
70 | /// Rotate REV: <----------------------------------------------< |
||
71 | */ |
||
72 | /// To keep track of the encoder position in software, we connect PhaseA to an |
||
73 | /// external processor interrupt line, and PhaseB to any I/O pin. We set up |
||
74 | /// the external interrupt to trigger whenever PhaseA produces a rising edge. |
||
75 | /// When a rising edge is detected, our interrupt handler function is executed. |
||
76 | /// Inside the handler function, we quickly check the PhaseB line to see if it |
||
77 | /// is high or low. If it is high, we increment the encoder's position |
||
78 | /// counter, otherwise we decrement it. The encoder position counter can be |
||
79 | /// read at any time to find out the current position. |
||
80 | // |
||
81 | // NOTE: This code is currently below version 1.0, and therefore is considered |
||
82 | // to be lacking in some functionality or documentation, or may not be fully |
||
83 | // tested. Nonetheless, you can expect most functions to work. |
||
84 | // |
||
85 | // This code is distributed under the GNU Public License |
||
86 | // which can be found at http://www.gnu.org/licenses/gpl.txt |
||
87 | // |
||
88 | //***************************************************************************** |
||
89 | |||
90 | #ifndef ENCODER_H |
||
91 | #define ENCODER_H |
||
92 | |||
93 | #include "global.h" |
||
94 | |||
95 | // include encoder configuration file |
||
96 | #include "encoderconf.h" |
||
97 | |||
98 | // constants/macros/typdefs |
||
99 | |||
100 | // defines for processor compatibility |
||
101 | // chose proper Interrupt Mask (IMSK) |
||
102 | #ifdef EIMSK |
||
103 | #define IMSK EIMSK // for processors mega128, mega64 |
||
104 | #endif |
||
105 | #ifdef GICR |
||
106 | #define IMSK GICR // for mega16,32,etc |
||
107 | #endif |
||
108 | // default |
||
109 | #ifndef IMSK |
||
110 | #define IMSK GIMSK // for other processors 90s8515, mega163, etc |
||
111 | #endif |
||
112 | |||
113 | |||
114 | //! Encoder state structure |
||
115 | // stores the position and other information from each encoder |
||
116 | typedef struct struct_EncoderState |
||
117 | { |
||
118 | s32 position; ///< position |
||
119 | } EncoderStateType; |
||
120 | |||
121 | |||
122 | // functions |
||
123 | |||
124 | //! encoderInit() initializes hardware and encoder position readings |
||
125 | // Run this init routine once before using any other encoder function. |
||
126 | void encoderInit(void); |
||
127 | |||
128 | //! encoderOff() disables hardware and stops encoder position updates |
||
129 | void encoderOff(void); |
||
130 | |||
131 | //! encoderGetPosition() reads the current position of the encoder |
||
132 | s32 encoderGetPosition(u08 encoderNum); |
||
133 | |||
134 | //! encoderSetPosition() sets the current position of the encoder |
||
135 | void encoderSetPosition(u08 encoderNum, s32 position); |
||
136 | |||
137 | #endif |
Powered by WebSVN v2.8.3