---
# System prepended metadata

title: STM的QEP
tags: [STM32]

---

[TOC]

# QEP
- 介紹可見[新訓FPGA](https://hackmd.io/gcwxE_ENSviIpOjB_HLSuQ)中的新訓項目3

# STM的QEP

## 簡介
- 見rm0090 17.3.16
- STM的encoder interface利用timer的計數與邊沿檢測功能實現QEP對encoder的計數功能
- 高級timer 1、8，和通用timer 2~5才有encoder interface可以使用，如果不夠用就要用外部中斷方式在軟體內部自行計算了
- QEP的實現使用timer中的兩個channel對A、B相訊號做輸入捕獲，計數器再依據捕獲訊號做計數

## 原理
- 捕獲訊號與計數器邏輯關係可見rm0090 Table 93.
- 時序圖
    ![image](https://hackmd.io/_uploads/rJLHVru2A.png)

## CubeMX 配置
- 使用timer 2為例
- mode設定
    - 因為使用兩個通道，所以在combined channel中選擇Encoder Mode
    ![image](https://hackmd.io/_uploads/S1-sEH_nR.png)
- 參數設定
    ![image](https://hackmd.io/_uploads/B1xECBB_hR.png)
    - 注意現在是使用輸入捕獲概念做計時器觸發，所以Counter Setting對計數影響要注意
        - prescaler與period直接影響計數範圍，計數範圍決定PWM方波的頻率
        - counter mode 不用變更
        - CKD 與 auto-reload preload不設置
        - TRGO 維持
    - Encoder參數
        - Encoder Mode 選TI1 and TI2。因為使用AB相編碼器的A、B輸入才能判別旋轉方向
        - 下面是對兩個channel的設定，兩個都選rising edge即可，其餘不用動


## 程式編寫
- 在user code begin 2 區段加入這行，啟用計時器功能
    ``` c++=
    HAL_TIM_Encoder_Start(&htim2, TIM_CHANNEL_ALL);
    ```
    注意TIM_CHANNEL_ALL的使用一樣是從函式註解得知的喔
- 因為QEP機制在timer內已經實現了，timer 的計數器本身就是編碼器的計數值，直接在需要讀取計數值的地方加入這行
    ``` c++=
    counter = __HAL_TIM_GET_COUNTER(&htim2);
    ```
# 練習1 
- 將馬達的編碼器供電，將AB相連接至Timer encoder mode對應的腳位
- 宣告一個全域變數並在主迴圈中讀取計數值
- 燒錄程式並進入debug mode，把變數值加近watch window
- 執行程式，並轉動馬達，觀察計數變化


