目次

Rotary Encoder emulate

 秋月電子のロータリーエンコーダドライブ回路キットの
 動作を確認する必要に迫られました。



 ロータリーエンコーダが出力してくる信号は、以下。




 クロックで、4信号を出力すると考えれば
 カウンタとデコーダの利用でエミュレート
 できそう。

 出力信号をXOUTとすれば、entityは次のように
 記述できます。

entity remu is
  port (
    -- system 
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ;
    -- output
    XOUT   : out std_logic_vector(3 downto 0) --;
  );
end remu;

 カウンタで0から3を生成し、デコーダで対応
 するビットパターンを出力すると考えると
 ブロック図は、以下。



 対応するVHDLコードは、次の定義でよいでしょう。

  iXOUT <= X"9" when ( iSCNT = 1 ) else
           X"0" when ( iSCNT = 2 ) else
           X"6" when ( iSCNT = 3 ) else
           X"F" ;

 カウンタは、0から3を生成するとよいので
 単純に2ビットバイナリーカウンタで実現。

  process (nRESET,iCLK)
  begin 
    if ( nRESET = '0' ) then
      iSCNT <= 0 ;
    elsif rising_edge( iCLK ) then
      iSCNT <= iSCNT + 1 ;
    end if ;
  end process ;

 カウンタを動かすクロックを、ロータリーエンコーダ
 の動作周波数に近づければよいので、分周器を入れて
 対応します。

  process (nRESET,CLOCK)
  begin 
    if ( nRESET = '0' ) then
      iCNT <= 0 ;
    elsif rising_edge( CLOCK ) then
      iCNT <= iCNT + 1 ;
    end if ;
  end process ;
  iCLK <= '1' when ( iCNT = 0 ) else '0' ;

 すべてのブロックができたので、VHDLコードとして
 まとめます。

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity remu is
  port (
    -- system 
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ;
    -- output
    XOUT   : out std_logic_vector(3 downto 0) --;
  );
end remu ;

architecture Behavioral of remu is
  -- internal register
  signal iXOUT : std_logic_vector(3 downto 0) ;
  signal iSCNT : integer range 0 to 3 ;
  -- clock divider
  signal iCNT : integer range 0 to 4095 ;
  signal iCLK : std_logic ;
begin
  -- output
  XOUT <= iXOUT ;

  -- decoder
  iXOUT <= X"9" when ( iSCNT = 1 ) else
           X"0" when ( iSCNT = 2 ) else
           X"6" when ( iSCNT = 3 ) else
           X"F" ;

  -- counter
  process (nRESET,iCLK)
  begin 
    if ( nRESET = '0' ) then
      iSCNT <= 0 ;
    elsif rising_edge( iCLK ) then
      iSCNT <= iSCNT + 1 ;
    end if ;
  end process ;

  -- clock divider
  process (nRESET,CLOCK)
  begin 
    if ( nRESET = '0' ) then
      iCNT <= 0 ;
    elsif rising_edge( CLOCK ) then
      iCNT <= iCNT + 1 ;
    end if ;
  end process ;
  iCLK <= '1' when ( iCNT = 0 ) else '0' ;

end Behavioral;

 XC9536を使うとして、ピンアサインは以下。

# system
NET "nreset"  LOC = "P39";
NET "clock"   LOC = "P5" ;

# emulate signal
NET "xout<0>" LOC = "P1" ;
NET "xout<1>" LOC = "P2" ;
NET "xout<2>" LOC = "P3" ;
NET "xout<3>" LOC = "P4" ;


目次

inserted by FC2 system