#include <reg51.h>
#include <intrins.h>
#include <string.h>
#define uchar unsigned char
#define uint unsigned int
sbit ENCODER_A = P3^5; // 旋轉(zhuǎn)編碼器A相
sbit ENCODER_B = P3^4; // 旋轉(zhuǎn)編碼器B相
sbit CS = P3^2; // 數(shù)字電位器片選
sbit U_D = P3^1; // 數(shù)字電位器方向
sbit INC = P3^0; // 數(shù)字電位器增加
// 上一次的編碼器狀態(tài)和時間戳
uchar lastA = 1, lastB = 1;
uint lastTime = 0;
int steps = 0; // 旋轉(zhuǎn)的步數(shù)
uint stepMultiplier = 1; // 步數(shù)增加的倍數(shù),根據(jù)旋轉(zhuǎn)速度動態(tài)調(diào)整
uint currentTime = 0; // 將currentTime移出中斷服務例程并定義為全局變量
// 定時器中斷服務例程(假設每1ms中斷一次),用于更新時間和處理編碼器
void timer0_isr(void) interrupt 1 {
currentTime++; // 更新時間戳
// 讀取旋轉(zhuǎn)編碼器
// 判斷旋轉(zhuǎn)方向并計算步數(shù)
uchar a = ENCODER_A;
uchar b = ENCODER_B;
//uchar a;
// a = ENCODER_A ? 1 : 0; // 使用三元運算符根據(jù)ENCODER_A的狀態(tài)設置a的值
// 判斷旋轉(zhuǎn)方向
if ((a == 0) && (b == 1) && (lastA == 1) && (lastB == 0)) {
steps += stepMultiplier; // 順時針旋轉(zhuǎn)
} else if ((a == 1) && (b == 0) && (lastA == 0) && (lastB == 1)) {
steps -= stepMultiplier; // 逆時針旋轉(zhuǎn)
}
// 更新上一次的狀態(tài)和時間戳
lastA = a;
lastB = b;
lastTime = currentTime;
// 根據(jù)時間差調(diào)整步數(shù)增加的倍數(shù)
adjustStepMultiplier(currentTime - lastTime);
}
// 調(diào)整步數(shù)增加的倍數(shù)
void adjustStepMultiplier(uint timeDiff) {
if (timeDiff < 5) {
// 旋轉(zhuǎn)非常快
stepMultiplier = 5;
} else if (timeDiff < 10) {
// 旋轉(zhuǎn)快
stepMultiplier = 3;
} else if (timeDiff < 20) {
// 旋轉(zhuǎn)中等速度
stepMultiplier = 2;
} else {
// 旋轉(zhuǎn)慢或停止
stepMultiplier = 1;
}
}
//初始化定時器
void initTimer() {
TMOD = 0x01; // 設置定時器模式
TH0 = (65536 - 1000) / 256; // 設置定時器初值,假設12MHz晶振,每1ms中斷一次
TL0 = (65536 - 1000) % 256;
ET0 = 1; // 開啟定時器0中斷
EA = 1; // 開啟全局中斷
TR0 = 1; // 啟動定時器0
}
void delayms(void) {
unsigned char i;
for (i = 0; i<100; i++)
;
// 這個循環(huán)的數(shù)字可能需要根據(jù)您的MCU時鐘進行調(diào)整
}
// 初始化數(shù)字電位器
void initPotentiometer() {
CS = 0;
U_D = 0;
INC = 0;
INC = 1;
CS = 1;
delayms(1);
}
// 調(diào)整數(shù)字電位器
void adjustPotentiometer(int stepsToAdjust, uchar direction) {
if (stepsToAdjust == 0) return; // 沒有步數(shù)則不調(diào)整
CS = 0;
U_D = direction;
for (int i = 0; i < abs(stepsToAdjust); i++) {
INC = 0;
_nop_();
_nop_();
INC = 1;
}
CS = 1;
// 這里應該有一個適當?shù)难舆t,但delayms函數(shù)沒有定義
// 你需要自己實現(xiàn)這個函數(shù),或者使用其他方法延遲
}
void main() {
initTimer(); // 初始化定時器
initPotentiometer(); // 初始化數(shù)字電位器
while (1) {
if (currentTime != lastTime) { // 檢查是否有新的編碼器讀數(shù)
adjustPotentiometer(steps, steps > 0 ? 1 : 0); // 根據(jù)steps的符號確定方向
steps = 0; // 清除步數(shù)
}
// ... (其他邏輯)
}
}
|