这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 嵌入式开发 » 软件与操作系统 » 利用PLD完成旋转编码器计数输出任务

共1条 1/1 1 跳转至

利用PLD完成旋转编码器计数输出任务

工程师
2015-04-29 21:09:46     打赏

这段程序是我用来完成编码器解码输出的程序。编码器的输入是由双路相位相差90度的方波组成,左旋还是右旋就是依靠谁的相位超前判断。用pld完成去抖动并且按照一定的周期整形输出,效果完美,单是程序上可能还需要有改进,主要是否还能简化!请了解的朋友指出,大家一同探讨!


 


module freek5 (fly,u3bq,u3aq,outled,leftin,rightin,rst,gobleclk,pulse,direct);
input [1:0] fly;
input leftin,rightin,rst;
input gobleclk;
output u3bq,u3aq,pulse,direct;
output [3:0] outled;


wire a,b,c,d;
wire u5a,u5b;
wire inrst;

 

reg u1aq,u1aqb;
reg u1bq,u1bqb;
reg u2aq;
reg u2bq;
reg u3bq;
reg u3aq;
reg [9:0] leftin_counter ;
reg [9:0] rightin_counter;
reg   [15:0] pulsecounter;
reg   [9:0] leftin_stack;
reg   [9:0] rightin_stack;
reg pulse;
reg direct;

assign outled = 4'b0101;
assign inrst = ~rst;
assign u5a = a&u1bqb;
assign u5b = c&u1aqb;


always @(u5a or d )

begin
case ({u5a,d})

2'b00 : begin
        u1aq  = u1aq;
        u1aqb = u1aqb;
        end

2'b10: begin
       u1aq  = 1'b1;
       u1aqb = 1'b0;
       end

2'b01: begin
       u1aq = 1'b0;
       u1aqb = 1'b1;
       end
endcase
end

 

 


always @(u5b or d )

begin
case ({u5b,d})

2'b00: begin
       u1bq = u1bq;
       u1bqb = u1bqb;
       end
2'b10 : begin
        u1bq  =1'b1;
        u1bqb = 1'b0;
        end
2'b01 : begin
        u1bq = 1'b0;
        u1bqb = 1'b1;
        end
endcase
end


always @(posedge a or posedge c  or posedge inrst )
begin
     if ( inrst == 1'b1)
         begin
         u2aq = 1'b0;
         //u2aqb = 1'b1;
         end
 else         
begin
      if ( a==1'b1)
         begin
         u2aq  =1'b0;
         //u2aqb =1'b1;
         end
       else
          begin
          if (c == 1'b1)
             begin
             u2aq = u1aq;
             //u2aqb = ~u2aq;
             end
          else 
             begin
             u2aq =u2aq;
             //u2aqb =~u2aqb;
             end
          end
end
end

always @(posedge a or posedge c or posedge inrst)
begin
        if (inrst ==1'b1)
           begin
           u2bq = 1'b0;
           //u2bqb = 1'b1;
           end
else
begin
         if (c==1'b1)
             begin
             u2bq  =1'b0;
             //u2bqb =~u2bqb;
             end
          else
             begin
             if (a == 1'b1)
                 begin
                 u2bq = u1bq;
                 end
               else
                  u2bq = u2bq;
              end
end
end

always @(posedge d or posedge a or posedge inrst)
begin
   if (inrst == 1'b1)
       begin
       u3aq = 1'b0;
       end
else
begin
       if (a==1'b1)
           begin
           u3aq = 1'b0;
           end
       else
           begin
           if (d==1'b1)
              u3aq = u2aq;
            else
               u3aq = u3aq;
            end
end
end

always @(posedge d or posedge c or posedge inrst)
begin
        if (inrst== 1'b1)
            begin
            u3bq = 1'b0;
            end
begin
        if ( c == 1'b1)
            begin
            u3bq = 1'b0;
            end
         else
            begin
             if (d==1'b1)
                 u3bq = u2bq;
              else
                 u3bq =u3bq;
             end
end
end
                 
             
assign {d,a,b,c}  = decode (fly);

function [3:0] decode;
input  [1:0] fly;

case (fly)
2'b11 : decode = 4'b1000;
2'b01 : decode = 4'b0100;
2'b00 : decode = 4'b0010;
2'b10 : decode = 4'b0001;
endcase

endfunction


always @(posedge rightin or negedge rst)
begin
if (rst == 1'b0)
   begin
   rightin_counter = 10'b0000_0000_00;
   end
else
if (leftin ==1'b0)
   begin
   rightin_counter = rightin_counter+1;
   end

end

always @(posedge leftin or negedge rst)
begin
   if (rst == 1'b0)
      begin
      leftin_counter = 10'b0000_0000_00;
      end
   else
       if (rightin == 1'b0)
        begin
           leftin_counter = leftin_counter +1;
        end
end


always @(posedge gobleclk or negedge rst)
begin
    if (rst == 1'b0)
        begin
        pulsecounter = 16'b0000_0000_0000_0000;
        rightin_stack = 10'b0000_0000_00;
        leftin_stack  = 10'b0000_0000_00;
        end
     else
        begin
        pulsecounter = pulsecounter +1;
        
           if (pulsecounter == 16'b1111_1111_1111_1111)
            begin
            if (pulse == 1'b1)
                begin
                if ( rightin_counter>rightin_stack)
                    begin
                    pulse = 1'b0;
                    direct = 1'b1;
                    rightin_stack = rightin_stack +1;
                    pulsecounter = 20'b0000_0000_0000_0000_0000;
                    end
                else
                   begin
                    if (leftin_counter >leftin_stack)
                         begin
                         pulse = 1'b0;
                         direct =1'b0;
                         leftin_stack = leftin_stack+1;
                         pulsecounter = 20'b0000_0000_0000_0000_0000;
                         end
                     else
                        begin
                          leftin_stack = leftin_stack;
                           rightin_stack =rightin_stack;
                          end
                        end
                    end
            else
               begin
               pulse =1'b1;
               end
            end      // end
            else
              begin
              pulse = pulse;
              end
        end
end

 

endmodule

 



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]