本代碼實現單片機(可能為 STC/8051 系列)下的增量式旋轉編碼器掃描驅動。包含:
// 編碼器 A 相 -> P4.2,需外接 680Ω 上拉電阻
sbit BMA = P4^2;
// 編碼器 B 相 -> P4.3,需外接 680Ω 上拉電阻
sbit BMB = P4^3;
// 編碼器公共端 -> 接地
// 編碼器按鍵 (C 相) -> P1.6
sbit BMC = P1^6;
unsigned int counter = 0; // 編碼器脈衝計數值
增量式編碼器輸出 A、B 兩路相位差 90° 的方波:
| 方向 | A | B | 狀態序列 |
|---|---|---|---|
| 正轉 (CW) | 1→0→0→1 | 1→1→0→0 | 11 → 10 → 00 → 01 → 11... |
| 反轉 (CCW) | 11 → 01 → 00 → 10 → 11... |
核心邏輯:從 `00` 狀態出發,檢測下一狀態:
void scan_encoder(void) {
unsigned int i;
while (1) {
// 等待穩定在 00 狀態
if (BMA == 0 && BMB == 0) {
// 去抖動延時:若持續 00 則繼續等待
for (i = 0; i < 0xFFF0; i++) {
if (BMA == 0 && BMB == 0) {
yans(1); // 微秒級延時
} else if (BMA == 0 && BMB == 1) { // 01 -> 正轉
counter++;
return;
} else if (BMA == 1 && BMB == 0) { // 10 -> 反轉
counter--;
return;
}
// 若變為 11,for 循環自然結束,外層 while 重新檢測
}
}
// 按鍵檢測:低電平有效,復位計數器
else if (BMC == 0) {
counter = 0;
return;
}
// 其他狀態:直接返回,等待下次掃描
else {
return;
}
}
}
採用「等待 00 → 延時檢測轉移」的簡易狀態機,避免複雜的狀態表,資源佔用極小。
編碼器處理優先於按鍵檢測。若需按鍵最高優先級,應將 `BMC` 判斷前置。
`unsigned int` 16 位,範圍 0~65535。長時間運行需考慮溢出處理或改用 `unsigned long`。
// 顯示計數值(假設 LCD/數碼管驅動)
void xszs(void) {
unsigned int code db[] = {0, 0};
fsfont55(); // 設置字體
fsszxy(4, db); // 設置坐標
printf("%5u\n", counter); // 輸出 5 位無符號整數
txjs(); // 刷新顯示
}
// 主程序
void testmain(void) {
yans(3000); // 上電延時 3秒,等待外設穩定
while (1) {
xszs(); // 刷新顯示
scan_encoder(); // 掃描編碼器
}
}