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

📄 dp_test.vhd

📁 本程序是用VHDL语言编写的
💻 VHD
📖 第 1 页 / 共 2 页
字号:
library ieee;
use ieee.std_logic_1164.all;
use	ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;

entity dp_test is
generic	(N:integer :=4);		-- 时钟4分频

port (
clk				: in std_logic;
rst				: in std_logic;

mcu_nwr		    : in  std_logic;    -- mcu的wr
mcu_nrd			: in  std_logic;	   -- mcu的rd
mcu_ncs			: in  std_logic;

data			: inout std_logic_vector(15 downto 0);   --数据总线
Addr_Bus		: in std_logic_vector(5 downto 0);

servo_poisition : in std_logic_vector(15 downto 0);	   --伺服电机位置和外部其他一些信息输入信息
luola_in		: in std_logic_vector(9 downto 0);	   --罗拉位置输入和外部其他一些信息输入

clk_out			: out std_logic;		-- Test

Moto_A_dir		: out std_logic;		-- 步进电机A方向输出
Moto_A_cp		: out std_logic;		-- 步进电机A脉冲输出

Servo_A_dir		: out std_logic;		-- 伺服电机A方向输出
Servo_A_cp		: out std_logic;		-- 伺服电机A脉冲输出

Servo_B_dir		: out std_logic;		-- 伺服电机B方向输出
Servo_B_cp		: out std_logic;		-- 伺服电机B脉冲输出

Servo_A_on		: out std_logic;		-- 伺服电机A伺服控制器使能输出
Servo_B_on		: out std_logic;		-- 伺服电机B伺服控制器使能输出

Servo_A_clr     : out std_logic;		-- 伺服电机A伺服控制器累积脉冲清零输出
Servo_B_clr     : out std_logic;		-- 伺服电机B伺服控制器累积脉冲清零输出

Servo_A_Lock	: in std_logic;			-- MCU发给CPLD的驱动使能信号
Servo_unable	: in std_logic;			
----------------------------------------------------------
Servo_Phase_A	: in  std_logic;		-- 伺服编码器编码输入
Servo_Phase_B	: in  std_logic; 		

servo_cp_test   : out std_logic;		-- 伺服编码器4倍频输出
servo_dir_test	: out std_logic	
--data_out		: out std_logic_vector(3 downto 0)

);
end;

architecture exam of dp_test is

constant Moto	: integer	:=10;
signal 	 count	: integer;
signal	 clk_in	: std_logic;

--SIGNAL Dout     : std_logic_vector(3 downto 0);--总线输出

--步进电机------------------------------------------
signal A_moto	: std_logic_vector(3 downto 0);--步进电机A控制寄存器
signal A_moto_en  :std_logic;		-- 步进电机A使能控制寄存器
signal A_moto_dir :std_logic;		-- 步进电机A方向控制寄存器
signal A_moto_cp  :std_logic;		-- 步进电机A脉冲控制寄存器

signal A_moto_count :integer;		-- 步进电机A脉冲对内部时钟的分频计数器

--伺服电机------------------------------------------
signal A_servo	  : std_logic_vector(7 downto 0); -- 伺服电机A控制寄存器	
signal B_servo	  : std_logic_vector(15 downto 8);-- 伺服电机B控制寄存器	

signal A_sv_enable:std_logic_vector (1 downto 0);-- 伺服电机A使能控制
signal B_sv_enable:std_logic_vector (1 downto 0);-- 伺服电机B使能控制

signal A_sv_clr	  :std_logic;		-- 伺服电机A控制器累积脉冲清零数输出寄存器
signal B_sv_clr	  :std_logic;       -- 伺服电机B控制器累积脉冲清零数输出寄存器

signal A_servo_on :std_logic;		-- 伺服电机A控制器使能输出寄存器
signal B_servo_on :std_logic;		-- 伺服电机B控制器使能输出寄存器

signal A_servo_dir:std_logic;		-- 伺服电机A方向控制寄存器
signal B_servo_dir:std_logic;		-- 伺服电机B方向控制寄存器

signal A_servo_cp :std_logic;		-- 伺服电机A脉冲控制寄存器
signal B_servo_cp :std_logic;		-- 伺服电机B脉冲控制寄存器

signal A_phase_ctr: std_logic;		-- 伺服电机A脉冲相位输出控制寄存器
signal B_phase_ctr: std_logic;		-- 伺服电机B脉冲相位输出控制寄存器

signal A_servo_fre:integer ;  		-- 伺服电机A频率输出寄存器
signal B_servo_fre:integer ;  		-- 伺服电机B频率输出寄存器

signal A_fre_buf:integer ;  		-- 伺服电机A频率输出缓存
signal B_fre_buf:integer ;  		-- 伺服电机B频率输出缓存

signal A_servo_stop:std_logic;		-- 伺服电机A因为到了行程极限而停止
signal B_servo_stop:std_logic;		-- 伺服电机B因为到了行程极限而停止

signal A_run_state:std_logic_vector(1 downto 0); --伺服电机运行状态
signal B_run_state:std_logic_vector(1 downto 0); --伺服电机运行状态

signal	A_speed_ctr :std_logic_vector(3 downto 0);	-- 伺服电机A速度控制寄存器
signal	B_speed_ctr :std_logic_vector(3 downto 0);	-- 伺服电机B速度控制寄存器

signal 	A_servo_counter :integer;	-- 伺服电机A脉冲控制计数器
signal 	B_servo_counter :integer;	-- 伺服电机B脉冲控制计数器

signal	 A_frequecy:integer	range	0 to 200;	-- 伺服电机A频率输出控制字
constant A_fre_min:integer:=2000;  -- 伺服电机A频率输出最小控制寄存器


constant A_fre_max0:integer:=156;	-- 伺服电机A频率输出第0档最大控制寄存器
constant A_fre_max1:integer:=104;	-- 伺服电机A频率输出第1档最大控制寄存器
constant A_fre_max2:integer:=78;	-- 伺服电机A频率输出第2档最大控制寄存器
constant A_fre_max3:integer:=62;	-- 伺服电机A频率输出第3档最大控制寄存器
constant A_fre_max4:integer:=52;	-- 伺服电机A频率输出第4档最大控制寄存器
constant A_fre_max5:integer:=46;	-- 伺服电机A频率输出第5档最大控制寄存器
constant A_fre_max6:integer:=40;	-- 伺服电机A频率输出第6档最大控制寄存器
constant A_fre_max7:integer:=36;	-- 伺服电机A频率输出第7档最大控制寄存器
constant A_fre_max8:integer:=32;	-- 伺服电机A频率输出第8档最大控制寄存器
constant A_fre_max9:integer:=26;	-- 伺服电机A频率输出第9档最大控制寄存器


constant B_fre_min:integer:=80000;  -- 伺服电机B频率输出最小控制寄存器
constant B_fre_max:integer:=40;		-- 伺服电机B频率输出最大控制寄存器

----------------------------------------------------------------------
------编码器--------

signal	Not_A_phase_a		:std_logic;		-- 伺服电机编码器读取
signal	A_phase_a			:std_logic;		
signal	A_phase_b			:std_logic;

signal	A_cw_test			:std_logic;		-- 测试
signal	A_ccw_test			:std_logic;
signal	A_servo_count_clr	:std_logic_vector(1 downto 0);

signal	A_servo_pdir:std_logic; 							-- 伺服电机A编码器反馈的方向
signal	A_servo_cp_clr		:std_logic;						-- 伺服电机A编码器读数清零

signal	A_cp_number		:std_logic_vector(15 downto 0); -- 伺服电机A编码器读数存储
signal	A_servo_cp_cw	:std_logic_vector(15 downto 0); -- 伺服电机A编码器正向脉冲读数存储
signal	A_servo_cp_ccw	:std_logic_vector(15 downto 0); -- 伺服电机A编码器反向脉冲读数存储
signal	A_servo_cp_temp	:std_logic_vector(15 downto 0); -- 伺服电机A编码器读数缓存


signal	A_servo_count:integer;

signal	B_servo_count_clr	:std_logic_vector(1 downto 0);
signal	B_servo_cp_clr		:std_logic;

signal	cpld_mcu_interupt	:std_logic;	--CPLD发送给MCU的中断信号寄存器
------------------------------------------------------------
begin

process(clk)
begin
	if(clk'event and clk ='1')	then
		if(count =N-1) then     count<= 0;
		else  		count <=count +1;
			if count < (integer (N/2)) then	clk_in <= '0';
			else		clk_in<= '1';
			end if;
		end if;
	end if;
end process;

clk_out <= clk_in;
--data_out<= Dout; 

Moto_A_cp  <= A_moto_cp;		-- 步进电机A控制输出
Moto_A_dir <= A_moto_dir;

--Read :process (mcu_nrd,mcu_ncs,servo_poisition,luola_in,A_cp_number,Addr_Bus)
Read:	process(clk_in)
	begin
		if (clk_in'event and clk_in ='1')	then
			if	(mcu_nrd='0' and mcu_ncs ='0')	then
				case	Addr_Bus	is
					when	"000000"	=>		data <= servo_poisition;				 	-- 地址0x00000000读取伺服位置等信息
					when	"000001"	=>		data <= "000000" & luola_in ;				-- 地址0x00000002读取罗拉位置等信息
					when	"000010"  =>		data <=	A_cp_number(15 downto 0);		--地址0x00000004读取伺服电机A的低16位值
					when	"000011"  =>		data <=	A_cp_number(15 downto 0);	--地址0x00000006读取伺服电机A的高4位值
					when	others =>	data <="0000000000000000";
				end	case;
			else
				data <="ZZZZZZZZZZZZZZZZ";
			end if;
		end if;
end process	Read;
	
Write :process	(clk_in,rst)
	begin
		if (clk_in'event and clk_in ='1')	then
			if	rst = '0' then		A_moto <= "0000";			-- 电机控制字初始化
									A_servo<= "00000000";
									B_servo<= "00000000";
			else
				if	(  mcu_nwr = '0' and mcu_ncs ='0' ) then
					case	Addr_Bus	is
						when	"001000"	=>		A_moto <= data (3 downto 0);			-- 地址0x00000010写步进电机控制信息
						when	"001001"	=>		A_servo<= data (7 downto 0);   			-- 地址0x00000012写伺服电机A控制信息
						when	"001010"	=>		B_servo<= data (7 downto 0);			-- 地址0x00000014写伺服电机B控制信息
						when	"001111"	=>		A_servo_count_clr <= data (1 downto 0); -- 地址0x00000016写伺服电机A编码器清零信息
						when	"001100"	=>		B_servo_count_clr <= data (1 downto 0);	-- 地址0x00000018写伺服电机B编码器清零信息
												
						when	"001011"	=>		A_sv_enable<= data (1 downto 0);		-- 地址0x0000001a写伺服电机A使能信息
						when	"001110"	=>		B_sv_enable<= data (1 downto 0);		-- 地址0x0000001c写伺服电机B使能信息				
						when	others  =>			A_moto <= A_moto;			-- 电机控制字初始化
													A_servo<= A_servo;
													B_servo<= B_servo;							
					end 	case;
				end if;
		end if;
	end if;
end process	Write;

--步进电机A控制---------------------------------------
Moto_A: process	(A_moto,rst)		-- 步进电机控制进程
	begin
	if rst ='0' then	A_moto_en<= '0'; A_moto_dir <= '0';		-- 复位方向为正方向,不发脉冲
	else
	-- A_moto第0位为使能控制位 0->关 1->开  
	-- A_moto第1位为方向控制位 0->正方向  1->反方向  
		case	A_moto	is											
		when	"0000"	=>		A_moto_en<= '0'; A_moto_dir <= '0';	
		when	"0001"	=>		A_moto_en<= '1'; A_moto_dir <= '0';	
		when	"0011"  =>		A_moto_en<= '1'; A_moto_dir <= '1';	
		when	others  =>		A_moto_en<= '0'; A_moto_dir <= '0';
		end 	case;
	end 	if;		
end process Moto_A;

Moto_A_Run: process (clk_in,rst,A_moto_en)		-- 步进电机脉冲产生进程
	begin
	if	(rst ='0' or A_moto_en ='0')  then	A_moto_cp <='0';
	else
		if (clk_in'event and clk_in ='1')	then
			if(A_moto_count =Moto-1) then     A_moto_count<= 0;
			else  		A_moto_count <=A_moto_count +1;
				if  A_moto_count < (integer (Moto/2)) then	A_moto_cp <= '0';
				else		A_moto_cp<= '1';
				end if;
			end if;
		end if;
	end if;	
end  process  Moto_A_Run;	
-------------------------------------------------------------
-------------------------------------------------------------
A_servo_sensor_test:process(clk_in,rst)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -