A l'exemple AI guardàvem els valors a la memòria de dades i després els llegiem amb adreçament indirecte. Encara que només s'executessin un cop, al programa hi havia un conjunt significatiu d'instruccions que escrivien els valors dels codis Gray que després havíem de llegir.
En aquest exemple guardarem els 16 valors del codi Gray a la memòria de programa en el moment de programar i així estalviarem línies de programa. Les etiquetes Gra2 i Gra3 no les fem servir. El valor d'EEDATH no el llegim ja que sabem que és zero.
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 Visualit EQU 0x22 ; Una variable on guardem el que mostraran els LED Compta EQU 0x23 ; Una variable per comptar iteracions Retard1 EQU 0x24 ; Variable per al bucle de retard
PSECT code, class=CODE, delta=2, abs
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
bcf RP0
movlw 5 ; Retard d'1 s
call Rets ; Retard per evitar problemes amb el polsador
clrf Compta ; Posa el comptador d'iteracions a valor zero
clrf Visualit ; Posa el comptador dels LED a valor zero
clrf Previ ; L'estat previ del polsador és no premut
clrf PORTC ; Comencem amb els LED apagats
Bucle:
movlw 00000001B
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 Esborra
incf Compta,f ; Si són iguals, incrementa el valor de Compta
movf Compta,w ; Copia Compta a l'acumulador
xorlw 4 ; Comprova si val 4, si ho val s'activa Z
btfss ZERO ; Si val 4 no fa la instrucció següent
goto Final ; Si no era 4 va a Final
movf Polsador,w ; Copia Polsador a W, si val 0 s'activa Z
btfsc ZERO ; Si Polsador valia 1 (Z=0) no fa la instrucció següent
goto Invert ; Si no està premut, ja estem
incf Visualit,f ; Si ho està, incrementa el valor de Visualit
btfsc Visualit,4 ; Mira si hem arribat a 16
clrf Visualit ; Si hem arribat a 16, torna a posar el comptador a zero
call Llegir ; Llegim el valor a la memòria de programa
movwf PORTC ; I ho posa als LED
Invert:
movf Previ,w ; Copia Previ a l'acumulador
xorlw 00000001B ; Inverteix el valor
movwf Previ ; I ho guarda a Previ
Esborra:
clrf Compta ; Posa el comptador d'iteracions a valor zero
Final: ; Funció de retard 1 ms
nop
decfsz Retard1,f
goto Final
goto Bucle ; Repetim-ho...
; ; Funció de retard de 0,2 W s ; Rets: movwf Retard1+2 Bucles: decfsz Retard1,f goto Bucles decfsz Retard1+1,f goto Bucles decfsz Retard1+2,f goto Bucles return Llegir: bsf RP1 ; Tria el banc 2 movlw HIGH Gray ; Llegim l'adreça de la variable movwf EEADRH ; Adreça EEPROM movlw LOW Gray ; Llegim l'adreça de la variable bcf RP1 ; Tria el banc 0 addwf Visualit,w ; Li suma el valor a mostrar bsf RP1 ; Tria el banc 2 movwf EEADR ; Adreça EEPROM bsf RP0 ; Tria el banc 3 bsf EEPGD ; Accés a memòria de programa bsf RD ; Lectura nop nop ; espera dos cicles bcf RP0 ; Tria el banc 2 movf EEDAT,w ; Llegim bcf RP1 ; Tria el banc 0 return
Gray: DB 00000000B, 00000001B, 00000011B, 00000010B, 00000110B, 00000111B DB 00000101B, 00000100B, 00001100B, 00001101B, 00001111B, 00001110B DB 00001010B, 00001011B, 00001001B, 00001000B END main
Tal com ho hem posat, els valors es guardaran després de la darrera instrucció del programa. Si ens cal, però, podem especificar una adreça diferent per guardar-los.
ORG 0x60 Gray: DB 00000000B, 00000001B, 00000011B, 00000010B, 00000110B, 00000111B DB 00000101B, 00000100B, 00001100B, 00001101B, 00001111B, 00001110B DB 00001010B, 00001011B, 00001001B, 00001000B END main

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