Добил.
В принципе, избавлятся от дребезга в енкодере проще, чем в кнопке.
Так как начало и конец импульса всегда отделены началом и концом другого импульса.
Типа:
Нажал1-Нажал2-Отжал1-Отжал2.
Между нажал1 и отжал1 всегда есть нажал2.
Вывод: надо играть на edges.
Не важен дребезг, сколько не дребезжи, после первого edge сигнал игнорируем
до активности на другом сигнале.
Еще мысль:
после первого edge имеем направление движения:
или 10, или 01, после второго edge фиксируем предыдущее состояние (направление).
Наваял код в Microchip X Lab xc8
для PIC18F14K50 - то, что под рукой было.
Преобразовывает в gray code - в зависимости от направления вращения состояния
меняются:
00
01
11
10
00
или
00
10
11
01
00
CODE
/*
* File: main.c
* Author: dmitriy
*
* Created on September 17, 2013, 10:55 PM
*/
#include <htc.h>
#include <stdlib.h>
#include <stdint.h> /* For uint8_t definition */
#include "config.h"
uint8_t values;
void Init()
{
// Input PB4, PB5 for encoder
// Output PC1, PC2
TRISC = 0xF1;
ANSEL = 0;
ANSELH = 0;
// Enable pullups on PORTB
INTCON2bits.NOT_RABPU = 0;
//Enable interrupt on change for PB4, PB5, PB6
IOCBbits.IOCB4 = 1;
IOCBbits.IOCB5 = 1;
//Enable interrupt on change
INTCON2bits.RABIP = 1;
INTCONbits.RBIE = 1;
INTCONbits.PEIE = 1;
INTCONbits.GIE = 1;
}
void interrupt isr(void) {
if (INTCONbits.RBIF) {
values = (PORTB & 0x30) >> 4;
INTCONbits.RBIF = 0;
}
}
/*
*
*/
int main(int argc, char** argv) {
uint8_t edges = 0;
uint8_t edge;
uint8_t old_values;
uint8_t grey = 0;
uint8_t myvalue;
Init();
old_values = (PORTB & 0x30) >> 4;
while (1) {
myvalue = values;
edge = myvalue ^ old_values;
old_values = myvalue;
if (edge) {
//activity detected
if (edge != edges) {
//activity on new edge
edges = edge;
if (!myvalue) {
//fix direction
// which depends on edge
if (edge & 0x01) {
switch (grey) {
case 00:
grey = 0x01;
break;
case 0x01:
grey = 0x03;
break;
case 0x03:
grey = 0x02;
break;
case 0x02:
grey = 0x00;
break;
} //switch
} else {
switch (grey) {
case 00:
grey = 0x02;
break;
case 0x02:
grey = 0x03;
break;
case 0x03:
grey = 0x01;
break;
case 0x01:
grey = 0x00;
break;
} //switch
} //if (edge & 0x01)
PORTC = grey << 1;
} //if (!myvalue)
} //if (edge != edges)
}
}
return (EXIT_SUCCESS);
}