|
天问51的库函数搬来你看看,也可以自己去翻代码全开源的。
#ifndef _EC11_51_H_
#define _EC11_51_H_
//----------------编码器参数微调宏定义----------------//
#ifndef KEY_COUNT_DESHAKING
#define KEY_COUNT_DESHAKING 15 //按键消抖时间15
#endif
#ifndef KEY_COUNT_LONGT
#define KEY_COUNT_LONGT 1500 //长按按键判断时间1500
#endif
#ifndef KEY_COUNT_DUAL
#define KEY_COUNT_DUAL 180 //双击按键判断时间180
#endif
#ifndef KEY_LONG_REPEAT
#define KEY_LONG_REPEAT 200 //长按按键的回报率的倒数,即一直长按按键时响应的时间间隔200
#endif
//----------------重入缓存结构体----------------//
typedef struct tongdaoHC {
unsigned char EC11_A_dq; //EC11的A引脚读到的当前状态
unsigned char EC11_B_dq; //EC11的B引脚读到的当前状态
unsigned char EC11_D_dq; //EC11的D引脚读到的当前状态
unsigned char EC11_A_Last; //EC11的A引脚上一次的状态
unsigned char EC11_B_Last; //EC11的B引脚上一次的状态
unsigned char EC11_IN_Click; //EC11按键状态机动作标志
unsigned char EC11_j_km; //EC11判断转动快慢的计数器
unsigned int EC11_j_COUNT; //EC11按键动作计数器
}tongdaoHC;
//----------------函数声明列表----------------//
unsigned char Encoder_EC11_Scan(tongdaoHC *HC);
//*******************************************************************/
//功能:扫描EC11旋转编码器的动作并动作分析
//形参:无
//返回:EC11动作返回 0无动作 1正转 2反转 3按着按键正转 4按着按键反转 5短按 6双击 7长按 8长按松开
//详解:对EC11旋转编码器的动作进行模式分析
//*******************************************************************/
unsigned char Encoder_EC11_Scan(tongdaoHC *HC)
{
unsigned char ScanResult = 0; //用于分析编码器动作的变量
if(HC->EC11_j_km)
HC->EC11_j_km--;
if(!HC->EC11_A_dq && !HC->EC11_A_Last && !HC->EC11_B_dq && HC->EC11_B_Last) //A相当前状态和上次状态都为低电平时,抓B相上次状态为高当前状态为低的下降沿。
{
ScanResult = 1; //正转
}
else if(!HC->EC11_A_dq && HC->EC11_A_Last && !HC->EC11_B_dq && !HC->EC11_B_Last) //B相当前状态和上次状态都为低电平时,抓A相上次状态为高当前状态为低的下降沿。
{
ScanResult = 2; //反转
}
HC->EC11_A_Last = HC->EC11_A_dq; //更新编码器上一个状态暂存变量
HC->EC11_B_Last = HC->EC11_B_dq; //更新编码器上一个状态暂存变量
if(HC->EC11_D_dq == 0) //如果EC11的按键按下,
{
if(ScanResult == 0) //状态记录值为0表示EC11没有转动
{
ScanResult = 5; //返回值为5
}
else
{
if(ScanResult == 1) //按下按键时候正转
{
HC->EC11_IN_Click = 7;
return 3; //编码器按键按下并正转返回值为3
}
if(ScanResult == 2) //按下按键时候反转
{
HC->EC11_IN_Click = 7;
return 4; //编码器按键按下并反转返回值为4
}
}
}
else //如果EC11的按键没有按下,
{
if(ScanResult==1)
return 1; //编码器正转返回值为1
else if(ScanResult==2)
return 2; //编码器反转返回值为2
}
if(HC->EC11_IN_Click = 7)//有旋转动作等待释放
{
if(ScanResult==0) //按键被释放
{
HC->EC11_IN_Click = 0; //按键状态机清零
}
}
else //没有旋转动作等待进入按键处理
{
if(HC->EC11_j_COUNT<3000) //打开按键按下时间定时器
HC->EC11_j_COUNT++;
switch (HC->EC11_IN_Click) //状态机
{
case 0://初始状态
if(ScanResult==5)
{
HC->EC11_IN_Click = 1; //进入状态1有键按下
HC->EC11_j_COUNT = 0; //复位计时器
}
break;
case 1://有键按下状态
if(ScanResult==5 && HC->EC11_j_COUNT > KEY_COUNT_DESHAKING)//按下消抖时间结束
{
HC->EC11_IN_Click = 2; //进入状态2按键以稳定按下。
}
break;
case 2://按键以稳定按下。
if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==0)//按键释放且计时小于180MS
{
HC->EC11_IN_Click = 3;//进入状态3按键双击等待状态。
HC->EC11_j_COUNT = 0; //复位计时器
}
else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==5)//按键按下且计时大于180MS
{
HC->EC11_IN_Click = 5;//进入状态5按键长按等待状态。
}
break;
case 3://按键双击等待状态。
if(HC->EC11_j_COUNT <KEY_COUNT_DUAL && ScanResult==5)//按键按下且计时重新计数小于180MS
{
HC->EC11_IN_Click = 4;//进入状态4按键双击二次按下状态。
HC->EC11_j_COUNT = 0; //复位计时器
}
else if(HC->EC11_j_COUNT >=KEY_COUNT_DUAL && ScanResult==0)//按键释放且计时重新计数大于180MS
{
HC->EC11_IN_Click = 0; //按键状态机清零
return 5;//单击返回5
}
break;
case 4://按键双击二次按下状态。
if(HC->EC11_j_COUNT > KEY_COUNT_DESHAKING && ScanResult==0)//按下消抖时间结束且按键被释放
{
HC->EC11_IN_Click = 0; //按键状态机清零
return 6; //双击返回键值6
}
break;
case 5://按键长按等待状态。
if(HC->EC11_j_COUNT <KEY_COUNT_LONGT && ScanResult==0)//按键被释放且计时小于1600MS
{
HC->EC11_IN_Click = 0; //按键状态机清零
return 5;//单击返回5
}
else if(HC->EC11_j_COUNT >=KEY_COUNT_LONGT && ScanResult==5)//记录键值在按下键值表里且计时大于1600MS
{
HC->EC11_IN_Click = 6;//进入状态6按键长按时间到达状态。
HC->EC11_j_COUNT = 0; //复位计时器
return 7;//连续按下返回键值
}
break;
case 6://按键长按时间以到达。
if(ScanResult==0) //按键被释放
{
HC->EC11_IN_Click = 0; //按键状态机清零
return 8;//连续按下松开返回键值
}
else if(HC->EC11_j_COUNT >=KEY_LONG_REPEAT && ScanResult==5)//记录键值在按下键值表里大于200MS
{
HC->EC11_j_COUNT = 0; //复位计时器
return 7;//连续按下返回键值
}
break;
}
}
return 0;//没有按键返回0
}
#endif |
|