单片机------编码器(按键和旋转)---4
/ #ifndef ROTARY_Drive #define ROTARY_Drive
#define ROTARY_KEY_NO 0 //默认 #define ROTARY_KEY_S 1 //短按 #define ROTARY_KEY_M 2 //双击 #define ROTARY_KEY_L 3 //长按
sbit ROTARY_MUTE=P3^5; //编码器按键 sbit ROTARY_A=P3^6; //编码器的旋转触点 sbit ROTARY_B =P3^7; 编码器的旋转触点
extern void ROTARY_Init(); //编码器初始化 extern ROTARY_ROTARY_Scan_Drive(); //编码器扫描旋转 extern void ROTARY_Key_Scan_Drive() //编码器扫描按键长按短按双击 extern u8 xdata ROTARY_Read_Data_Key; //编码器按键结果 extern u8 xdata ROTARY_Read_Data_Rotary; //编码器旋转结果
#endif
/ #include <all.h>
u8 xdata ROTARY_Read_Data_Key=ROTARY_KEY_NO; u8 xdata ROTARY_Read_Data_Rotary=0;
void ROTARY_Init() { P3M0&=0xdf; //11 01 1111 标准化输入输出口 P3M1&=0xdf; //1101 1111 标准化输入输出口
ROTARY_MUTE=1; //拉高 ROTARY_A=1; //拉高 ROTARY_B=1; //拉高
}
void ROTARY_Key_Scan_Drive() { static bit flag1=0; //长按标志位 static bit flag2=1; //按键释放标志位,防止多次判断成长按 static bit key_down=0; static u8 count1=0; static u16 count2=0; if(key_down1) //E 如果进入到状态1 { count2++; if(count2>=5000) //F 如果按键持续按了很长时间 { count2=0; if(flag21) //如果上次长按后有过释放,如果没有释放就说明是按住不放,不再做判断。 这里面没有释放 就不做判断。flag2=1是按键释放标志位。只有长按后,做过一次按键释放判断,然后赋值, 才能进入下次长按判断,不然会有多次长按判断。需要按键释放后给一次值 。 { flag1=1; //长按标志位,表示已经判断为长按 flag2=0; ROTARY_Read_Data_Rotary++; //计数器,方便用数码管等显示示数 ROTARY_Read_Data_Key=ROTARY_KEY_L; //判断为长按,然后跳出 } }
// 下面是按键释放后的一些判断
if(ROTARY_MUTE==1) // 如果按键释放
{
key_down=0; //状态清0,下次循环不再进入
flag2=1; //长按之后的释放,如果不写就会连续判断为多次长按
count2=0; //把长延迟count2清0
if(flag1)
{
flag1=0; //不判断是不是短按了,直接跳出
}
else
{
ROTARY_Read_Data_Rotary++;
ROTARY_Read_Data_Key=ROTARY_KEY_S; //判断为短按,然后跳出
}
}
}
//下面的程序是判断按键有没有被按过 E如果没有进入到状态1 else { if(ROTARY_MUTE0) //A 如果按键按下 { count1++; if(count1>100) //B稍微延迟下,避免抖动影响判断 { count1=0; if(ROTARY_MUTE0) //C如果按键确认按下
{
key_down=1; // D进入到状态1
}
}
}
else //A按键没有按下
{
count1=0; //D进入到状态0
}
}
} / void ROTARY_ROTARY_Scan_Drive() { static bit Turn_Left=0,Turn_Right=0,Rotary_Flag=0; if(ROTARY_A1&&ROTARY_B1) { Rotary_Flag=1; } if(Rotary_Flag1) { if(ROTARY_A0&&ROTARY_B0) { if(Turn_Right1) { Rotary_Read_Data_Rotary++; Rotary_Flag=0; } if(Turn_Left==1) { Rotary_Read_Data_Rotary–; Rotary_Flag=0; } } } Turn_Left=ROTARY_A; Turn_Right=ROTARY_B;
}
