我这刚好一个问题 我用ALTERA EPM1270做一个时序控制 就是发送固定的频率和固定的脉冲数 其中频率可调用拨码开关控制 脉冲数可控制 用小键盘控制 发送的是俩个信号A和B 相位差90度 但是我发现发送出来的脉冲里有时候开始时B信号被截1/4周期这时候A被截掉整个一个脉冲少了一个 有时候是结束的时候B被截掉1/4个周期这时候A信号可以达到完整输出 不知道问题在哪 下面是这个模块的原程序和注释
-- Generated by Quartus II Version 5.0 (Build Build 148 04/26/2005) -- Update on Wed Jun 06 09:10:40 2007 --验证通过 PASSED!!!
LIBRARY ieee; USE ieee.std_logic_1164.all; USE ieee.std_logic_unsigned.all;
--根据给定的脉冲宽度,产生标准正交ABZ编码器信号。默认整圈为2500个脉冲 --给定的方向:DIR=1,A超前B; DIR=0,B超前A; -- _____ --给定的脉冲宽度 ______| |___________ -- _____ _____ --输出的A脉冲 ______| |_____| |_____ -- _____ _____ --输出的B脉冲 _________| |_____| |_____ -- -- _____ --输出的Z脉冲 ____________| |___________
-- Entity Declaration
ENTITY ORTH_ABZ_GENTR32 IS -- {{ALTERA_IO_BEGIN}} DO NOT REMOVE THIS LINE! PORT ( RST : IN STD_LOGIC; --复位,低有效 CLK : IN STD_LOGIC; --系统时钟 --- LOAD : IN STD_LOGIC; --更新 --- PLS_WIDTH : IN STD_LOGIC_VECTOR(31 downto 0); ---给定的脉冲宽度 --- DIR : IN STD_LOGIC; --给定的方向:DIR=1,A超前B; DIR=0,B超前A; DATA_WIDTH: IN std_logic_vector(7 downto 0); key_in: IN std_logic_vector(3 downto 0); PLS_OUT: OUT std_logic_vector(3 downto 0); A_OUT : OUT STD_LOGIC; B_OUT : OUT STD_LOGIC; Z_OUT : OUT STD_LOGIC; AN_OUT : OUT STD_LOGIC; BN_OUT : OUT STD_LOGIC; ZN_OUT : OUT STD_LOGIC ); -- {{ALTERA_IO_END}} DO NOT REMOVE THIS LINE! END ORTH_ABZ_GENTR32;
-- Architecture Body
ARCHITECTURE ORTH_ABZ_GENTR_architecture OF ORTH_ABZ_GENTR32 IS signal period :STD_LOGIC_VECTOR(31 downto 0); signal half_period :std_logic_vector(31 downto 0); signal po :std_logic:='0'; signal cnt :std_logic_vector(31 downto 0):=(others=>'0'); signal rs_eg,fl_eg :STD_LOGIC; signal q0 :STD_LOGIC:='0'; signal q1 :STD_LOGIC; signal oa,ob,oz :STD_LOGIC; signal circle :STD_LOGIC_VECTOR(15 downto 0):=(others=>'0'); --整圈计数 SIGNAL LOAD :std_logic:='1';
SIGNAL PLS_WIDTH :std_logic_vector(31 downto 0):=X"000000C8"; ---给定的脉冲宽度 SIGNAL DIR :std_logic:='1'; --给定的方向:DIR=1,A超前B; DIR=0,B超前A;
signal in_DATA_3210 :std_logic_vector(3 downto 0); signal in_DATA_4 :std_logic; signal in_DATA_5 :std_logic; signal in_DATA_6 :std_logic; signal mode0123 :std_logic_vector(3 downto 0); SIGNAL PLS_NUMBER :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL PLS_COUNT :std_logic_vector(31 downto 0):=X"00000000"; SIGNAL key_in_old :std_logic_vector(3 downto 0):=X"0"; ------------------更新载入新的脉冲宽度数据 BEGIN process(DATA_WIDTH ,key_in) begin in_DATA_3210<=DATA_WIDTH(3 downto 0); mode0123<=key_in(3 downto 0); in_DATA_4<=DATA_WIDTH(4); in_DATA_5<=DATA_WIDTH(5); in_DATA_6<=DATA_WIDTH(6); DIR<=DATA_WIDTH(7); case in_DATA_3210 is WHEN "0000" => PLS_WIDTH <= X"0000012C"; --125khz WHEN "0001" => PLS_WIDTH <= X"00000177"; --100khz WHEN "0010" => PLS_WIDTH <= X"000001F4"; --75khz WHEN "0011" => PLS_WIDTH <= X"000002EE"; --50khz WHEN "0100" => PLS_WIDTH <= X"000005DC"; --25khz WHEN "0101" => PLS_WIDTH <= X"00000EA6"; --10khz WHEN "0110" => PLS_WIDTH <= X"00001D4C"; --5khz WHEN "0111" => PLS_WIDTH <= X"0000927C"; --1khz WHEN "1000" => PLS_WIDTH <= X"000124F8"; --500hz WHEN "1001" => PLS_WIDTH <= X"00016E36"; --400hz WHEN "1010" => PLS_WIDTH <= X"0001E848"; --300hz WHEN "1011" => PLS_WIDTH <= X"0002DC6C"; --200hz WHEN "1100" => PLS_WIDTH <= X"003D0900"; --100hz WHEN "1101" => PLS_WIDTH <= X"000B71B0"; --50hz WHEN "1110" => PLS_WIDTH <= X"00393870"; --10hz WHEN "1111" => PLS_WIDTH <= X"007270E0"; --5hz
END CASE; end process; process(CLK) --load begin if (clk 'event and clk='1') then if (RST='0') then period<=(others=>'1'); else if (LOAD='1') then period<=PLS_WIDTH; end if ; end if; end if; end process ; -------------------产生周期为脉冲宽度的方波 half_period<= ("0" & period(31 downto 1));-------half period = period/2
process(clk) begin if (key_in/=key_in_old)then cnt<=X"00000001"; else if (clk 'event and clk='1') then cnt<=cnt+1; if cnt<period then if cnt>half_period then po<='1'; else po<='0'; end if; else cnt<=X"00000001"; end if; end if; end if; end process; -------------------检测出方波的上升下降边沿 rs_eg<=q0 and (not(q1)); fl_eg<=q1 and (not(q0)); process(clk) ---上升沿和下降沿检测 begin if (CLK 'event and CLK='1') then q0<=po; q1<=q0; end if; end process ; -------------------利用方波上升和下降沿,把方波二分频 process(clk) begin if (CLK 'event and CLK='1') then if (rs_eg='1') then oa<=not(oa); end if; end if; end process ; ---------------------- process(clk) begin if (CLK 'event and CLK='1') then if (fl_eg='1') then ob<=not(ob); end if; end if; end process ; --------------------根据旋转方向调整控制AB相输出相位 ----------------------Z相整圈脉冲输出 process(clk) begin if (CLK 'event and CLK='1') then if (rs_eg='1') then circle<=circle+1; --整圈脉冲数 = 2500 --MARK=(2500-1)*2 = 4998 = X"1386" if (circle=X"1386") then oz<='1'; circle<=(others=>'0'); else oz<='0'; end if; end if; end if; end process ; process(key_in)
begin
CASE mode0123 is WHEN "0000" => PLS_NUMBER<=X"00000002" ; --1 ---------------------- WHEN "0001" => PLS_NUMBER<=X"00000004" ; --2 ---------------------- WHEN "0010" => PLS_NUMBER<=X"00000006" ; --3 ---------------------- WHEN "0011" => PLS_NUMBER<=X"00000008" ; --4 ---------------------- WHEN "0100" => PLS_NUMBER<=X"0000000A" ; --5 ---------------------- WHEN "0101" => PLS_NUMBER<=X"00000014" ; --10 ---------------------- WHEN "0110" => PLS_NUMBER<=X"00000064" ; --100 ---------------------- WHEN "0111" => PLS_NUMBER<=X"000003E8" ; --1000 ---------------------- WHEN "1000" => PLS_NUMBER<=X"00002710" ; --10000 ---------------------- WHEN "1001" => PLS_NUMBER<=X"000186A0" ; --100000 ---------------------- WHEN "1010" => PLS_NUMBER<=X"000F4240" ; --1000000 ---------------------- WHEN "1011" => PLS_NUMBER<=X"11111111" ; --2147483648 ---------------------- WHEN "1100" => PLS_NUMBER<=X"0000000C" ; ---------------------- WHEN "1101" => PLS_NUMBER<=X"0000000D" ; ---------------------- WHEN "1110" => PLS_NUMBER<=X"0000000E" ; ---------------------- WHEN "1111" => PLS_NUMBER<=X"00000000" ; ---------------------- END CASE; end process ; process(clk) begin if (clk 'event and clk='1') then if(key_in/=key_in_old) then PLS_COUNT<=X"00000000"; key_in_old<=key_in; end if;
if(cnt=X"00000002") then if(PLS_COUNT<PLS_NUMBER) then PLS_COUNT<=PLS_COUNT+1; else PLS_COUNT<=PLS_NUMBER; -- key_in_old<="1111"; end if; end if; PLS_OUT<=PLS_COUNT(3 downto 0); if (PLS_NUMBER<=PLS_COUNT) then if (in_DATA_6='0')then
B_OUT<='0'; A_OUT<='0'; BN_OUT<='0'; AN_OUT<='0'; Z_OUT<= '0'; ZN_OUT<='0'; else B_OUT<='1'; A_OUT<='1'; BN_OUT<='1'; AN_OUT<='1'; Z_OUT<='1'; ZN_OUT<='1'; end if; else if(DIR='1') then B_OUT<=ob; A_OUT<=oa; BN_OUT<=not(ob); AN_OUT<=not(oa); Z_OUT<= oz; ZN_OUT<= not(oz); else B_OUT<=not(ob); A_OUT<=oa; BN_OUT<=ob; AN_OUT<=not(oa); Z_OUT<= oz; ZN_OUT<= not(oz); end if; end if; end if; end process ; END ORTH_ABZ_GENTR_architecture; |