打印

我用ALTERA EPM1270做一个时序控制 大家帮忙看下问题出在哪?

[复制链接]
2363|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
风中De舞者|  楼主 | 2007-9-4 17:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
我这刚好一个问题  我用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;

相关帖子

沙发
端木| | 2007-9-16 23:00 | 只看该作者

请问你出来的结果是仿真的还是实际测试的?

    请问你出来的结果是仿真的还是实际测试的?看到你说还有外部的拨码控制,建议,你把输入条件简化,一步步测试,可能比较容易找到问题。

     个人看法,呵呵

使用特权

评论回复
板凳
风中De舞者|  楼主 | 2007-9-17 15:37 | 只看该作者

问题已经解决了 21IC上好象比较缺经验丰富的高手啊。。。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

32

主题

287

帖子

1

粉丝