Aquest cas és una variant de l'exemple CP. Ara també comptarem cada cop que es prem el polsador però el valor que mostrarem als LED no serà binari natural sinó binari Gray. El codi binari Gray es caracteritza pel fet que entre dos nombres consecutius sempre només canvia un bit i els altres romanen igual. En canvi en binari natural (el que hem vist a format de les dades) hi ha posicions en les que només en canvia un i altres en les que canvien tots. La següent taula ens mostra els dos codis per a nombres de quatre bits:
| Valor decimal |
Binari natural |
Binari Gray |
Valor decimal |
Binari natural |
Binari Gray |
|
| 0 | 0000 | 0000 | 8 | 1000 | 1100 | |
| 1 | 0001 | 0001 | 9 | 1001 | 1101 | |
| 2 | 0010 | 0011 | 10 | 1010 | 1111 | |
| 3 | 0011 | 0010 | 11 | 1011 | 1110 | |
| 4 | 0100 | 0110 | 12 | 1100 | 1010 | |
| 5 | 0101 | 0111 | 13 | 1101 | 1011 | |
| 6 | 0110 | 0101 | 14 | 1110 | 1001 | |
| 7 | 0111 | 0100 | 15 | 1111 | 1000 |
Guardarem els 16 codis Gray en una zona de memòria de 16 bytes i farem servir l'adreçament indirecte per anar a buscar el valor corresponent. El programa seria:
#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 Visualit ; Una variable on guardem el que mostraran els LED Compta ; Una variable per comptar iteracions Retard1 ; Variable per al bucle de retard Gray:16 ; Els codis Gray dels números del 0 al 15 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 bcf STATUS,RP0 clrf Compta ; Posa el comptador d'iteracions a valor zero clrf Visualit ; Posa el comptador dels LED a valor zero bcf STATUS,IRP ; Preventivament, posem IRP a 0 movlw Gray ; Adreça del primer codi movwf FSR ; Preparem l'adreçament indirecte movlw b'00000000' ; 0 call Guarda ; Funció que ho guarda a la memòria movlw b'00000001' ; 1 call Guarda movlw b'00000011' ; 2 call Guarda movlw b'00000010' ; 3 call Guarda movlw b'00000110' ; 4 call Guarda movlw b'00000111' ; 5 call Guarda movlw b'00000101' ; 6 call Guarda movlw b'00000100' ; 7 call Guarda movlw b'00001100' ; 8 call Guarda movlw b'00001101' ; 9 call Guarda movlw b'00001111' ; 10 call Guarda movlw b'00001110' ; 11 call Guarda movlw b'00001010' ; 12 call Guarda movlw b'00001011' ; 13 call Guarda movlw b'00001001' ; 14 call Guarda movlw b'00001000' ; 15 call Guarda clrf Previ ; L'estat previ del polsador és no premut clrf PORTC ; Comencem amb els LED apagats Bucle movlw b'00000001' 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 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 STATUS,Z ; 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 STATUS,Z ; 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 movlw Gray ; Adreça del primer codi addwf Visualit,w ; Li suma el valor a mostrar movwf FSR ; I ho posa per a l'adreçament indirecte movf INDF,w ; Llegeix el valor a mostrar movwf PORTC ; I ho posa als LED Invert movf Previ,w ; Copia Previ a l'acumulador xorlw b'00000001' ; 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...
Guarda movwf INDF ; Adreçament indirecte incf FSR,f ; Incrementem el punter return end

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