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