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 8 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:
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
cblock 0x20 Polsador ; Una variable amb l'estat del polsador (1 = premut) Previ ; I una amb l'estat previ del polsador Sentit ; I una per al sentit de gir Visualit ; Una variable on guardem el que mostraran els LED Compta ; Una variable per comptar iteracions Retard1 ; Variable per al bucle de retard Retard2 endc
org 0 Inici bsf STATUS,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 b'00010000' movwf ADCON1 ; Posa el conversor a 1/8 de la freqüència bcf STATUS,RP0 bsf STATUS,RP1 ; Tria el banc 2 movlw b'00000001' movwf ANSEL ; Posa AN0 com entrada analògica bcf STATUS,RP0 bcf STATUS,RP1 ; Tria el banc 0 movlw b'00000001' ; activa el conversor A/D connectat a AN0 movwf ADCON0 ; amb el resultat justificat per l'esquerra movlw b'00001000' ; 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, en total 5 bsf ADCON0,GO ; Inicia la conversió btfsc ADCON0,GO ; 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 b'00000001' ; 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 STATUS,Z ; Si són iguals va a Final goto Rotar movf Sentit,w ; Copia Sentit a l'acumulador xorlw b'00000001' ; Inverteix el valor movwf Sentit ; I ho guarda a Sentit Rotar bcf STATUS,C ; 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 STATUS,C ; 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
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.
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
cblock 0x20 Polsador ; Una variable amb l'estat del polsador (1 = premut) Memoria ; El bit 0 és l'estat previ del polsador i el bit 1 és el sentit de gir Visualit ; Una variable on guardem el que mostraran els LED Compta ; Una variable per comptar iteracions Retard1 ; Variable per al bucle de retard Retard2 endc
org 0 Inici bsf STATUS,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 b'00010000' movwf ADCON1 ; Posa el conversor a 1/8 de la freqüència bcf STATUS,RP0 bsf STATUS,RP1 ; Tria el banc 2 movlw b'00000001' movwf ANSEL ; Posa AN0 com entrada analògica bcf STATUS,RP0 bcf STATUS,RP1 ; Tria el banc 0 movlw b'00000001' ; activa el conversor A/D connectat a AN0 movwf ADCON0 ; amb el resultat justificat per l'esquerra movlw b'00001000' ; Activa el bit 3 movwf Visualit ; Ho copia sobre la variable Visualit clrf Memoria ; Inicialment, rotació a 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, en total 5 bsf ADCON0,GO ; Inicia la conversió btfsc ADCON0,GO ; 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 b'00000001' ; 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 b'00000001' ; Conserva només el bit 0 (Previ) xorwf Polsador,w ; Compara Previ amb Polsador, si són iguals s'activa Z btfsc STATUS,Z ; Si són iguals va a Final goto Rotar movf Memoria,w ; Copia Memoria a l'acumulador xorlw b'00000010' ; Inverteix el valor del bit 1 (Sentit) movwf Memoria ; I ho guarda a Sentit Rotar bcf STATUS,C ; 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 STATUS,C ; 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

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