En aquest exemple es combinen coses dels exemples VV i CP.
Com en l'exemple VV, en aquest cas llegirem el potenciòmetre utilitzant una entrada analògica i utilitzarem els vuit bits superiors del valor llegit per variar la velocitat però cada cop que premem el polsador variarem el sentit de gir dels LED.
El programa serà el següent:
PROCESSOR 16F690 #include <xc.inc> config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Polsador EQU 0x20 ; Una variable amb l'estat del polsador (1 = premut) Previ EQU 0x21 ; I una amb l'estat previ del polsador Sentit EQU 0x22 ; I una per al sentit de gir Visualit EQU 0x23 ; Una variable on guardem el que mostraran els LED Compta EQU 0x24 ; Una variable per comptar iteracions Retard1 EQU 0x25 ; Variable per al bucle de retard Retard2 EQU 0x26 ; Variables per al bucle de retard
PSECT code, class=CODE, delta=2, abs ; A l'inici de la memòria
main:
bsf RP0 ; Tria el banc 1
movlw 0xFF ; Posa l'acumulador a FFh (tot uns)
movwf TRISA ; Posa tots els bits del port A com a entrada
clrf TRISC ; Posa tots els bits del port C com a sortida
movlw 00010000B
movwf ADCON1 ; Posa el conversor a 1/8 de la freqüència
bcf RP0
bsf RP1 ; Tria el banc 2
movlw 0000000B
movwf ANSEL ; Posa AN0 com entrada analògica
bcf RP0
bcf RP1 ; Tria el banc 0
movlw 00000001B ; activa el conversor A/D connectat a AN0
movwf ADCON0 ; amb el resultat justificat per l'esquerra
movlw 00001000B ; Activa el bit 3
movwf Visualit ; Ho copia sobre la variable Visualit
clrf Sentit ; Inicialment, rotació a la dreta
clrf Previ ; L'estat previ del polsador és no premut
Bucle:
movf Visualit,w ; Copia la variable Visualit a l'acumulador
movwf PORTC ; Copia el resultat sobre els LED
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
bsf GO_DONE ; Inicia la conversió
btfsc GO_DONE ; Quan el bit sigui 0 la conversió haurà acabat
goto $-1 ; repetim la línia fins que deixi de ser 0
movf ADRESH,w ; Copia els bits superiors a l'acumulador
addlw 1 ; Li suma 1 i tenim la durada variable del cicle
movwf Retard2 ; Ho copia a la variable Retard2
RetVar:
decfsz Retard1,f ; Decrementa la variable 1
; si dona zero, no es fa la instrucció següent
goto RetVar ; Salta, excepte si el resultat ha estat zero
decfsz Retard2,f ; Decrementa la variable 2
goto RetVar ; Salta, excepte si el resultat ha estat zero
movlw 13 ; El punt indica que es un valor decimal
movwf Retard2 ; Comença un altre cicle de durada fixa (10 ms)
Ret10ms:
decfsz Retard1,f
goto Ret10ms
decfsz Retard2,f
goto Ret10ms
movlw 00000001B ; Polsador activat
movwf Polsador ; Activem polsador abans de comprovar
btfsc PORTA,3 ; Mira si està desactivada l'entrada A3
; Si desactivat (premut), no fa la instrucció següent
clrf Polsador ; Si no està premut, desactiva polsador
movf Previ,w ; Copia Previ a l'acumulador
xorwf Polsador,w ; Compara Previ amb Polsador, si són iguals s'activa Z
btfsc ZERO ; Si són iguals va a Final
goto Rotar
movf Sentit,w ; Copia Sentit a l'acumulador
xorlw 00000001B ; Inverteix el valor
movwf Sentit ; I ho guarda a Sentit
Rotar:
bcf CARRY ; posa a zero el bit d'arrossegament
; Això cal en qualsevol sentit
btfsc Sentit,0 ; En quin sentit rodem?
goto Esquerra ; 1 = Esquerra
Dreta: ; Gir a la dreta
rrf Visualit,f ; Fa rodar els bits cap a la dreta
; el bit d'arrossegament entra per l'esquerra
; i el bit de la dreta passa a l'arrossegament
btfsc CARRY ; Comprova si s'ha activat l'arrossegament
; Si no s'ha activat, salta una instrucció
bsf Visualit,3 ; Si s'ha activat, torna a posar un 1 (0000 1000)
goto Bucle ; Repetim-ho...
Esquerra: ; Gir a l'esquerra
rlf Visualit,f ; Fa rodar els bits cap a l'esquerra
btfss Visualit,4 ; Hem sortit fora dels 4 bits dels LED?
goto Bucle ; No, repetim-ho...
bcf Visualit,4 ; Sí, desactivem el 4
bsf Visualit,0 ; i tornem a activar el primer
goto Bucle ; i repetim-ho...
END main
Si el polsador no funciona, assegureu-vos que heu marcat 3-State on 'Release from Reset' a la finestra de propietats del PICkit 2:

Hem emprat tres variables que només emmagatzemen un bit (Polsador, Previ i Sentit). Podríem agrupar dues d'elles (Previ i Sentit) en una sola a base de fer servir bits diferents. En el programa següent hem agafat una variable anomenada Memoria on el bit 0 correspon a Previ i el bit 1 a Sentit. Per fer fàcil la comparació, el bit que correspon al polsador ha d'estar en la mateixa posició que en la variable Polsador. No és convenient agrupar Polsador a la mateixa variable ja que si ho fem no podríem fer les comparacions amb xor. En el programa també declarem només una variable Retard però comptant que ocupa dos bytes, així reduïm el nombre d'etiquetes.
PROCESSOR 16F690 #include <xc.inc> config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Polsador EQU 0x20 ; Una variable amb l'estat del polsador (1 = premut) Memoria EQU 0x21 ; El bit 0 és l'estat previ del polsador i el bit 1 és el sentit de gir Visualit EQU 0x23 ; Una variable on guardem el que mostraran els LED Compta EQU 0x24 ; Una variable per comptar iteracions Retard EQU 0x25 ; Variable per al bucle de retard (2 bytes)
PSECT code, class=CODE, delta=2, abs ; A l'inici de la memòria
main:
bsf RP0 ; Tria el banc 1
movlw 0xFF ; Posa l'acumulador a FFh (tot uns)
movwf TRISA ; Posa tots els bits del port A com a entrada
clrf TRISC ; Posa tots els bits del port C com a sortida
movlw 00010000B
movwf ADCON1 ; Posa el conversor a 1/8 de la freqüència
bcf RP0
bsf RP1 ; Tria el banc 2
movlw 0000000B
movwf ANSEL ; Posa AN0 com entrada analògica
bcf RP0
bcf RP1 ; Tria el banc 0
movlw 00000001B ; activa el conversor A/D connectat a AN0
movwf ADCON0 ; amb el resultat justificat per l'esquerra
movlw 00001000B ; Activa el bit 3
movwf Visualit ; Ho copia sobre la variable Visualit
clrf Memoria ; Inicialment, rotació a la dreta i polsador és no premut
Bucle:
movf Visualit,w ; Copia la variable Visualit a l'acumulador
movwf PORTC ; Copia el resultat sobre els LED
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
bsf GO_DONE ; Inicia la conversió
btfsc GO_DONE ; Quan el bit sigui 0 la conversió haurà acabat
goto $-1 ; repetim la línia fins que deixi de ser 0
movf ADRESH,w ; Copia els bits superiors a l'acumulador
addlw 1 ; Li suma 1 i tenim la durada variable del cicle
movwf Retard+1 ; Ho copia a la variable Retard+1
RetVar:
decfsz Retard,f ; Decrementa la variable 1
; si dona zero, no es fa la instrucció següent
goto RetVar ; Salta, excepte si el resultat ha estat zero
decfsz Retard+1,f ; Decrementa la variable 2
goto RetVar ; Salta, excepte si el resultat ha estat zero
movlw 13 ; El punt indica que es un valor decimal
movwf Retard+1 ; Comença un altre cicle de durada fixa (10 ms)
Ret10ms:
decfsz Retard,f
goto Ret10ms
decfsz Retard+1,f
goto Ret10ms
movlw 00000001B ; Polsador activat
movwf Polsador ; Activem polsador abans de comprovar
btfsc PORTA,3 ; Mira si està desactivada l'entrada A3
; Si desactivat (premut), no fa la instrucció següent
clrf Polsador ; Si no està premut, desactiva polsador
movf Memoria,w ; Copia Memoria a l'acumulador
andlw 00000001B ; Conserva només el bit 0 (Previ)
xorwf Polsador,w ; Compara Previ amb Polsador, si són iguals s'activa Z
btfsc ZERO ; Si són iguals va a Final
goto Rotar
movf Memoria,w ; Copia Memoria a l'acumulador
xorlw 00000010B ; Inverteix el valor del bit 1 (Sentit)
movwf Memoria ; I ho guarda a Sentit
Rotar:
bcf CARRY ; posa a zero el bit d'arrossegament
; Això cal en qualsevol sentit
btfsc Memoria,1 ; En quin sentit rodem?
goto Esquerra ; 1 = Esquerra
Dreta: ; Gir a la dreta
rrf Visualit,f ; Fa rodar els bits cap a la dreta
; el bit d'arrossegament entra per l'esquerra
; i el bit de la dreta passa a l'arrossegament
btfsc CARRY ; Comprova si s'ha activat l'arrossegament
; Si no s'ha activat, salta una instrucció
bsf Visualit,3 ; Si s'ha activat, torna a posar un 1 (0000 1000)
goto Bucle ; Repetim-ho...
Esquerra: ; Gir a l'esquerra
rlf Visualit,f ; Fa rodar els bits cap a l'esquerra
btfss Visualit,4 ; Hem sortit fora dels 4 bits dels LED?
goto Bucle ; No, repetim-ho...
bcf Visualit,4 ; Sí, desactivem el 4
bsf Visualit,0 ; i tornem a activar el primer
goto Bucle ; i repetim-ho...
END main

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.