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.01.26
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 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     // configure encoder direction pins for input
00045     cbi(ENC0_DIR_PORT, ENC0_DIR_PIN);
00046     cbi(ENC1_DIR_PORT, ENC1_DIR_PIN);
00047 
00048     // configure interrupt I/O pins for input
00049     // INT0 and INT1 are pins PD2 and PD3 on processors
00050     // 90s8515, mega161, mega163, mega323, mega16, mega32
00051     cbi(DDRD, PD2);
00052     cbi(DDRD, PD3);
00053     
00054     // INT0 and INT1 are pins PD0 and PD1 on processors
00055     // mega103, mega128, mega64
00056     //cbi(DDRD, PD2);
00057     //cbi(DDRD, PD3);
00058 
00059     // configure interrupts for rising-edge triggering
00060     // for processors 90s8515, mega161, mega163, mega323, mega16, mega32
00061     sbi(MCUCR, ISC11);
00062     sbi(MCUCR, ISC10);
00063     sbi(MCUCR, ISC01);
00064     sbi(MCUCR, ISC00);
00065     // for processors mega103, mega128, mega64
00066     //sbi(EICRA, ISC11);
00067     //sbi(EICRA, ISC10);
00068     //sbi(EICRA, ISC01);
00069     //sbi(EICRA, ISC00);
00070 
00071     // initialize/clear encoder data
00072     for(i=0; i<NUM_ENCODERS; i++)
00073     {
00074         EncoderState[i].position = 0;
00075         EncoderState[i].velocity = 0;
00076     }
00077     // start tracking encoders
00078     // enable interrupts
00079     // for processors 90s8515, mega161, mega163, mega323, mega16, mega32
00080     sbi(GIMSK, INT0);
00081     sbi(GIMSK, INT1);
00082     // for processors mega103, mega128, mega64
00083     //sbi(EIMSK, INT0);
00084     //sbi(EIMSK, INT1);
00085     
00086     // enable global interrupts
00087     sei();
00088 }
00089 
00090 // encoderOff() disables hardware and stops encoder position updates
00091 void encoderOff(void)
00092 {
00093     // disable interrutps
00094     cbi(GIMSK, INT0);
00095     cbi(GIMSK, INT1);
00096 }
00097 
00098 // encoderGetPosition() reads the current position of the encoder 
00099 s32 encoderGetPosition(u08 encoderNum)
00100 {
00101     // sanity check
00102     if(encoderNum < NUM_ENCODERS)
00103         return EncoderState[encoderNum].position;
00104     else
00105         return 0;
00106 }
00107 
00108 // encoderSetPosition() sets the current position of the encoder
00109 void encoderSetPosition(u08 encoderNum, s32 position)
00110 {
00111     // sanity check
00112     if(encoderNum < NUM_ENCODERS)
00113         EncoderState[encoderNum].position = position;
00114     // else do nothing
00115 }
00116 
00117 SIGNAL(ENC0_INTERRUPT)
00118 {
00119     // encoder has generated a pulse
00120     // check the direction line and update position accordingly
00121     if( inb(ENC0_DIR_PORT) & ENC0_DIR_PIN )
00122         EncoderState[0].position++;
00123     else
00124         EncoderState[0].position--;
00125 }
00126 
00127 SIGNAL(ENC1_INTERRUPT)
00128 {
00129     // encoder has generated a pulse
00130     // check the direction line and update position accordingly
00131     if( inb(ENC1_DIR_PORT) & ENC1_DIR_PIN )
00132         EncoderState[1].position++;
00133     else
00134         EncoderState[1].position--;
00135 }

Generated on Tue Feb 4 20:18:36 2003 for Procyon AVRlib by doxygen1.3-rc2