Main Page   Data Structures   File List   Data Fields   Globals  

/encoder.c

Go to the documentation of this file.
00001 /*! \file encoder.c \brief Quadrature Encoder reader/driver. */
00002 //*****************************************************************************
00003 //
00004 // File Name    : 'encoder.c'
00005 // Title        : Quadrature Encoder reader/driver
00006 // Author       : Pascal Stang - Copyright (C) 2003
00007 // Created      : 2003.01.26
00008 // Revised      : 2003.02.24
00009 // Version      : 0.1
00010 // Target MCU   : Atmel AVR Series
00011 // Editor Tabs  : 4
00012 //
00013 // NOTE: This code is currently below version 1.0, and therefore is considered
00014 // to be lacking in some functionality or documentation, or may not be fully
00015 // tested.  Nonetheless, you can expect most functions to work.
00016 //
00017 // This code is distributed under the GNU Public License
00018 //      which can be found at http://www.gnu.org/licenses/gpl.txt
00019 //
00020 //*****************************************************************************
00021 
00022 #ifndef WIN32
00023     #include <avr/io.h>
00024     #include <avr/signal.h>
00025     #include <avr/interrupt.h>
00026 #endif
00027 
00028 #include "global.h"
00029 #include "encoder.h"
00030 
00031 // Program ROM constants
00032 
00033 // Global variables
00034 volatile EncoderStateType EncoderState[NUM_ENCODERS];
00035 
00036 // Functions
00037 
00038 // encoderInit() initializes hardware and encoder position readings
00039 //      Run this init routine once before using any other encoder functions.
00040 void encoderInit(void)
00041 {
00042     u08 i;
00043 
00044     // initialize/clear encoder data
00045     for(i=0; i<NUM_ENCODERS; i++)
00046     {
00047         EncoderState[i].position = 0;
00048         //EncoderState[i].velocity = 0;     // NOT CURRENTLY USED
00049     }
00050 
00051     // configure direction and interrupt I/O pins:
00052     // - for input
00053     // - apply pullup resistors
00054     // - rising-edge interrupt triggering
00055     // - enable interrupt
00056 
00057     #ifdef ENC0_SIGNAL
00058         // set interrupt pins to input and apply pullup resistor
00059         cbi(ENC0_PHASEA_DDR, ENC0_PHASEA_PIN);
00060         sbi(ENC0_PHASEA_PORT, ENC0_PHASEA_PIN);
00061         // set encoder direction pin for input and apply pullup resistor
00062         cbi(ENC0_PHASEB_DDR, ENC0_PHASEB_PIN);
00063         sbi(ENC0_PHASEB_PORT, ENC0_PHASEB_PIN);
00064         // configure interrupts for rising-edge triggering
00065         sbi(ENC0_ICR, ENC0_ISCX0);
00066         sbi(ENC0_ICR, ENC0_ISCX1);
00067         // enable interrupts
00068         sbi(IMSK, ENC0_INT);    // ISMK is auto-defined in encoder.h
00069     #endif
00070     #ifdef ENC1_SIGNAL
00071         // set interrupt pins to input and apply pullup resistor
00072         cbi(ENC1_PHASEA_DDR, ENC1_PHASEA_PIN);
00073         sbi(ENC1_PHASEA_PORT, ENC1_PHASEA_PIN);
00074         // set encoder direction pin for input and apply pullup resistor
00075         cbi(ENC1_PHASEB_DDR, ENC1_PHASEB_PIN);
00076         sbi(ENC1_PHASEB_PORT, ENC1_PHASEB_PIN);
00077         // configure interrupts for rising-edge triggering
00078         sbi(ENC1_ICR, ENC1_ISCX0);
00079         sbi(ENC1_ICR, ENC1_ISCX1);
00080         // enable interrupts
00081         sbi(IMSK, ENC1_INT);    // ISMK is auto-defined in encoder.h
00082     #endif
00083     #ifdef ENC2_SIGNAL
00084         // set interrupt pins to input and apply pullup resistor
00085         cbi(ENC2_PHASEA_DDR, ENC2_PHASEA_PIN);
00086         sbi(ENC2_PHASEA_PORT, ENC2_PHASEA_PIN);
00087         // set encoder direction pin for input and apply pullup resistor
00088         cbi(ENC2_PHASEB_DDR, ENC2_PHASEB_PIN);
00089         sbi(ENC2_PHASEB_PORT, ENC2_PHASEB_PIN);
00090         // configure interrupts for rising-edge triggering
00091         sbi(ENC2_ICR, ENC2_ISCX0);
00092         sbi(ENC2_ICR, ENC2_ISCX1);
00093         // enable interrupts
00094         sbi(IMSK, ENC2_INT);    // ISMK is auto-defined in encoder.h
00095     #endif
00096     #ifdef ENC3_SIGNAL
00097         // set interrupt pins to input and apply pullup resistor
00098         cbi(ENC3_PHASEA_DDR, ENC3_PHASEA_PIN);
00099         sbi(ENC3_PHASEA_PORT, ENC3_PHASEA_PIN);
00100         // set encoder direction pin for input and apply pullup resistor
00101         cbi(ENC3_PHASEB_DDR, ENC3_PHASEB_PIN);
00102         sbi(ENC3_PHASEB_PORT, ENC3_PHASEB_PIN);
00103         // configure interrupts for rising-edge triggering
00104         sbi(ENC3_ICR, ENC3_ISCX0);
00105         sbi(ENC3_ICR, ENC3_ISCX1);
00106         // enable interrupts
00107         sbi(IMSK, ENC3_INT);    // ISMK is auto-defined in encoder.h
00108     #endif
00109     
00110     // enable global interrupts
00111     sei();
00112 }
00113 
00114 // encoderOff() disables hardware and stops encoder position updates
00115 void encoderOff(void)
00116 {
00117     // disable encoder interrupts
00118     #ifdef ENC0_SIGNAL
00119         // disable interrupts
00120         sbi(IMSK, INT0);    // ISMK is auto-defined in encoder.h
00121     #endif
00122     #ifdef ENC1_SIGNAL
00123         // disable interrupts
00124         sbi(IMSK, INT1);    // ISMK is auto-defined in encoder.h
00125     #endif
00126     #ifdef ENC2_SIGNAL
00127         // disable interrupts
00128         sbi(IMSK, INT2);    // ISMK is auto-defined in encoder.h
00129     #endif
00130     #ifdef ENC3_SIGNAL
00131         // disable interrupts
00132         sbi(IMSK, INT3);    // ISMK is auto-defined in encoder.h
00133     #endif
00134 }
00135 
00136 // encoderGetPosition() reads the current position of the encoder 
00137 s32 encoderGetPosition(u08 encoderNum)
00138 {
00139     // sanity check
00140     if(encoderNum < NUM_ENCODERS)
00141         return EncoderState[encoderNum].position;
00142     else
00143         return 0;
00144 }
00145 
00146 // encoderSetPosition() sets the current position of the encoder
00147 void encoderSetPosition(u08 encoderNum, s32 position)
00148 {
00149     // sanity check
00150     if(encoderNum < NUM_ENCODERS)
00151         EncoderState[encoderNum].position = position;
00152     // else do nothing
00153 }
00154 
00155 #ifdef ENC0_SIGNAL
00156 //! Encoder 0 interrupt handler
00157 SIGNAL(ENC0_SIGNAL)
00158 {
00159     // encoder has generated a pulse
00160     // check the direction line and update position accordingly
00161     if( inb(ENC0_PHASEB_PORTIN) & (1<<ENC0_PHASEB_PIN) )
00162         EncoderState[0].position++;
00163     else
00164         EncoderState[0].position--;
00165 }
00166 #endif
00167 
00168 #ifdef ENC1_SIGNAL
00169 //! Encoder 1 interrupt handler
00170 SIGNAL(ENC1_SIGNAL)
00171 {
00172     // encoder has generated a pulse
00173     // check the direction line and update position accordingly
00174     if( inb(ENC1_PHASEB_PORTIN) & (1<<ENC1_PHASEB_PIN) )
00175         EncoderState[1].position++;
00176     else
00177         EncoderState[1].position--;
00178 }
00179 #endif
00180 
00181 #ifdef ENC2_SIGNAL
00182 //! Encoder 2 interrupt handler
00183 SIGNAL(ENC2_SIGNAL)
00184 {
00185     // encoder has generated a pulse
00186     // check the direction line and update position accordingly
00187     if( inb(ENC2_PHASEB_PORTIN) & (1<<ENC2_PHASEB_PIN) )
00188         EncoderState[2].position++;
00189     else
00190         EncoderState[2].position--;
00191 }
00192 #endif
00193 
00194 #ifdef ENC3_SIGNAL
00195 //! Encoder 3 interrupt handler
00196 SIGNAL(ENC3_SIGNAL)
00197 {
00198     // encoder has generated a pulse
00199     // check the direction line and update position accordingly
00200     if( inb(ENC3_PHASEB_PORTIN) & (1<<ENC3_PHASEB_PIN) )
00201         EncoderState[3].position++;
00202     else
00203         EncoderState[3].position--;
00204 }
00205 #endif

Generated on Fri Aug 1 10:42:41 2003 for Procyon AVRlib by doxygen1.2.18