/*********************************************************************** File: jogdial.c Description: source file for encoder handler and routines Usage: link this file after compilation to your project Notice: function check_jogdial() should be called each 1 ms to enable proper speed detection and reaction time. In case of other timing please recalculate the constants speed1treshold and speed2treshold. Their value is computed as 80, resp. 120 ms divided by timer interval. Also don’t forget to change switch1bitmask, switch2bitmask and INPUTPORT to appropriate values. INPUTPORT is a memory mapped variable or function that contains switch 1 and switch 2 logic levels as bits stored in the returned word and the switchXbitmasks are values computed as ( 1 << switch X bit no. ) ***********************************************************************/ #include #include "jogdial.h" u8 jog_state = 0; /* previous encoder switch levels */ u8 time_step = 0; /* time elapsed from last encoder change */ u16 jog_no = 0; /* actual absolute encoder position */ int rel_no = 0; /* constants for quicker resolution of state machine */ const u8 JogUp[] = { 2, 0, 3, 1 }; const u8 JogDown[] = { 1, 3, 0, 2 }; /*********************************************************************** Name: check_jogdial Parameters: - Returns: - Changes: jog_state, time_step, jog_no Description: Main encoder state machine. Should be called every 1 ms. See Notice in header of this file! ***********************************************************************/ void check_jogdial( void ) { u8 input_byte, step; u16 old_val = jog_no; input_byte = ( P1 >> 1 ) & 0x03; /* get switch 1 and switch 2 logic levels */ if( time_step < 10 ) step = 2; else step = 1; /* longer step length leads to normal speed reaction */ if( JogDown[ input_byte ] == jog_state ) { jog_no -= step; rel_no -= step; } else if( JogUp[ input_byte ] == jog_state ) { jog_no += step; rel_no += step; } /* if encoder position changes over one step (four phases) or more, reset the reaction time counter otherwise increase the counter until its value reaches 1000 */ if( ( (u8)old_val & 0xFC ) != ( (u8)jog_no & 0xFC ) ) time_step = 0; else if( time_step < 255 ) time_step++; jog_state = input_byte; /* remember actual switch levels logical */ } /*********************************************************************** Name: jogdial_value Parameters: - Returns: actual absolute position of the encoder (14 bits wide unsigned word) Changes: - Description: The function returns actual encoder position. Could you need to apply range checking, rewrite this function in your way. ***********************************************************************/ u16 jogdial_value( void ) { return ( jog_no >> 2 ); /* discard phase information */ } /*********************************************************************** Name: set_jogdial Parameters: new encoder position (14 bits wide unsigned word) Returns: - Changes: jog_no Description: The function sets new encoder position. Next reading/change of the position will continue from the value set by this function. ***********************************************************************/ void set_jogdial( u16 new_value ) { jog_no = new_value << 2; /* add fake phase information */ rel_no = jog_no; } /*********************************************************************** Name: reset_jogdial Parameters: - Returns: - Changes: jog_no Description: The function resets the encoder position to the zero value. Next reading/change of the position will continue from the value set by this function. ***********************************************************************/ void reset_jogdial( void ) { jog_no = 0; rel_no = ( rel_no + 4 ) % 4; } /*********************************************************************** Name: jogdial_relative Parameters: - Returns: relative value Changes: jog_no Description: The function resets the encoder position to the zero value. Next reading/change of the position will continue from the value set by this function. ***********************************************************************/ int jogdial_relative( void ) { return rel_no >> 2; } /************************** End of file: jogdial.c ***************************/