⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 motor.vhd

📁 ALTEA EPM7128 CPLD的用于控制三维步进电机的VHDL源代码
💻 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 + -