找回密碼
 立即注冊(cè)

QQ登錄

只需一步,快速開始

搜索
查看: 5795|回復(fù): 8
打印 上一主題 下一主題
收起左側(cè)

求增量式正交旋轉(zhuǎn)編碼器的Verilog HDL鑒相代碼

[復(fù)制鏈接]
跳轉(zhuǎn)到指定樓層
樓主
ID:199427 發(fā)表于 2018-12-28 13:22 | 只看該作者 |只看大圖 回帖獎(jiǎng)勵(lì) |倒序?yàn)g覽 |閱讀模式
30黑幣
求增量式正交旋轉(zhuǎn)編碼器的Verilog HDL鑒相代碼

      需要使用大約13個(gè)增量式正交旋轉(zhuǎn)編碼器設(shè)定值,stm32的定時(shí)器不夠用,用中斷需要13個(gè)中斷,不太方便,stm32的引腳也不太好分配。想用EPM1270(LQFP-144)讀取13個(gè)旋轉(zhuǎn)編碼器的值,再串行傳送給stm32進(jìn)行處理。
      CSDN.NET上有代碼,沒有帳號(hào),且需要購(gòu)買。請(qǐng)問哪位前輩能提供?先感謝了!



分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復(fù)

使用道具 舉報(bào)

沙發(fā)
ID:199427 發(fā)表于 2018-12-29 13:38 | 只看該作者
本帖最后由 wxyz 于 2018-12-29 15:04 編輯

旋轉(zhuǎn)編碼器的A和B分別用5.1K電阻上拉到3.3V,再用0.1uF電容對(duì)地濾波消除抖動(dòng)和干擾。
借助單片機(jī)中斷模式的思路:

在上升邊沿觸發(fā)模式下,A和B進(jìn)行電平比較:
對(duì)A觸發(fā)的中斷:同加異減
對(duì)B觸發(fā)的中斷:同減異加

采用對(duì)A觸發(fā)的上升沿中斷模式,簡(jiǎn)單的Verilog HDL如下:

  1. always @(posedge RotaryEncoder01Aphase)  // A的上升沿
復(fù)制代碼

根據(jù)以前單片機(jī)中斷模式的調(diào)試經(jīng)驗(yàn),編碼器有漏計(jì)數(shù)情況,計(jì)數(shù)不連續(xù)遞增或遞減,編碼器的抖動(dòng)干擾會(huì)造成漏計(jì)數(shù)情況。單片機(jī)可以采用延時(shí)消除抖動(dòng)干擾,但Verilog HDL中不知道如何解決?




回復(fù)

使用道具 舉報(bào)

板凳
ID:439075 發(fā)表于 2018-12-30 11:18 | 只看該作者
簡(jiǎn)單的代碼比較好做,可能對(duì)于抖動(dòng)濾波做的不好,真正的消抖效果需要靠實(shí)際環(huán)境考核才能驗(yàn)證。
說(shuō)個(gè)簡(jiǎn)單方法,先設(shè)法獲取A、B相的上升沿和下降沿,每個(gè)沿都觸發(fā)同一個(gè)移位寄存器,取本次(D1、D0)及上次(D3、D2)的鎖存值共四位,即D3、D2、D1、D0。判斷方式為D3和D0相同(D2和D1不同)則正向,相反則為反向。這個(gè)方法你通過波形圖分析就可以推導(dǎo)出來(lái)。
回復(fù)

使用道具 舉報(bào)

地板
ID:199427 發(fā)表于 2018-12-30 15:37 | 只看該作者
謝謝 bucker 答復(fù)!沒有完全理解您的思路。簡(jiǎn)單寫了如下代碼:


復(fù)制代碼
沒有測(cè)試。不知道對(duì)不對(duì)?



回復(fù)

使用道具 舉報(bào)

5#
ID:199427 發(fā)表于 2018-12-30 19:18 | 只看該作者
添加代碼后,排版格式亂了。再發(fā)一次。
wire A, B;
reg [1:0] ABtimes;
reg period;
reg [3:0] shift_register,  [3:0] buffer0,   [3:0] buffer1;
reg [15:0] Counter;


always @(posedge A or posedge B or negedge A or negedge B)     
begin
   ABtimes = ABtimes +1;
   shift_register[3:0] = {shift_register[2:0], 1};   //  拼接1到最低位


   if(ABtimes == 3)  //  00-01-10-11  編碼器經(jīng)過了 A上升、B上升、A下降和B下降四步
   begin
           if(period == 0)
           begin
                  period = 1;    // 第二個(gè)周期
                  buffer1 =  shift_register;     //  暫存第二個(gè)周期的移位寄存器值
           end
           else
           begin
                 period = 0;     // 第一個(gè)周期
                 buffer0 =  shift_register;     //  暫存第一個(gè)周期的移位寄存器值
           end
   end
     
   if((ABtimes == 3)&& (period == 1))  //  編碼器經(jīng)過四步和第二個(gè)周期
   begin
       if ((buffer0[3:3]==buffer1[0:0])&& (buffer0[2:2]==buffer1[1:1])) // D3和D0相同(D2和D1不同)
            Counter <= Counter + 1;
      else
            Counter <= Counter - 1;


      shift_register <=  0;   //  清零
   end  


end



回復(fù)

使用道具 舉報(bào)

6#
ID:199427 發(fā)表于 2018-12-31 08:56 | 只看該作者
      if ((buffer0[3:3]==buffer1[0:0])&& (buffer0[2:2]==buffer1[1:1])) // D3和D0相同(D2和D1不同)
修改為

      if ((buffer0[3:3]==buffer1[0:0])&& (buffer0[2:2]!=buffer1[1:1])) // D3和D0相同(D2和D1不同)
回復(fù)

使用道具 舉報(bào)

7#
ID:199427 發(fā)表于 2019-1-2 09:49 | 只看該作者
又看了其他的資料,大概理解了鑒相的思路,如下圖所示:

通過光時(shí),A或B為低電平。遮擋光時(shí),A或B為高電平。A的讀出值序列為1-0-0-1,B的值序列為1-1-0-0,旋轉(zhuǎn)編碼器為順時(shí)針旋轉(zhuǎn)。A的讀出值序列為1-1-0-0,B的值序列為1-0-0-1,與順時(shí)針值相反,旋轉(zhuǎn)編碼器為逆時(shí)針旋轉(zhuǎn)。

回復(fù)

使用道具 舉報(bào)

8#
ID:199427 發(fā)表于 2019-1-6 11:28 | 只看該作者
在《阿莫電子論壇》上找到了代碼,鏈接如下:
www點(diǎn)amobbs點(diǎn)com/thread-840211-1-1.html


CPLD應(yīng)用:光柵旋轉(zhuǎn)編碼器的4倍頻解碼

發(fā)表于 2007-10-27 10:22:55 | 只看該作者 回帖獎(jiǎng)勵(lì)
CPLD應(yīng)用:增量式光柵旋轉(zhuǎn)編碼器的4倍頻解碼

剛學(xué)了幾天的CPLD,上傳我的第一個(gè)應(yīng)用,不知道實(shí)際工作情況如何,希望高手指點(diǎn)指點(diǎn),謝謝

如果CLK時(shí)鐘頻率為25Mhz,則至少可以對(duì)輸出頻率2.5Mhz以下增量式光柵旋轉(zhuǎn)編碼器的進(jìn)行4倍頻解碼

概念如下:

增量式光柵旋轉(zhuǎn)編碼器分辨率:2500p/r (常用伺服系統(tǒng)的編碼器)
按工作時(shí)最大的輸出頻率為2.5Mhz計(jì)算,編碼器可以工作到60000r/m,當(dāng)然這樣的旋轉(zhuǎn)速度實(shí)際上是很難達(dá)到的,實(shí)際上的常用的伺服電機(jī)最大工作到5000r/m

CLK:倍頻用時(shí)鐘頻率
A:編碼器A相
B:編碼器B相

CP:解碼后的脈沖
DIR:旋轉(zhuǎn)方向

仿真圖片如下:





Verilog hdl代碼:

module decoder(CLK, A, B, CP, DIR);
        input CLK;
        input A;
        input B;
        output CP;
        output DIR;

        reg CP;
        reg DIR;

        wire a_xor_b;
        reg a_xor_b_temp;
        reg[3:0] a_xor_b_counter;


        xor (a_xor_b, A, B);        

        always @(posedge CLK)
                begin               
                if(a_xor_b_temp != a_xor_b)
                        begin
                        CP = 1'b1;
                        a_xor_b_temp = a_xor_b;                        
                        a_xor_b_counter = 4'b0000;
                        end
                else
                        begin
                        a_xor_b_counter = a_xor_b_counter + 4'b0001;
                        if(a_xor_b_counter >= 4'b0010)                 // 根據(jù)實(shí)際應(yīng)用,可以改變a_xor_b_counter上限值來(lái)改變輸出脈寬
                                begin
                                CP = 1'b0;
                                end                                
                        end
                end

        always @(posedge A) begin
                DIR = ~B;
        end

endmodule

不明白,為什么編碼器還要外接時(shí)鐘?





回復(fù)

使用道具 舉報(bào)

9#
ID:328014 發(fā)表于 2019-1-10 00:29 | 只看該作者
mark幫頂下
回復(fù)

使用道具 舉報(bào)

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表