Quadrature Encoder
Quadrature Encoder
Quadrature Encoder
Spring 2009
jeg
S1 S2 =10 10 00
sCCW2
00
sCW1
01 01 01
sCW2
00 01
11
00 00
sCW4
sReset
11 11
sCW3
00
10 10
11 10 10
01 11 11
sCCW3
sCCW4
01 11
sLock -Out
01
Each state also has an impossible transition, which is the complement of its stable transition value. As an example for sCW1 the stable transition is 00. It is impossible for both inputs to change at the same time, so the impossible transition is 11. If a transition
Spring 2009
jeg
of 11 occurs the state machine goes to the lockout state of sLockout. It remains in this state until a master rested forces the fstate machine to the state sReset. The only time the state machine should drop into the sLockout state is when there is ineffective debouncing of the inputs.
VDHL Function
The quadrature encoder has four input and four outputs shown in Figure 2. The s1 and s2 inputs come from debounced quadrature switches that are 90 electrical degrees apart. Reset is an asynchronous reset that takes the finite state machine back to the sReset state. The global clock is clk and forces synchronous outputs to be synchronous to the rising edge of the global clock
QuadEncoder s1 s2 reset clk dir look cntEnable bad
inst
The outputs dir, look and bad are synchronous outputs and cntEnable is an asynchronous output. The output dir goes high for clockwise rotation and low for counter-clockwise rotation. The ouput look is high when any external position counters should have a stable values and low during the external counter transitions. Bad is high when the finite state machine is in the sLockout state and low otherwise. This output is intended for debugging only. The output cntEnable is an asynchronous output and is high for one clock cycle following a changes on s1 or s2. See Figure 3 for nominal timing waveforms. It should be noted that cntEnable will remain high as long as the finite state machine is in the sLockout state. This is an alternate way to detect ineffective debouncing of s1 or s2 during debugging.
Spring 2009
jeg
VHDL Listing
The following is a listing of the quadrature encoder VHDL. This file is also available on the course web page.
--Quadrature Encoder --James Grover on 3/27/209 entity QuadEncoder is port( s1,s2,reset,clk dir,look cntEnable,bad ); end entity QuadEncoder;
architecture behavioral of QuadEncoder is type state_type is (sReset, sCW1, sCW2, sCW3, sCW4, sCCW1, sCCW2, sCCW3, sCCW4, sLockout); signal state : state_type; signal oldState : state_type; begin fsm: process(clk, reset, s1, s2) begin if(reset = '1') then state <= sReset; oldState <= sReset; elsif (clk'event and clk = '1')then case state is when sReset => if( S1 = '0' AND S2 = '0') then state <= sCW1; oldState <= sCW1; elsif (S1 = '0' and S2 = '1') then state <= sCW2; oldState <= sCW2; elsif (S1 = '1' and S2 = '1') then state <= sCW3; oldState <= sCW3; else state <= sCW4; oldState <= sCW4; end if; when sCW1 => -- 00 oldState <= sCW1; if( S1 = '0' AND S2 = '1') then state <= sCW2; elsif (S1 = '1' and S2 = '0') then state <= sCCW1; elsif (S1 = '1' and S2 = '1') then state <= sLockout; else state <= sCW1; end if; when sCW2 => -- 01 oldState <= sCW2;
Spring 2009
if( S1 = '1' AND S2 = '1') then state <= sCW3; elsif (S1 = '0' and S2 = '0') then state <= sCCW2; elsif (S1 = '1' and S2 = '0') then state <= sLockout; else state <= sCW2; end if; sCW3 => -- 11 oldState <= sCW3; if( S1 = '1' AND S2 = '0') then state <= sCW4; elsif (S1 = '0' and S2 = '1') then state <= sCCW3; elsif (S1 = '0' and S2 = '0') then state <= sLockout; else state <= sCW3; end if; sCW4 => -- 10 oldState <= sCW4; if( S1 = '0' AND S2 = '0') then state <= sCW1; elsif (S1 = '1' and S2 = '1') then state <= sCCW4; elsif (S1 = '0' and S2 = '1') then state <= sLockout; else state <= sCW4; end if; sCCW1 => -- 10 oldState <= sCCW1; if( S1 = '1' AND S2 = '1') then state <= sCCW4; elsif (S1 = '0' and S2 = '0') then state <= sCW1; elsif (S1 = '0' and S2 = '1') then state <= sLockout; else state <= sCCW1; end if; sCCW2 => -- 00 oldState <= sCCW2; if( S1 = '1' AND S2 = '0') then state <= sCCW1; elsif (S1 = '0' and S2 = '1') then state <= sCW2; elsif (S1 = '1' and S2 = '1') then state <= sLockout; else state <= sCCW2; end if; sCCW3 => -- 01 oldState <= sCCW3; if( S1 = '0' AND S2 = '0') then state <= sCCW2;
jeg
when
when
when
when
when
Spring 2009
jeg
elsif (S1 = '1' and S2 = '1') then state <= sCW3; elsif (S1 = '1' and S2 = '0') then state <= sLockout; else state <= sCCW3; end if; when sCCW4 => -- 11 oldState <= sCCW4; if( S1 = '0' AND S2 = '1') then state <= sCCW3; elsif (S1 = '1' and S2 = '0') then state <= sCW4; elsif (S1 = '0' and S2 = '0') then state <= sLockout; else state <= sCCW4; end if; when sLockout => state <= sLockout; end case; if(oldState = state) then look <= '1'; else look <= '0'; end if; end if; end process; process(oldState,state) begin if(oldState /= state) then cntEnable <= '1'; else cntEnable <= '0'; end if; end process; with state select dir <=
'1' when sCW1, '1' when sCW2, '1' when sCW3, '1' when sCW4, '0' when others;