#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; // 清除步数
}
// ... (其他逻辑)
}
}
|