📄 motor.vhd
字号:
--用于三维步进电机控制的VHDL程序
--by LAUKING
--2007.08.09
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_unsigned.all;
use IEEE.std_logic_arith.all;
entity motor is
port(
--CPLD'S working clock
gclk1: in std_logic;
--CPU's conection pins for CPLD
ready_all: out std_logic;
ready1: out std_logic;
ready2: out std_logic;
ready3: out std_logic;
--CPU's data bus for date for CPLD receiption and return
p0_data: in std_logic_vector (7 downto 0);
--CPLD's chip selection port
cs_cpld: in std_logic:='1';
--CPU's interrupt 1 signal
int1: out std_logic;
--Three motors' selection ports
cp1: out std_logic := 'Z';
cp2: out std_logic := 'Z';
cp3: out std_logic := 'Z';
--Direction control ports
dir1: out std_logic;
dir2: out std_logic;
dir3: out std_logic;
--Speed control for motor 1
spd11: out std_logic;
spd12: out std_logic;
spd13: out std_logic;
--Speed control for motor 2
spd21: out std_logic;
spd22: out std_logic;
spd23: out std_logic;
--pins connecting with CPU
wr: in std_logic;
rd: in std_logic;
ale: in std_logic;
--protect switch
low1: in std_logic; --常闭开关,平时为高电平,触及行程开关时跳变为低
low2: in std_logic;
low3: in std_logic;
high1: in std_logic;
high2: in std_logic;
high3: in std_logic;
--emergency stop
stop: in std_logic; --平时为低电平,急停开关按下时跳变为高电平
--run LED
run_led: out std_logic;
--speaker
speak: out std_logic :='0'
);
end motor;
architecture motor_arch of motor is
signal speed1,speed2,speed3: std_logic_vector(3 downto 0); --速度等进设置值
signal indata1,indata2,indata3: std_logic_vector(7 downto 0); --读进的脉冲数据
signal tclk0,tclk1,tclk2,tclk3: std_logic; --CPLD内部输出脉冲
signal div_frequency0: std_logic_vector(3 downto 0); --分频数值
signal div_frequency: std_logic_vector(3 downto 0); --分频数值
signal counter1,counter2,counter3: integer range 1000 downto 0; --脉冲计数器
signal class1,class2,class3: integer range 1000 downto 0; --速度等级
signal busy1,busy2,busy3: std_logic; --电机忙标志位
begin
process(gclk1,wr,p0_data,cs_cpld) --接收步进电机速度设置值
begin
if gclk1'event and gclk1 = '1' then
if cs_cpld = '0' then
if p0_data(7 downto 5) = "001" then
speed1 <= p0_data(3 downto 0);
elsif p0_data(7 downto 5) = "010" then
speed2 <= p0_data(3 downto 0);
elsif p0_data(7 downto 5) = "011" then
speed3 <= p0_data(3 downto 0);
end if;
end if;
end if;
end process;
tclk0 <= div_frequency0(3); --首先进行16分频
tclk1 <= div_frequency(3); --再次进行16分频
tclk2 <= div_frequency(3); --再次进行16分频
tclk3 <= div_frequency(3); --再次进行16分频
class1 <= 8 when speed1 = "1111" else --class值越小,分频越大,速度越小
9 when speed1 = "1110" else
10 when speed1 = "1101" else
11 when speed1 = "1100" else
12 when speed1 = "1011" else
13 when speed1 = "1010" else
14 when speed1 = "1001" else
16 when speed1 = "1000" else
18 when speed1 = "0111" else
21 when speed1 = "0110" else
25 when speed1 = "0101" else
31 when speed1 = "0100" else
41 when speed1 = "0011" else
59 when speed1 = "0010" else
105 when speed1 = "0001" else
458 when speed1 = "0000" else
18;
class2 <= 8 when speed2 = "1111" else --class值越小,分频越大,速度越小
9 when speed2 = "1110" else
10 when speed2 = "1101" else
11 when speed2 = "1100" else
12 when speed2 = "1011" else
13 when speed2 = "1010" else
14 when speed2 = "1001" else
16 when speed2 = "1000" else
18 when speed2 = "0111" else
21 when speed2 = "0110" else
25 when speed2 = "0101" else
31 when speed2 = "0100" else
41 when speed2 = "0011" else
59 when speed2 = "0010" else
105 when speed2 = "0001" else
458 when speed2 = "0000" else
18;
class3 <= 8 when speed3 = "1111" else --class值越小,分频越大,速度越小
9 when speed3 = "1110" else
10 when speed3 = "1101" else
11 when speed3 = "1100" else
12 when speed3 = "1011" else
13 when speed3 = "1010" else
14 when speed3 = "1001" else
16 when speed3 = "1000" else
18 when speed3 = "0111" else
21 when speed3 = "0110" else
25 when speed3 = "0101" else
31 when speed3 = "0100" else
41 when speed3 = "0011" else
59 when speed3 = "0010" else
105 when speed3 = "0001" else
458 when speed3 = "0000" else
18;
process(gclk1,wr,p0_data,cs_cpld,high1,low1) --行程开关1判断
begin
if(gclk1'event and gclk1='1') then
if high1 = '1' then --实际情况,转台一直是高电平
dir1 <= '1';
elsif low1 = '1' then --实际情况,转台一直是高电平
dir1 <= '0';
elsif cs_cpld = '0' then
if p0_data(7 downto 5) = "001" then
dir1 <= p0_data(4);
end if;
end if;
end if;
end process;
process(gclk1,wr,p0_data,cs_cpld,high2,low2) --行程开关2判断
begin
if(gclk1'event and gclk1='1') then
if high2 = '1' then
dir2 <= '1';
elsif low2 = '1' then
dir2 <= '0';
elsif cs_cpld = '0' then
if p0_data(7 downto 5) = "010" then
dir2 <= p0_data(4);
end if;
end if;
end if;
end process;
process(gclk1,wr,p0_data,cs_cpld,high3,low3) --行程开关3判断
begin
if(gclk1'event and gclk1='1') then
if high3 = '1' then
dir3 <= '1';
elsif low3 = '1' then
dir3 <= '0';
elsif cs_cpld = '0' then
if p0_data(7 downto 5) = "011" then
dir3 <= p0_data(4);
end if;
end if;
end if;
end process;
process(gclk1,wr) --数控分频,作为速度等级基频
begin
if(gclk1'event and gclk1='1') then
if div_frequency0 = "1111" then
div_frequency0 <= "0000";
else div_frequency0 <= div_frequency0 + 1;
end if;
end if;
end process;
process(tclk0,wr) --数控分频,作为速度等级基频
begin
if(tclk0'event and tclk0='1') then
if div_frequency = "1111" then
div_frequency <= "0000";
else div_frequency <= div_frequency + 1;
end if;
end if;
end process;
process(tclk1) --脉冲1产生计数器
begin
if(tclk1'event and tclk1='1') then
if counter1 = (class1 + class1) then
counter1 <= 0;
else counter1 <= counter1 + 1;
end if;
end if;
end process;
process(tclk2) --脉冲2产生计数器
begin
if(tclk2'event and tclk2='1') then
if counter2 = (class2 + class2) then
counter2 <= 0;
else counter2 <= counter2 + 1;
end if;
end if;
end process;
process(tclk3) --脉冲3产生计数器
begin
if(tclk3'event and tclk3='1') then
if counter3 = (class3 + class3) then
counter3 <= 0;
else counter3 <= counter3 + 1;
end if;
end if;
end process;
process(tclk1,p0_data,wr,cs_cpld,low1,high1,stop) --读入cp1脉冲数
begin
if(cs_cpld = '0' and p0_data(7 downto 5) ="101") then
indata1(7 downto 3) <= p0_data(4 downto 0);
indata1(2 downto 0) <= "000";
elsif stop = '1' then
indata1 <="00000000";
elsif (low1 = '1' or high1 = '1') then --实际情况电平为高
indata1 <= "00000001";
elsif tclk1'event and tclk1 = '1' then
if indata1 = "00000000" then
indata1 <= indata1;
elsif counter1 = (class1 + class1) then
indata1 <= indata1 - 1;
end if;
end if;
end process;
process(tclk2,p0_data,wr,cs_cpld,low2,high2,stop) --读入cp2脉冲数
begin
if(cs_cpld = '0' and p0_data(7 downto 5) ="110") then
indata2(7 downto 3) <= p0_data(4 downto 0);
indata2(2 downto 0) <= "000";
elsif stop = '1' then
indata2 <= "00000000";
elsif (low2 = '1' or high2 = '1') then
indata2 <= "00000001";
elsif tclk2'event and tclk2 = '1' then
if indata2 = "00000000" then
indata2 <= indata2;
elsif counter2 = (class2 + class2) then
indata2 <= indata2 - 1;
end if;
end if;
end process;
process(tclk3,p0_data,wr,cs_cpld,low3,high3,stop) --读入cp3脉冲数
begin
if(cs_cpld = '0' and p0_data(7 downto 5) = "111") then
indata3(7 downto 3) <= p0_data(4 downto 0);
indata3(2 downto 0) <= "000";
elsif stop = '1' then
indata3 <= "00000000";
elsif (low3 = '1' or high3 = '1') then
indata3 <= "00000001";
elsif tclk3'event and tclk3 = '1' then
if indata3 = "00000000" then
indata3 <= indata3;
elsif counter3 = (class3 + class3) then
indata3 <= indata3 - 1;
end if;
end if;
end process;
process(tclk1,stop) --产生脉冲cp1
begin
if stop = '0' then
if (cs_cpld = '0' and p0_data(7 downto 5) = "101") then
cp1 <= '1';
ready1 <= '1';
elsif tclk1'event and tclk1 = '1' then
if counter1 = (class1 + class1) then
if indata1 = "00000000" then
cp1 <= '1';
ready1 <= '0';
busy1 <= '0';
else cp1 <= '0';
ready1 <= '1';
busy1 <= '1';
end if;
elsif counter1 = class1 then
cp1 <= '1';
end if;
end if;
elsif stop = '1' then
cp1 <= '1';
ready1 <= '1';
-- busy1 <= '1';
end if;
end process;
process(tclk2) --产生脉冲cp2
begin
if stop = '0' then
if (cs_cpld = '0' and p0_data(7 downto 5) = "110") then
cp2 <= '1';
ready2 <= '1';
elsif tclk2'event and tclk2 = '1' then
if counter2 = (class2 + class2) then
if indata2 = "00000000" then
cp2 <= '1';
ready2 <= '0';
busy2 <= '0';
else cp2 <= '0';
ready2 <= '1';
busy2 <= '1';
end if;
elsif counter2 = class2 then
cp2 <= '1';
end if;
end if;
elsif stop = '1' then
cp2 <= '1';
ready2 <= '1';
-- busy2 <= '1';
end if;
end process;
process(tclk3) --产生脉冲cp3
begin
if stop = '0' then
if (cs_cpld = '0' and p0_data(7 downto 5) = "111") then
cp3 <= '1';
ready3 <= '1';
elsif tclk3'event and tclk3 = '1' then
if counter3 = (class3 + class3) then
if indata3 = "00000000" then
cp3 <= '1';
ready3 <= '0';
busy3 <= '0';
else cp3 <= '0';
ready3 <= '1';
busy3 <= '1';
end if;
elsif counter3 = class3 then
cp3 <= '1';
end if;
end if;
elsif stop = '1' then
cp3 <= '1';
ready3 <= '1';
-- busy3 <= '1';
end if;
end process;
process(low1,low2,low3,high1,high2,high3) --行程开关触位,蜂鸣器鸣叫报警
begin
if(low1 = '1' or low2 = '1' or low3 = '1' or high1 = '1' or high2 = '1' or high3 = '1') then
speak <= '1';
else speak <= '0';
end if;
end process;
process(gclk1,busy1,busy2,busy3) --运行指示灯,电机忙则点亮
begin
if(gclk1'event and gclk1='1') then
if (busy1 = '1' or busy2 = '1' or busy3 = '1') then
run_led <= '0';
else run_led <= '1';
end if;
end if;
end process;
process(stop,low1,low2,low3,high1,high2,high3)
begin
if (stop = '1' or low1 = '1' or low2 = '1' or low3 = '1' or high1 = '1' or high2 = '1' or high3 = '1') then
ready_all <= '1';
int1 <= '0'; --急停键按下或者位置错误则触发外部中断1
else ready_all <= '0';
int1 <= '1';
end if;
end process;
end motor_arch;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -