A l'Exemple RB tenim dos bucles de retard. Podríem definir aquest bucle com una funció i anar-hi des dels dos llocs on el necessitem. En realitat, passarem un paràmetre (a través de W) a la funció, així que es comportarà com una funció amb paràmetre.
En el programa següent hem substituït els dos Bucles de retard per crides (call) a la funció i passem el nombre de cicles a través de l'acumulador.
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
call Retards ; Bucle de retard
movlw 13 ; El punt indica que es un valor decimal
call Retards ; Bucle de retard
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...
;
; Bucle de retard
;
Retards:
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
return
END main

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