#申请原创#
为了方便调整时间,准备尝试使用滚轮编码器来替代按键,通过滚动滚轮来输入增加或减少的数值。关于滚轮编码器的工作原理这里不作介绍,感兴趣的可以自行百度,有不少附有动画介绍的。
为了测试方便,拆了一个旧鼠标的滚轮来制作实验用的滚轮模块,下面是制作过程的照片:
这是制作好的滚轮模块:
开始只添加了上拉电阻,并未添加滤波电容,测试时通过逻辑分析仪抓取的时序发现有很多的杂波,详见下图:
将时序放大后可以明显看到有许多抖动的杂波:
添加了104的电容后,杂波就消除了,下面就是滚轮滚动的波形,前后段的滚动方向不同:
这是测试过程的照片:
网上没有搜索到现成的滚轮编码器驱动代码,只好自己编写,我将滚轮转动的时序分成了4种状态,即起始状态、方向标志状态、确定状态和恢复状态,参见下图:
因为我是通过上拉电阻钳定引脚为高电平,所以起始状态为两个引脚均为高电平,状态标志变量state赋值为0。第二个状态是任一引脚转为低电平,此时是确定旋转方向的标志,状态变量state赋值为1。接下来是另一引脚也转为低电平,即两个引脚同时为低电平,此时可以确定滚动转动了一个单位,也就是确定状态,变量state赋值为2。第4个状态则是先转为低电平的引脚恢复为高电平,我称之为恢复状态,变量state赋值为3。最后两个引脚均恢复为高电平,为下一次判断作准备。
按照上述思路,我定义了两个变量分别表示两个引脚之前的状态,当这两个变量之一与当前引脚的电平不一致时,表示滚轮有移动发生。相应的驱动代码如下:
if((rol1 != ROL1_GetValue()) | (rol2 != ROL1_GetValue())){ //捕获滚轮动作
rol1 = ROL1_GetValue();
rol2 = ROL2_GetValue();
LCD_write_value(30,0,2,0,1,rol1);
LCD_write_value(45,0,2,0,1,rol2);
if(rol1>0 & rol2>0) //起始状态(两个引脚均为高电平)
state = 0;
else{
if(rol1==0 & rol2==0) //第3状态(两个引脚均为低电平)
state = 2;
else{
if(state == 0){ //第2状态(判定旋转方向)
dire = rol1;
state = 1;
}
else{
state = 3; //第4状态(恢复)
counts = 1;
}
}
}
LCD_write_value(30,1,1,0,1,state);
LCD_write_value(0,1,1,0,1,dire); //显示旋转方向
LCD_write_value(10,1,2,0,1,counts);//显示旋转数
}
经过测试,可以方便地获得滚轮转动及方向信息,下图为测试装置。
|