40130064 发表于 2011-7-19 17:11:34

增量式光电编码器计数器程序(VHDL),欢迎各位测试拍砖.

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
ENTITY ABC IS
   PORT (
      clk                     : IN std_logic;   
      clr                  : IN std_logic;   
      a                     : IN std_logic;   
      b                     : IN std_logic;   
      counter               : BUFFER std_logic_vector(23 DOWNTO 0));   
END ABC;

ARCHITECTURE epm570 OF ABC IS
   SIGNAL cot               :std_logic_vector(1 DOWNTO 0);      
   SIGNAL prestate            :std_logic_vector(1 DOWNTO 0);   
   SIGNAL state               :std_logic_vector(1 DOWNTO 0);   
   SIGNAL judge               :std_logic_vector(3 DOWNTO 0);   
   SIGNAL dire_0            :std_logic;   
   SIGNAL cp_0                :std_logic;   

BEGIN
   PROCESS(clr,clk)
   BEGIN
   IF(clr = '1')THEN
   cot<=(OTHERS=>'0');
   prestate <=(OTHERS=>'0');
   state<=(OTHERS=>'0');
   judge <=(OTHERS=>'0');
   dire_0<='0';
   cp_0 <='0';
   ELSE
           IF (clk'EVENT AND clk = '1')THEN
                  state(1) <= a;   
                  state(0) <= b;   
                  prestate <= state;
                  judge <= prestate&state;
                                CASE judge IS
                                WHEN "0010"=>cp_0 <= '1';dire_0 <= '1';        
                                WHEN "1011"=>cp_0 <= '1';dire_0 <= '1';   
                                WHEN "1101"=>cp_0 <= '1';dire_0 <= '1';   
                                WHEN "0100"=>cp_0 <= '1';dire_0 <= '1';   
                                WHEN "0001"=>cp_0 <= '1';dire_0 <= '0';   
                                WHEN "0111"=>cp_0 <= '1';dire_0 <= '0';   
                                WHEN "1110"=>cp_0 <= '1';dire_0 <= '0';   
                                WHEN "1000"=>cp_0<= '1';dire_0<= '0';
                                WHEN OTHERS => NULL;
                                END CASE;
                        IF (cp_0 = '1') THEN
                                cot <= cot + "01";
                        END IF;
                          
                        IF (cot = "01") THEN
                                cot <= "00";   
                                cp_0 <= '0';   
                        END IF;               
                END IF;
                END IF;
   END PROCESS;

PROCESS(cp_0,clr,dire_0)
VARIABLE direction :INTEGER RANGE -1 TO 1;
BEGIN
        IF(dire_0 = '1') THEN
        direction :=1;
        ELSE
        direction :=-1;
        END IF;
          
        IF(clr = '1')THEN --
        counter <= (OTHERS=>'0') ;   
        ELSE
                IF (cp_0'EVENT AND cp_0 = '0')THEN
                counter <= counter + direction;
                END IF;
        END IF;
END PROCESS;
END epm570;

scfor 发表于 2011-7-21 08:45:10

学习 帮顶了

nightwish0227 发表于 2011-7-21 09:01:23

module encoder(clk,reset,encoder_a,encoder_b,count_data);
input clk;
input reset;
input encoder_a;
input encoder_b;
output count_data;
reg    current_state;
reg    next_state;       
reg    count_data;
always@(posedge clk)
        if(!reset)
                begin
                        current_state<=2'b00;
                        next_state<=2'b00;
                end
                else
                        begin
                                current_state<=next_state;
                                next_state<={encoder_a,encoder_b};
                        end
always@(posedge clk)
        if(!reset)
                count_data<=2'b00;
        else
                case(current_state):
                        2'b00:
                                if(next_state==2'b01)
                                        count_data<count_data+32'b1;
                                else if(next_state=2'b10)
                                        count_data<count_data-32'b1;
                                        else
                                                count_data<=count_data;
                        2'b01:
                                if(next_state==2'b11)
                                        count_data<count_data+32'b1;
                                else if(next_state=2'b00)
                                        count_data<count_data-32'b1;
                                        else
                                                count_data<=count_data;
                        2'b11:
                                if(next_state==2'b10)
                                        count_data<count_data+32'b1;
                                else if(next_state=2'b01)
                                        count_data<count_data-32'b1;
                                        else
                                                count_data<=count_data;
                        2'b10:
                                if(next_state==2'b00)
                                        count_data<count_data+32'b1;
                                else if(next_state=2'b11)
                                        count_data<count_data-32'b1;
                                        else
                                                count_data<=count_data;
                        default:
                                count_data<=count_data;
                 endcase
endmodule

我用verilog HDL写了一个,已通过测试。VHDL的语言不是很熟,回头看看语法去

scfor 发表于 2011-7-21 09:43:38

正反转的脉冲都正确么
页: [1]
查看完整版本: 增量式光电编码器计数器程序(VHDL),欢迎各位测试拍砖.