目次
前
次
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を接続。
目次
前
次