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