Когда-то делал валкодер из механической мыши для регулятора громкости усилителя. Скорость вращения конечно маленькая. Возможно для ваших целей нужно использовать аппаратные прерывания и сам обработчик переписать на АСМе, чтобы быстрее все работало.
Вот моя тестовая прога:
Code
device=16F876a
'****************************************************************
' LCD should be connected as follows:
' LCD PIC
' DB4 PortB.4
' DB5 PortB.5
' DB6 PortB.6
' DB7 PortB.7
' RS PortA.0 (add 4.7K pullup resistor to 5 volts)
' E PortA.1
' RW Ground
' Vdd 5 volts
' Vss Ground
' Vo 20K potentiometer (or ground)
' DB0-3 No connect
'-------------------------------------------------------------
DECLARE XTAL 4
declare LCD_RSPIN=PORTA.0
DECLARE LCD_ENPIN=PORTA.1
DECLARE LCD_DTPIN=PORTB.4
DECLARE LCD_INTERFACE=4
DECLARE LCD_LINES=2
'-------------------------------------------------------------------------------
' Vareables
'-------------------------------------------------------------------------------
dim Vol as BYTE
dim Flag as BYTE 'Переменная выбора
dim Klav as BYTE 'Номер кнопки
dim row as BYTE '
'===============================================================================
'------------------------------------------------------ -------------------------
' Инициализация
'-------------------------------------------------------------------------------
'@ device WDT_OFF
ADCON1 = 7 'Все порты цифровые
ADCON0.0 = 0 'АЦП выключен
SSPCON.5 = 0 'Модуль SSP выкл., порты цифровые
TRISB = %00001111 'Порты 0..3 на вход
OPTION_REG=%00001000'On pull-up PORTB,прерывания по спаду RB0/INT,
'пределитель перед WDT
TRISA = %00000 'На выход
TRISC = %00000000 'На выход
'INTCON.7=0 'Disable interapt
Delayms 100 ' Wait for LCD to startup
Cls ' Clear the LCD
'*******************************************************************************
' MAIN
'-------------------------------------------------------------------------------
' Опрос кнопок
'-------------------------------------------------------------------------------
vol=50
On Interrupt intRB0
INTCON = %10010000 'Разрешение внешнего прерывания
press:
for row=0 to 3
PORTB= (dcd (row +4))^$ff 'Установка порта № строка+4 в 0
if PORTB.3=0 then
delayms 20
if PORTB.3=0 then
klav=row
goto klaviatura
endif
endif
if PORTB.2=0 then
delayms 20
if PORTB.2=0 then
klav=row +4
goto klaviatura
endif
endif
next row
goto press
'Обработка переменной клавиатуры
klaviatura:
print at 1, 1, "number key=", DEC1 klav
GoTo press
'-------------------------------------------------------------------------------
' Обработка внешнего прерывания по входу порта В0
'-------------------------------------------------------------------------------
Disable 'Запрешение прерываний перед обработчиком
intRB0:
'INTCON = %00000000 'Запрет прерываний битами
IF PORTB.1=1 Then
IF vol=63 Then exit
vol=vol +1
Else
IF vol=0 Then exit
vol=vol -1
EndIF
'Сюда можно вставить тестовые команды
print at 2, 1, "Volume=", DEC2 vol
exit:
INTCON = %10010000 'Разрешение внешнего прерывания и сброс флага
Resume
Enable 'Разрешение прерываний после обработчика
'-------------------------------------------------------------------------------
End
Переменная vol - step, portb.1- dir - это куды вращается энкодер.