本文記錄一款基於單片機的編碼開關(旋轉編碼器)掃描驅動程序,實現正反轉方向識別、脈衝計數累加/遞減、按鍵復位計數器功能。代碼採用輪詢方式,包含去抖動延時邏輯,適合資源受限的嵌入式環境。
// 編碼器 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(); // 掃描編碼器
}
}
00 為同步基準,單邊沿采樣判斷方向,邏輯清晰。yans() 延時,濾除機械觸點抖動。for(i=0; i<0xfff0; i++) 防止編碼器靜止時程序卡死。BMC 低電平,實現計數器歸零。