目次

DCモータドライブ

 次のDCモータドライブ回路をテストします。




 IchigoJamの出力は、4ビットが基本なので、4ビットでは
 DUTY比(0から99%)を出力できないので、表を用意し
 対応します。

 対応は、次表とします。
 (左がデコーダの入力値、右を出力値)

 0 : 0
 1 : 11
 2 : 20
 3 : 30
 4 : 40
 5 : 50
 6 : 60
 7 : 70
 8 : 80
 9 : 90
10 : 83
11 : 70
12 : 60
13 : 50
14 : 40
16 : 30

 DUTY比はCPLD、FPGA内部で変換されるとすれば
 IchigoJamは、4ビットのデータを時間間隔を
 入れて出力するだけ。

10 ' test DC motor
20 FOR I=0 TO 15
30   LET J,I:GOSUB 100
40   FOR K=1 TO 4:OUT K,[K]:NEXT
50   FOR K=1 TO 10:WAIT 60:NEXT
60 NEXT
70 FOR K=1 TO 4:OUT K,0:NEXT
80 END
100 '
110 FOR K=1 TO 4
120   LET [K],J % 2:LET J,J >> 1
130 NEXT
135 ? [4],[3],[2],[1]
140 RTN

 0から15の整数を4ビットに変換するために
 サブルーチンで配列にビットを構成する1と0
 を計算して保存します。

 動かすと、次のようになります。



 ラベルを利用して書き換えると、以下。

10 ' test DC motor
20 FOR I=0 TO 15
30   LET J,I:GSB @HND
40   FOR K=1 TO 4:OUT K,[K]:NEXT
50   FOR K=1 TO 10:WAIT 60:NEXT
60 NEXT
70 FOR K=1 TO 4:OUT K,0:NEXT
80 END
100 @HND
110 FOR K=1 TO 4
120   LET [K],J % 2:LET J,J >> 1
130 NEXT
135 ? [4],[3],[2],[1]
140 RTN

 4ビット入力で、DUTY比(7ビット)を生成するVHDL
 コードは、以下。

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

entity decx is
  port (
    -- input
    DDIN  : in  std_logic_vector(3 downto 0) ;
    -- enable
    DDOUT : out std_logic_vector(6 downto 0) --;
  );
end decx ;

architecture behavioral of decx is
  -- input
  signal iDDIN  : integer range 0 to 15 ;
  -- output
  signal iDDOUT : integer range 0 to 99 ;
begin
  -- output
  DDOUT <= conv_std_logic_vector(iDDOUT,7) ;

  -- input
  iDDIN <= conv_integer(DDIN) ;

  -- decode
  iDDOUT <= 11 when ( iDDIN =  1 ) else
            20 when ( iDDIN =  2 ) else
            30 when ( iDDIN =  3 ) else
            40 when ( iDDIN =  4 ) else
            50 when ( iDDIN =  5 ) else
            60 when ( iDDIN =  6 ) else
            70 when ( iDDIN =  7 ) else
            80 when ( iDDIN =  8 ) else
            90 when ( iDDIN =  9 ) else
            83 when ( iDDIN = 10 ) else
            70 when ( iDDIN = 11 ) else
            60 when ( iDDIN = 12 ) else
            50 when ( iDDIN = 13 ) else
            40 when ( iDDIN = 14 ) else
            30 when ( iDDIN = 15 ) else
            0 ;

end behavioral;

 DUTY比に対応したPWM波形生成は、次の記述に。

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

entity dcmx is
  port (
    -- system
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ;
    -- enable
    ENX    : in  std_logic ;
    -- duty ratio
    DUTYX  : in  std_logic_vector(6 downto 0) ;
    -- enable
    WOUT   : out std_logic --;
  );
end dcmx ;

architecture behavioral of dcmx is
  -- counter
  signal iPCNT : integer range 0 to 100 ;
  -- internal register
  signal iDCNT : integer range 0 to 99 ;
  -- internal register
  signal iWOUT : std_logic ;
begin
  -- output
  WOUT <= iWOUT when ( ENX = '1' ) else '0' ;

  -- convert
  iWOUT <= '1' when ( iPCNT < iDCNT ) else '0' ;

  -- counter
  process (nRESET,CLOCK)
  begin
    if ( nRESET = '0' ) then
      iPCNT <= 0 ;
      iDCNT <= 0 ;
    elsif rising_edge(CLOCK) then
      if ( iPCNT = 100 ) then
        iPCNT <= 0 ;
        iDCNT <= conv_integer(DUTYX) ;
      else
        iPCNT <= iPCNT + 1 ;
      end if ;
    end if ;
  end process ;

end behavioral;

 2つの回路を動かすためのドライバは、以下。

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

entity mcrb is
  port (
    -- system
    nRESET : in  std_logic ;
    CLOCK  : in  std_logic ; -- 4MHz
    -- monitor
    MCLK   : out std_logic ;
    -- input
    DIN    : in  std_logic_vector(3 downto 0) ;
    ENX    : in  std_logic ;
    -- pulse out
    DOUT   : out std_logic --;
  );
end mcrb ;

architecture behavioral of mcrb is
  -- constant
  CONSTANT CNTMAX  : integer := 39 ;
  CONSTANT CNTHALF : integer := 20 ;
  -- clock divider
  signal iCNT : integer range 0 to CNTMAX ;
  signal iCLK : std_logic ;
  --
  signal iDUTY : std_logic_vector(6 downto 0) ;
  -- decoder
  component decx is
    port (
      -- input
      DDIN  : in  std_logic_vector(3 downto 0) ;
      -- enable
      DDOUT : out std_logic_vector(6 downto 0) --;
    );
  end component ;
  -- pwm generator
  component dcmx is
    port (
      -- system
      nRESET : in  std_logic ;
      CLOCK  : in  std_logic ;
      -- enable
      ENX    : in  std_logic ;
      -- duty ratio
      DUTYX  : in  std_logic_vector(6 downto 0) ;
      -- enable
      WOUT   : out std_logic --;
  );
  end component ;
  -- internal register
  signal iFOUT : std_logic ;
begin
  -- output
  MCLK <= not iCLK ;
  DOUT <= iFOUT ;

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

  -- module instance (decoder)
  DECXinst : decx port map (
      -- input
      DDIN  => DIN ,
      -- enable
      DDOUT => iDUTY
  );

  -- module instance

  DCMXinst : dcmx port map (
      -- system
      nRESET => nRESET ,
      CLOCK  => iCLK ,
      -- enable
      ENX    => ENX ,
      -- duty ratio
      DUTYX  => iDUTY ,
      -- enable
      WOUT   => iFOUT
  );

end behavioral;

 ピンアサインは、次のUCFファイルでまとめておきます。

# system
NET "CLOCK"  LOC = "P5"  ;
NET "nRESET" LOC = "P39" ;

# input
NET "DIN<0>"  LOC = "P1" ;
NET "DIN<1>"  LOC = "P2" ;
NET "DIN<2>"  LOC = "P3" ;
NET "DIN<3>"  LOC = "P4" ;
NET "ENX"     LOC = "P6" ;

# output
NET "DOUT" LOC = "P11" ;

# monitor
NET "MCLK" LOC = "P44" ;

 DCモータにPWM波形を与える場合、クロックを利用します。
 このクロックは、100kHzとしています。

 クロックの有無を目視するために、カウンタICを利用し
 分周します。

 100kHzは、1024分周すると100Hz以下になります。
 100Hzをさらに128分周すると、0.1Hz程度なので
 4040、4024のカウンタICを利用して、目視できる
 ようにします。

 回路は単純です。



 4040、4024をカスケードに接続し、4024の
 いずれかの出力にLEDを接続。


目次

inserted by FC2 system