He encontrado este código en internet de un proyecto parecido.
el PIC es para un 16F628 y habria que adaptarlo (está en aleman). Lo bueno es que aparece el código para el encoder y control de PGA que no es poco:
v0.3a 18.9.2003 TP
list p=16f628
; Pinbelegung
; ----------------------------------
; PORTA: 0 < rotary encoder - B Pin4
; 1 < rotary encoder - A Pin5
; 2 < rotary encoder - pushbutton
; 3 >
; 4 -
; 5 -
; 6 -
; 7 -
;
; PORTB: 0 > PGA mute
; 1 > PGA SCLK
; 2 > PGA SDI
; 3 > PGA CS
; 4 >
; 5 >
; 6 >
; 7 >
;
;
;
;- Rotary-Encoder mit PGA2310 Lautstärkesteller
#include <P16f628.INC>
ERRORLEVEL -302
;- Konfiguration
__CONFIG _PWRTE_ON & _WDT_OFF & _INTRC_OSC_NOCLKOUT & _MCLRE_OFF & _BODEN_ON & _LVP_OFF
#define encoder PORTA
#DEFINE CS_PGA PORTB,3
#DEFINE SDI PORTB,2
#DEFINE SCLK PORTB,1
#DEFINE mute PORTB,0
BUT_S1 EQU 2
;-Variablen
temp equ 0x20 ; Arbeitsregister
alt equ 0x21 ; alte Rotor-Position
neu equ 0x22 ; aktuelle Rotorposition
buffer equ 0x23 ; alter volume
cntalt equ 0x24 ; hilfregister
a equ 0x25 ; hilfsregister
CH equ 0x26
swan equ 0x27
swanalt equ 0x28
loops Equ 0x29 ; zähler für Warteschleife
loops2 Equ 0x2a ; zähler für Warteschleife
loops3 Equ 0x2b ;
Taste equ 0x2c ; Tastaturpuffer
Taetig equ 0x2d ; loopzähler
counterE equ 0x2e
volume equ 0x2f ; Zählstand / volume
;- Start
org 0
;- Initialisierung
init
bsf STATUS, RP0 ; Bank 1
clrf OPTION_REG
BCF TRISA, 3 ; RA3 auf Ausgang einstellen
movlw B'00000000' ; PortB alle outputs
movwf TRISB
bcf STATUS, RP0 ; Bank 0
clrf PORTB
call ReadTaste
clrf INTCON ; Interupt disable
BSF CMCON, CM0 ; 16F628 alle Comparatoreingänge auf Digital umschalten
BSF CMCON, CM1
BSF CMCON, CM2
clrf a
clrf CH
clrf Taste
clrf cntalt
BSF mute
movfw encoder
movwf alt ; aktuelle encoder-Stellung lesen
movlw B'00000011'
andwf alt, f ; nur 2 LSB stehen lassen
CALL WAIT
CALL WAIT
CALL WAIT ; anfangs ordentlich warten
call startup
;-mainloop
loop
BTFSS PORTA, BUT_S1
call invert
BTFSC PORTA, BUT_S1
call resetbutton
call read_encoder ; Rotary Encoder abfragen
movfw volume ; schreiben
movwf temp
movfw cntalt
xorwf temp, w ; hat sich volume geändert?
bz endb
incf temp,1 ; ist volume 1+ gestiegen?
xorwf temp,w
bnz ja
decf temp,1 ; sonst ist volume -1 gefallen?
decf temp,1
xorwf temp,w
bnz ja
goto endb
ja
movfw volume
call PGA_WR
movlw 0xfe
movwf Taetig ; setz den tätigkeitssensor hoch
endb
movfw Taetig
XORLW 0
SKPZ
decf Taetig, f ; zähl den tätigkeitssensor runter auf 0
XORLW 1
SKPNZ
call EEWrite ;wenn eine weile nix passiert wird wert weggespeichert
goto loop
;- Test des Encoders auf Verdrehung
read_encoder
movfw encoder
movwf neu ; aktuelle encoder-Stellung nach new
movlw B'00000011'
andwf neu, f ; nur 2 LSB stehen lassen
movfw neu ; wurde der encoder bewegt?
movwf temp
movfw alt
xorwf temp, w ; ist neu = alt?
bz ende ; ja: nicht verdreht, also nichts tun
movlw 0x01 ; user hat gespielt, also im falle startup
movwf loops3 ; will er wohl nicht das es weiterrasselt
; nein: encoder verdreht, aber in welche Richtung?
; drehen wir mal Bit0 des alten werts zum Vergleich
movfw volume ; nach links
movwf cntalt
bcf alt, 1
clrc ; Carry-Flag löschen
rlf alt, f ; alten Encoder-Stand um 1 Stelle nach links drehen
movfw neu
xorwf alt, f ; falls xorf >1 ergibt, dann war es eine Rechtsdrehung
bz links ; links: decrement volume
decf alt, f
bz links ; links: decrement volume
rechts
; wenn zwei schritte -
incf a,1
movfw a
XORLW 2
bnz weiter
; dann inc volume
movfw volume
XORLW .255
; ausser volume ist am oberen anschlag
SKPZ
incf volume, f ; rechts: increment volume
clrf a
goto weiter
links
; dito fürs decrement
incf CH,1
movfw CH
XORLW 2
bnz weiter
movfw volume
XORLW 0
SKPZ
decf volume, f ; links: decrement volume
clrf CH
weiter
movfw neu
movwf alt ; neu für nächsten Vergleich als alt speichern
ende
return
;-pushbutton Funktion mute
resetbutton
MOVLW 0
MOVWF swanalt
RETURN
invert
MOVLW 1
BTFSS PORTA, BUT_S1
MOVWF swan
MOVF swanalt,0
XORLW 1
BZ marke
Incf Taste,1 ; Toggeln des mute bits
BTFSS Taste,0
BCF mute
BTFSC Taste,0
BSF mute
MOVLW 1
MOVWF swanalt
call EEWriteB
marke
return
;- diverse Warteprozeduren
WAIT
jump3 movlw 0xff
movwf loops2
jump2 nop
nop
nop
nop
nop
nop
nop
decfsz loops2, F
goto jump2
decfsz loops, F
goto jump3
retlw 0
;-
WAIT_read
jump5 movlw .4
movwf loops2
jump4 nop
nop
nop
nop
nop
call read_encoder ; Rotary Encoder abfragen
nop
nop
decfsz loops2, F
goto jump4
decfsz loops, F
goto jump5
retlw 0
;-
WAIT10
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
RETURN ; yes, return from subWAIT
;- Hochzählprozedur EEPromgespeicherter Volume
startup
call WAIT ; abwarten bis sysstabil erreicht ist
call EERead ; Volume aus EEprom lesen
movfw counterE
movwf volume ; falls es 0 ist
movwf loops3
movfw counterE ; wenn null gespeichert ende
XORLW 0x00
SKPNZ
goto jump
movlw B'00000000' ; volume auf null da es dann loops3 mal hochgezählt wird
movwf volume
top3
incf volume,1
movfw volume
call PGA_WR
call WAIT_read
decfsz loops3, F
goto top3
; Hat user bei startup gespielt?
call EERead ; Startvolume aus EEprom lesen
xorwf volume,0 ; vergleichen mit aktellem volume
SKPZ ; wenn er hat erst neu mal sichern
call EEWrite
jump
retlw 0
;- EEprom lesen volume
EERead
BSF STATUS, RP0 ; EEADR liegt in der Bank 1
movlw 0x00
MOVWF EEADR ; schreibe die Adresse in EEADR
BSF EECON1, RD ; EEPROM Leseprozeß starten
MOVF EEDATA, W ; Die Daten der EEPROM Zelle nach W kopieren
BCF STATUS, RP0 ; Bank 0
movwf counterE
return
;- EEprom schreiben volume
EEWrite
BSF STATUS, RP0 ; EEADR liegt in der Bank 1
MOVLW 0x00
MOVWF EEADR
BCF STATUS, RP0 ; Bank 0
MOVFW volume
BSF STATUS, RP0 ; EEADR liegt in der Bank 1
MOVWF EEDATA
BSF EECON1, WREN ; nun ist Schreiben erlaubt
MOVLW 0x55
MOVWF EECON2 ; schreibe 55h nach EECON2
MOVLW 0xaa
MOVWF EECON2 ; schreibe AAh nach EECON2
BSF EECON1, WR ; starte den Schreibzyklus
NOP
NOP
call _wrcompl
BCF STATUS, RP0 ; Bank 0
jump1
return
;- EEprom lesen source
ReadTaste
BSF STATUS, RP0 ; EEADR liegt in der Bank 1
movlw 0x01
MOVWF EEADR ; schreibe die Adresse in EEADR
BSF EECON1, RD ; EEPROM Leseprozeß starten
MOVF EEDATA, W ; Die Daten der EEPROM Zelle nach W kopieren
BCF STATUS, RP0 ; Bank 0
movwf Taste
BTFSS Taste,0
BSF PORTA,3
BTFSC Taste,0
BCF PORTA,3
return
;- EEprom beschreiben source
EEWriteB
BSF STATUS, RP0 ; EEADR liegt in der Bank 1
MOVLW 0x01
MOVWF EEADR
BCF STATUS, RP0 ; Bank 0
MOVFW Taste
BSF STATUS, RP0 ; EEADR liegt in der Bank 1
MOVWF EEDATA ;
BSF EECON1, WREN ; nun ist Schreiben erlaubt
MOVLW 0x55
MOVWF EECON2 ; schreibe 55h nach EECON2
MOVLW 0xaa
MOVWF EECON2 ; schreibe AAh nach EECON2
BSF EECON1, WR ; starte den Schreibzyklus
NOP
NOP
call _wrcompl
BCF STATUS, RP0 ; Bank 0
return
;- Warten bis Schreibvorgang beendet
_wrcompl
bsf STATUS,RP0 ; Bank 1
btfsc EECON1,WR ; warte bis Schreibvorgang beendet
goto _wrcompl
bcf STATUS,RP0 ; Bank 0
return ; zurueck zur aufrufenden Routine
; 16 bits ins pga drücken
PGA_WR
BCF SCLK
BCF CS_PGA ; Chip select
CALL WAIT10
BTFSC volume,7
BSF SDI
BTFSS volume,7
BCF SDI
BSF SCLK ;Bit1
BCF SCLK
BTFSC volume,6
BSF SDI
BTFSS volume,6
BCF SDI
BSF SCLK ;Bit2
BCF SCLK
BTFSC volume,5
BSF SDI
BTFSS volume,5
BCF SDI
BSF SCLK ;Bit3
BCF SCLK
BTFSC volume,4
BSF SDI
BTFSS volume,4
BCF SDI
BSF SCLK ;Bit4
BCF SCLK
BTFSC volume,3
BSF SDI
BTFSS volume,3
BCF SDI
BSF SCLK ;Bit5
BCF SCLK
BTFSC volume,2
BSF SDI
BTFSS volume,2
BCF SDI
BSF SCLK ;Bit6
BCF SCLK
BTFSC volume,1
BSF SDI
BTFSS volume,1
BCF SDI
BSF SCLK ;Bit7
BCF SCLK
BTFSC volume,0
BSF SDI
BTFSS volume,0
BCF SDI
BSF SCLK ;Bit8
BCF SCLK
BTFSC volume,7
BSF SDI
BTFSS volume,7
BCF SDI
BSF SCLK ;Bit9
BCF SCLK
BTFSC volume,6
BSF SDI
BTFSS volume,6
BCF SDI
BSF SCLK ;Bit10
BCF SCLK
BTFSC volume,5
BSF SDI
BTFSS volume,5
BCF SDI
BSF SCLK ;Bit11
BCF SCLK
BTFSC volume,4
BSF SDI
BTFSS volume,4
BCF SDI
BSF SCLK ;Bit12
BCF SCLK
BTFSC volume,3
BSF SDI
BTFSS volume,3
BCF SDI
BSF SCLK ;Bit13
BCF SCLK
BTFSC volume,2
BSF SDI
BTFSS volume,2
BCF SDI
BSF SCLK ;Bit14
BCF SCLK
BTFSC volume,1
BSF SDI
BTFSS volume,1
BCF SDI
BSF SCLK ;Bit15
BCF SCLK
BTFSC volume,0
BSF SDI
BTFSS volume,0
BCF SDI
BSF SCLK ;Bit16
BCF SCLK
CALL WAIT10
BCF SDI
CALL WAIT10
BSF CS_PGA ; Chipdeselcet
RETURN
end
Podria servir?
Habria que definir los puertos del LCD, los de PGA, LED y botones según el esquema mio.
Un saludo