首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> 關於C

嵌入式編碼器掃描算法實現:正反轉脈衝計數與按鍵復位

     編輯:關於C

項目背景

本文記錄一款基於單片機的編碼開關(旋轉編碼器)掃描驅動程序,實現正反轉方向識別、脈衝計數累加/遞減、按鍵復位計數器功能。代碼採用輪詢方式,包含去抖動延時邏輯,適合資源受限的嵌入式環境。

硬件接口定義

// 編碼器 A 相 -> P4.2,需外接 680Ω 上拉電阻
sbit BMA = P4^2;  

// 編碼器 B 相 -> P4.3,需外接 680Ω 上拉電阻
sbit BMB = P4^3;  

// 編碼器公共端 -> 接地

// 編碼器按鍵 -> P1.6,按下為低電平
sbit BMC = P1^6;  

// 脈衝計數器(無符號整型)
unsigned int counter = 0;

編碼器正交編碼原理

標準增量式編碼器輸出兩路相位差 90° 的方波(A、B 相),通過判斷邊沿順序確定旋轉方向:

正轉(順時針)狀態序列

11 → 10 → 00 → 01 → 11 (循環)

反轉(逆時針)狀態序列

11 → 01 → 00 → 10 → 11 (循環)

程序以 00 狀態為檢測起點,通過延時采樣判斷下一狀態:

  • 00 → 01:正轉,counter++
  • 00 → 10:反轉,counter--
  • 00 → 11:異常/抖動,忽略
  • 長時間保持 00:超時退出(防止死循環)

核心掃描函數 scan_encoder()

void scan_encoder() {
    unsigned int i;
    while (1) {
        // 等待 00 狀態作為起始點
        if (BMA == 0 && BMB == 0) {
            // 去抖動延時循環
            for (i = 0; i < 0xfff0; i++) {
                if (BMA == 0 && BMB == 0) {
                    yans(1); // 短延時,繼續等待
                }
                else if (BMA == 0 && BMB == 1) { // 正轉:00 -> 01
                    counter++;
                    return;
                }
                else if (BMA == 1 && BMB == 0) { // 反轉:00 -> 10
                    counter--;
                    return;
                }
                if (BMA == 1 && BMB == 1) { // 異常狀態 11
                    return;
                }
            }
        }
        // 按鍵檢測:按下復位計數器
        else if (BMC == 0) {
            counter = 0;
            return;
        }
        else {
            return; // 其他狀態直接退出
        }
    }
}

顯示與主循環

// 顯示計數值(調用專用字體/顯示驅動)
void xszs() {
    unsigned int code db[] = {0, 0};
    fsfont55();
    fsszxy(4, db);
    printf("%5u\n", counter);
    txjs();
}

// 主測試程序
void testmain() {
    yans(3000); // 上電延時
    while (1) {
        xszs();         // 刷新顯示
        scan_encoder(); // 掃描編碼器
    }
}

關鍵設計點總結

  1. 狀態機思想:以 00 為同步基準,單邊沿采樣判斷方向,邏輯清晰。
  2. 軟件去抖動:雙層循環 + yans() 延時,濾除機械觸點抖動。
  3. 超時保護:for(i=0; i<0xfff0; i++) 防止編碼器靜止時程序卡死。
  4. 按鍵復位:獨立檢測 BMC 低電平,實現計數器歸零。
  5. 非阻塞設計:每次調用處理一個完整脈衝或按鍵事件,適合前後台架構。

優化建議

  • 改用定時器中斷定時掃描(如 1ms 周期),釋放 CPU 主循環。
  • 引入狀態機變量記錄上次狀態,支持連續高速旋轉不丟脈衝。
  • 利用單片機硬件編碼器接口(如 STM32 TIM 編碼器模式)實現零 CPU 佔用。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved