STM32正交編碼器驅動電機

1。編碼器原理
       什麼是正交?若是兩個信號相位相差90度,則這兩個信號稱爲正交。因爲兩個信號相差90度,所以能夠根據兩個信號哪一個先哪一個後來判斷方向。算法

 

 

 

這裏使用了TI12模式,例如當T1上升沿,T2在低電平時;T1降低沿,T2在高電平時,向上計數,這樣的好處是當有毛刺產生的時候,會自動+1 -1過濾掉毛刺。編碼

2。編碼器的中斷blog

因爲編碼器是基於定時器的,因此編碼器的中斷實際上就是定時器的中斷。也就是說定時器是每隔必定時間加一個數(或減一個數 ),當數到達預設值時就產生中斷,而編碼器是每個有效脈衝就加一個數(或減一個數 ),當數到達預設值時就產生中斷。若預設值爲1000則編碼器與定時器中斷不一樣的是,當編碼器反轉時值到達999產生一次中斷,而當編碼器正轉到達0時同 樣產生一次中斷。在硬件上這兩個中斷是無法區分的,這也就形成了有種狀況的誤判。io

3。STM32編碼器沒有考慮的狀況ast

想象一下,若是編碼器的預設值爲1000,當某次咱們使得編碼器正轉產生中斷後,當即反轉則又該怎麼辦呢?根據上面的說法,這時候會產生兩次同樣的中斷。 若是在算法上沒有處理的話,極有可能認爲是行走了兩次正向。但實際上並無。因此這個時候必須結合方向來判斷行走的狀況(判斷方向使用的是DIR寄存器 位)或者在產生中斷後讀一次count寄存器位(看看是999仍是0,以此來判斷當前的方向)。只有上一次爲正且這一次一樣爲正,距離纔是相加的。變量

4。STM32f1系列定時器16位的問題原理

我用STM32的定時器3工做於編碼器方式,能夠正常獲得編碼器位置,但因爲如今只有16位計數,位數不夠,我想擴展到32位,能夠先用定時器內部鏈接,將定時器3 的溢出送到定時器2,用定時器2作高位,在正轉的時候正常,但反向的時候出錯。換了個思路,作個每10ms產生一次的中斷,在中斷中調用下面的代碼,下述代碼中MAX_COUNT是 比 10ms內可能出現的計數最大值還要大的值,ENCODER_TIM_PERIOD是定時器的period值,最比如MAX_COUNT大,而後定義一個32位的有符號變量,如currentCount,而後每隔10ms執行一次currentCount += Enc_GetCount();只須要去讀取currentCount的值就能夠獲得位移信息了。擴展

s16   Enc_GetCount(void)
{
    static  u16   lastCount = 0;
    u16  curCount = ENCODER_TIM->CNT;
    s32 dAngle = curCount - lastCount;
    if(dAngle >= MAX_COUNT){
      dAngle -= ENCODER_TIM_PERIOD;
    }else if(dAngle < -MAX_COUNT){
      dAngle += ENCODER_TIM_PERIOD;
    }
    lastCount = curCount;
    return (s16)dAngle;
}軟件

5。其它一些獲得的信息硬件

1.編碼器有個轉速上限,超過這個上限是不能正常工做的,這個是硬件的限制,原則上線數越多轉速就越低,這點在選型時要注意,編碼器的輸出通常是開漏的,因此單片機的io必定要上拉輸入狀態. 2.定時器初始化好之後,任什麼時候候CNT寄存器的值就是編碼器的位置信息,正轉他會加反轉他會減這部分是不須要軟件干預的,初始化時給的TIM_Period 值應該是碼盤整圈的刻度值,在減溢出會自動修正爲這個數.加超過此數值就回0. 3.若是要擴展成多圈計數須要溢出中斷,程序上圈計數加減方向位就好了. 4.每一個定時器的輸入腳能夠經過軟件設定濾波 5.應用中若是沒有絕對位置信號或者初始化完成後尚未收到絕對位置信號前的計數只能是相對計數.收到絕對位置信號後從新修改一次CNT的值就好了.碼盤通常都有零位置信號,結合到定時器捕獲輸入就行.上電之後要往返運動一下找到這個位置. 6.即使有濾波計數值偶爾也會有出錯誤的狀況,一圈多計一個或少計一個數都是很正常的特別是轉速比較高的時候尤爲明顯,有個絕對位置信號作修正是頗有必要的.絕對位置信號不須要必定在零位置點,收到這個信號就將CNT修正爲一個固定的數值便可. 7.開啓定時器的輸入中斷能夠達到每一個步計數都做處理的效果,可是高速運轉的時候你可能處理不過來.

相關文章
相關標籤/搜索