En aquest exemple mostrem uns caràcters a la matriu de LED. En aquest cas concret són les xifres del 0 al 4, però podria ser qualsevol caràcter. Cal que cada caràcter estigui definit; per fer-ho senzill i compacte guardem les definicions dels caràcters a la memòria de programa, com en un dels programes de l'exemple ML. Cada caràcter s'ha creat amb una matriu de 7 ⨯ 5 punts però el definim amb vuit fileres perquè així és més fàcil multiplicar per vuit (rodant els bits), que és el que necessitem per trobar el caràcter que ens cal a cada moment.
Per a aquest primer exemple, mostrarem els caràcters en vermell. Atès que aquest és l'únic ús que donarem a la matriu de LED, podríem deixar sempre actiu el registre del color vermell i eliminar la interrupció que els va activant seqüencialment. Hem optat, però, per mantenir-ho; en previsió que el programa pugui ser ampliat amb altres usos de la matriu.
Per definir els caràcters ens hem basat en la definició que hi ha a la pàgina 17 del full de característiques de la pantalla sèrie i ho hem fet emprant aquest full de càlcul, que ja ens genera la línia completa per posar al programa.
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
Port EQU 0x20 ; Bits a enviar al port B
Sortida EQU 0x21 ; Valors a enviar al MAX7221 (6 bytes, 48 bits)
Compta EQU 0x27 ; Variable per comptar els bits
Filera EQU 0x28 ; Variable per comptar fileres
Compt EQU 0x29 ; Comptador per al bucle d'enviar
AdreH EQU 0x2A ; Adreça on hi ha les dades
AdreL EQU 0x2B ; Adreça on hi ha les dades
Valor EQU 0x2C ; Valor a enviar
Actiu EQU 0x2D ; Variable que diu quin color està actiu
; Actiu = 0 Apagat
; Actiu = 1 Vermell
; Actiu = 2 Verd
; Actiu = 3 Blau
Retard1 EQU 0x2E ; Variables per als cicles de retard
Retard2 EQU 0x2F
Retard3 EQU 0x30
; Zona de memòria de dades que no depèn del banc triat
W_Copia EQU 0x70 ; Guardarà el contingut de W durant la interrupció
ST_Copia EQU 0x71 ; Guardarà STATUS durant la interrupció
PSECT code, class=CODE, delta=2, abs main: ; Adreça 0 h goto Inici ; Saltem al lloc on hi ha el programa principal nop ; Zona de memòria de programa que no utilitzem nop nop
Interrup: ; Adreça 4 h
movwf W_Copia ; Copiem l'acumulador a W_Copia
swapf STATUS,w ; Copiem STATUS a l'acumulador permutant els nibbles
clrf STATUS ; Posa a 0 i així segur que el banc és el 0
movwf ST_Copia ; Guarda STATUS permutat a ST_Copia
btfss T0IF ; Mira si Timer0 ha arribat a zero
; Si hi ha arribat, no fa la instrucció següent
goto FiInt ; Si la interrupció no és del Timer0 no fem res
Timer0: ; Programa corresponent a Timer0
bcf T0IF ; Si ha arribat, desactivem el bit
movlw 100 ; Nova preselecció
movwf TMR0 ; Ho posem a TMR0
; Anem a gestionar el canvi de color
movlw 00000011B ; Descarta els bits que no serveixen
andwf Actiu,f
btfsc ZERO
goto NoZero ; Si Actiu val 0 no ho canvia
decf Actiu,f ; Passem a activar un altre color
btfss ZERO ; Si s'activa Z és que hem arribat a zero
goto NoZero ; Si és zero, tornem a 3
movlw 3
movwf Actiu
NoZero: ; Gestiona l'activació de tres MAX7221
; Segons Actiu, activa un color o un altre
movlw 00000011B ; Descarta els bits que no serveixen
andwf Actiu,f
btfsc ZERO ; Salta si el resultat no és zero
goto Apagat ; Si està apagat ho desactiva tot
movlw 1
xorwf Actiu,w
btfsc ZERO
goto Vermell ; Si val 1, activem el vermell
movlw 2
xorwf Actiu,w
btfsc ZERO
goto Verd ; Si val 2, activem el verd
; Si no és cap d'ells, activem el blau
movlw 0x01 ; Activat
movwf Sortida+4 ; Blau
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+2 ; Verd
movlw 1
goto Activa
Vermell:
movlw 0x01 ; Activat
movwf Sortida ; Vermell
movlw 0x00 ; Desactivat
movwf Sortida+2 ; Verd
movwf Sortida+4 ; Blau
nop ; Temps a afegir
nop
nop
nop
goto Activa
Verd:
movlw 0x01 ; Activat
movwf Sortida+2 ; Verd
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+4 ; Blau
goto Activa
Apagat:
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+2 ; Verd
movwf Sortida+4 ; Blau
Activa:
movlw 0x0C ; Shutdown mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
FiInt:
swapf ST_Copia,w ; Copia permutant ST_Copia a l'acumulador
movwf STATUS ; I ho passa a STATUS recuperant el valor d'abans
; de la interrupció
swapf W_Copia,f ; Permuta els bits de W_Copia
swapf W_Copia,w ; Torna a permutar els bits de W_Copia
; i els guarda a l'acumulador sense variar STATUS
retfie ; Torna al programa principal, on s'havia quedat
Inici:
bsf RP0 ; Tria el banc 1
movlw 10000101B ; Configuració de Timer0
; Com a temporitzador basat en rellotge
; 101 - Factor d'escala de 64
; I resistències de pull-up desactivades (valor per defecte)
movwf OPTION_REG ; Ho guarda al registre de configuració del Timer0
movlw 0xFF ; Posa l'acumulador a FFh (tot uns)
movwf TRISA ; Posa tots els bits del port A com a entrada
clrf TRISB ; Posa tots els bits del port B com a sortida
clrf TRISC ; Posa tots els bits del port C com a sortida
bcf RP0
bsf RP1 ; Tria el banc 2
movlw 00000101B
movwf ANSEL ; Configura AN0 i AN2 com entrada analògica
bcf RP0
bcf RP1 ; Tria el banc 0
clrf PORTC
clrf Port ; Posa a zero tots els bits de la variable Port
movf Port,w
movwf PORTB ; I ho envia al port B
call Ini3max ; Inicialitza la matriu
; Configura Timer 0 i activa la matriu i les interrupcions
; Una interrupció cada, aproximadament, 10 ms
movlw 1
movwf Actiu ; Posa en marxa el vermell
movlw 100 ; Presselecció de 100, que són 156 iteracions
movwf TMR0 ; Ho posa com a preselecció del temporitzador
movlw 10100000B ; Activem GIE i T0IE
movwf INTCON ; Activa les interrupcions globals i la de Timer0
call Apaga ; Apaga els LED
Bucle:
movlw 0; Xifra 0
movwf Valor
call EnviaMat
movlw 5 ; Retard
call Retard
movlw 1; Xifra 1
movwf Valor
call EnviaMat
movlw 5 ; Retard
call Retard
movlw 2; Xifra 2
movwf Valor
call EnviaMat
movlw 5 ; Retard
call Retard
movlw 3; Xifra 3
movwf Valor
call EnviaMat
movlw 5 ; Retard
call Retard
goto Bucle ; Torna a repetir
;
; Envia les dades d'una de les matrius als MAX7221
;
; Atenció: El contingut de Valor es perd
EnviaMat:
movlw high Carac ; Carrega la part alta de l'adreça de la taula
movwf AdreH ; Ho guarda per posar-ho a PCLATH
movlw low Carac ; Carrega la part baixa de l'adreça de la taula
movwf AdreL ; Ho guarda per posar-ho a PCL
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,f ; Valor que volem enviar, multiplicat per 2
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,f ; Valor que volem enviar, multiplicat per 4
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,w ; Valor que volem enviar, multiplicat per 8; el deixem a w
addwf AdreL,f ; Ho suma a la posició
btfsc CARRY ; Mirem si s'activa C
incf AdreH,f ; Si s'ha activat, incrementem AdreH
movlw 1 ; Primera filera
movwf Filera
movlw 8 ; Número de fileres a enviar
movwf Compt ; Ho guarda al comptador
BucMat:
movf Filera,w ; Filera actual
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
call Llegir ; Llegeix la filera
movwf Sortida ; Vermells
movlw 0 ; El verd i el blau apagats
movwf Sortida+2 ; Verds
movwf Sortida+4 ; Blaus
; Preparem per a la filera següent
incf AdreL,f ; Incrementa el punter
btfsc ZERO ; S'ha activat Z?
incf AdreH,f ; Si s'ha activat, incrementem AdreH
call Envia3max ; Ho envia al MAX7221
incf Filera,f ; Filera següent
decfsz Compt ; Decrementa el comptador
goto BucMat ; Si no és zero, envia el següent
return
;
; Apaga tots els LED
;
Apaga:
movlw 8 ; Hem d'apagar vuit fileres
movwf Filera ; Ho guarda al comptador
Repetir:
movf Filera,w ; Filera actual
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 00000000B ; Apagat
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia3max ; Ho envia al MAX7221
decfsz Filera,f ; Passem a una altra filera
goto Repetir
return
;
; Inicialització de tres MAX7221
;
Ini3max:
movlw 0x0C ; Shutdown mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x00 ; Desactivat
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
movlw 0x09 ; Decode mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x00 ; No decode
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
movlw 0x0B ; Scan limit
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x07 ; Vuit fileres
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
return
;
; Envia dades (48 bits) a tres MAX7221
; desactivant les interrupcions
;
Envia3max:
bcf T0IE ; Desactiva les interrupcions momentàniament
call Envia_max
bsf T0IE ; Reactiva les interrupcions a l'acabar
return
;
; Envia dades (48 bits) a tres MAX7221
;
; Els bits estan a les variables:
; Sortida Valor vermells
; Sortida+1 Adreça vermells
; Sortida+2 Valor verds
; Sortida+3 Adreça verds
; Sortida+4 Valor blaus
; Sortida+5 Adreça blaus
; Al final de la funció, el valor de Sortida queda corromput
; Si es vol conservar, cal copiar-lo a una altra variable
;
; Aquesta funció dura, aproximadament, 1 ms
Envia_max:
bcf Port,5 ; S'assegura que Clock està desactivat
bcf Port,6 ; S'assegura que Latch està desactivat
movf Port,w ; Agafa el valor de Port
movwf PORTB ; I el posa al port B
movlw 48 ; Número de bits a enviar
movwf Compta ; Variable per comptar els bits
Bucle3max:
bcf Port,4 ; Desactiva Data. Si toca activar-ho, ja ho farem
rlf Sortida,f ; Fa sortir el bit de més a l'esquerra cap a C
rlf Sortida+1,f ; i roda els altres a l'esquerra
rlf Sortida+2,f
rlf Sortida+3,f
rlf Sortida+4,f
rlf Sortida+5,f
btfsc CARRY ; Mira si el bit de l'esquerra era un 1
bsf Port,4 ; Si era 1, activa Data
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Data
movwf PORTB ; I el posa al port B
bsf Port,5 ; Activa Clock, forçant a llegir el bit
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Clock
movwf PORTB ; I el posa al port B
bcf Port,5 ; Desactiva Clock
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Clock
movwf PORTB ; I el posa al port B
decfsz Compta,f ; Decrementa Compta
goto Bucle3max ; Si Compta no és zero, repeteix el bucle
bsf Port,6 ; Torna a activar Latch
; Els valors es copiaran a la sortida del registre
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Latch
movwf PORTB ; I el posa al port B
return
;
; Funció de retard de 0,2 W s
;
Retard:
movwf Retard3
Bucles:
decfsz Retard1,f
goto Bucles
decfsz Retard2,f
goto Bucles
decfsz Retard3,f
goto Bucles
return
;
; Llegeix la taula amb les imatges
;
Llegir:
bcf T0IE ; Desactiva les interrupcions momentàniament
movf AdreH,w ; Llegim l'adreça de la variable
bsf RP1 ; Tria el banc 2
movwf EEADRH ; Adreça EEPROM
bcf RP1 ; Tria el banc 0
movf AdreL,w ; Llegim l'adreça de la variable
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
bsf T0IE ; Activa les interrupcions
return
Carac: ; Cada línia correspon a una xifra de 0 a 3 (vuit bytes per xifra) DB 00011100B, 00100010B, 00100110B, 00101010B, 00110010B, 00100010B, 00011100B, 00000000B ; 0 DB 00001000B, 00011000B, 00001000B, 00001000B, 00001000B, 00001000B, 00011100B, 00000000B ; 1 DB 00011100B, 00100010B, 00000010B, 00000100B, 00001000B, 00010000B, 00111110B, 00000000B ; 2 DB 00111110B, 00000100B, 00001000B, 00000100B, 00000010B, 00100010B, 00011100B, 00000000B ; 3 END main
El següent programa té dues millores respecte a l'anterior. Per un costat, hem creat una llista a la memòria de programa que indicarà quin caràcter s'ha de mostrar en cada moment. Per fer-ho més visual, hem optat per posar les xifres desordenades.
L'altra millora és que hem implementat la possibilitat de triar el color. La funció EnviaMat mira la variable Color i, segons el seu valor, fa sortir els caràcters en el color triat. Els valors que corresponen a cada color són els de la taula següent:
| Valor de Color | Color que li correspon | ||
| Decimal | Binari | 2 ⨯ Hex | |
| 7 | 111 | E | Blanc |
| 6 | 110 | C | Groc |
| 5 | 101 | A | Magenta |
| 4 | 100 | 8 | Vermell |
| 3 | 011 | 6 | Cian |
| 2 | 010 | 4 | Verd |
| 1 | 001 | 2 | Blau |
| 0 | 000 | 0 | Apagat |
Podem observar que cada un dels tres bits menys significatius correspon a un dels tres colors primaris (vermell, verd i blau), i això fa molt més fàcil comprovar quins dels colors s'han d'activar.
En aquest cas s'ha optat per fer sortir tots els caràcters de tots els colors (excepte apagat), seguin l'ordre de la taula. No seria complicat, però, fer una llista en la qual s'indiqués de quin color ha de sortir cada caràcter.
PROCESSOR 16F690 #include <xc.inc> #define numcar 4 config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Port EQU 0x20 ; Bits a enviar al port B
Sortida EQU 0x21 ; Valors a enviar al MAX7221 (6 bytes, 48 bits)
Compta EQU 0x27 ; Variable per comptar els bits
Filera EQU 0x28 ; Variable per comptar fileres
Compt EQU 0x29 ; Comptador per al bucle d'enviar
AdreH EQU 0x2A ; Adreça on hi ha les dades
AdreL EQU 0x2B ; Adreça on hi ha les dades
Valor EQU 0x2C ; Valor a enviar
Posic EQU 0x2D ; Posició a la llista de caràcters
Color EQU 0x2E ; Color en el que es mostrarà el text
; 4 vermell 2 verd 1 blau 7 blanc
; 6 groc 5 magenta 3 cian 0 apagat
Actiu EQU 0x2F ; Variable que diu quin color està actiu
; Actiu = 0 Apagat
; Actiu = 1 Vermell
; Actiu = 2 Verd
; Actiu = 3 Blau
Retard1 EQU 0x30 ; Variables per als cicles de retard
Retard2 EQU 0x31
Retard3 EQU 0x32
; Zona de memòria de dades que no depèn del banc triat
W_Copia EQU 0x70 ; Guardarà el contingut de W durant la interrupció
ST_Copia EQU 0x71 ; Guardarà STATUS durant la interrupció
PSECT code, class=CODE, delta=2, abs main: ; Adreça 0 h goto Inici ; Saltem al lloc on hi ha el programa principal nop ; Zona de memòria de programa que no utilitzem nop nop
Interrup: ; Adreça 4 h
movwf W_Copia ; Copiem l'acumulador a W_Copia
swapf STATUS,w ; Copiem STATUS a l'acumulador permutant els nibbles
clrf STATUS ; Posa a 0 i així segur que el banc és el 0
movwf ST_Copia ; Guarda STATUS permutat a ST_Copia
btfss T0IF ; Mira si Timer0 ha arribat a zero
; Si hi ha arribat, no fa la instrucció següent
goto FiInt ; Si la interrupció no és del Timer0 no fem res
Timer0: ; Programa corresponent a Timer0
bcf T0IF ; Si ha arribat, desactivem el bit
movlw 100 ; Nova preselecció
movwf TMR0 ; Ho posem a TMR0
; Anem a gestionar el canvi de color
movlw 00000011B ; Descarta els bits que no serveixen
andwf Actiu,f
btfsc ZERO
goto NoZero ; Si Actiu val 0 no ho canvia
decf Actiu,f ; Passem a activar un altre color
btfss ZERO ; Si s'activa Z és que hem arribat a zero
goto NoZero ; Si és zero, tornem a 3
movlw 3
movwf Actiu
NoZero: ; Gestiona l'activació de tres MAX7221
; Segons Actiu, activa un color o un altre
movlw 00000011B ; Descarta els bits que no serveixen
andwf Actiu,f
btfsc ZERO ; Salta si el resultat no és zero
goto Apagat ; Si està apagat ho desactiva tot
movlw 1
xorwf Actiu,w
btfsc ZERO
goto Vermell ; Si val 1, activem el vermell
movlw 2
xorwf Actiu,w
btfsc ZERO
goto Verd ; Si val 2, activem el verd
; Si no és cap d'ells, activem el blau
movlw 0x01 ; Activat
movwf Sortida+4 ; Blau
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+2 ; Verd
movlw 1
goto Activa
Vermell:
movlw 0x01 ; Activat
movwf Sortida ; Vermell
movlw 0x00 ; Desactivat
movwf Sortida+2 ; Verd
movwf Sortida+4 ; Blau
nop ; Temps a afegir
nop
nop
nop
goto Activa
Verd:
movlw 0x01 ; Activat
movwf Sortida+2 ; Verd
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+4 ; Blau
goto Activa
Apagat:
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+2 ; Verd
movwf Sortida+4 ; Blau
Activa:
movlw 0x0C ; Shutdown mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
FiInt:
swapf ST_Copia,w ; Copia permutant ST_Copia a l'acumulador
movwf STATUS ; I ho passa a STATUS recuperant el valor d'abans
; de la interrupció
swapf W_Copia,f ; Permuta els bits de W_Copia
swapf W_Copia,w ; Torna a permutar els bits de W_Copia
; i els guarda a l'acumulador sense variar STATUS
retfie ; Torna al programa principal, on s'havia quedat
Inici:
bsf RP0 ; Tria el banc 1
movlw 10000101B ; Configuració de Timer0
; Com a temporitzador basat en rellotge
; 101 - Factor d'escala de 64
; I resistències de pull-up desactivades (valor per defecte)
movwf OPTION_REG ; Ho guarda al registre de configuració del Timer0
movlw 0xFF ; Posa l'acumulador a FFh (tot uns)
movwf TRISA ; Posa tots els bits del port A com a entrada
clrf TRISB ; Posa tots els bits del port B com a sortida
clrf TRISC ; Posa tots els bits del port C com a sortida
bcf RP0
bsf RP1 ; Tria el banc 2
movlw 00000101B
movwf ANSEL ; Configura AN0 i AN2 com entrada analògica
bcf RP0
bcf RP1 ; Tria el banc 0
clrf PORTC
clrf Port ; Posa a zero tots els bits de la variable Port
movf Port,w
movwf PORTB ; I ho envia al port B
call Ini3max ; Inicialitza la matriu
; Configura Timer 0 i activa la matriu i les interrupcions
; Una interrupció cada, aproximadament, 10 ms
movlw 1
movwf Actiu ; Posa en marxa el vermell
movlw 100 ; Presselecció de 100, que són 156 iteracions
movwf TMR0 ; Ho posa com a preselecció del temporitzador
movlw 10100000B ; Activem GIE i T0IE
movwf INTCON ; Activa les interrupcions globals i la de Timer0
call Apaga ; Apaga els LED
movlw 7 ; Comencem amb blanc
movwf Color
movlw 0 ; Comencem pel primer caràcter a mostrar
movwf Posic
Bucle:
movlw high Text ; Carrega la part alta de l'adreça de la taula
movwf AdreH ; Ho guarda per posar-ho a PCLATH
movlw low Text ; Carrega la part baixa de l'adreça de la taula
movwf AdreL ; Ho guarda per posar-ho a PCL
movf Posic,w ; Quin caràcter toca
addwf AdreL,f ; Ho suma a la posició
btfsc CARRY ; Mirem si s'activa C
incf AdreH,f ; Si s'ha activat, incrementem AdreH
call Llegir ; Llegeix la filera
movwf Valor
call EnviaMat
movlw 5 ; Retard
call Retard
incf Posic,f
movlw numcar ; Nombre total de caràcters
xorwf Posic,w ; Mira si ja hi hem arribat
btfss ZERO
goto Diferents
Iguals:
clrf Posic ; Tornem al primer
decf Color,f ; Canviem el color
movlw 7 ; En previsió, preparem per posar blanc
btfsc ZERO ; Mira si hem arribat a zero
movwf Color ; Si hem arribat a zero, tornem a començar
Diferents:
goto Bucle ; Torna a repetir
;
; Envia les dades d'una de les matrius als MAX7221
;
; Atenció: El contingut de Valor es perd
EnviaMat:
movlw high Carac ; Carrega la part alta de l'adreça de la taula
movwf AdreH ; Ho guarda per posar-ho a PCLATH
movlw low Carac ; Carrega la part baixa de l'adreça de la taula
movwf AdreL ; Ho guarda per posar-ho a PCL
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,f ; Valor que volem enviar, multiplicat per 2
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,f ; Valor que volem enviar, multiplicat per 4
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,w ; Valor que volem enviar, multiplicat per 8; el deixem a w
addwf AdreL,f ; Ho suma a la posició
btfsc CARRY ; Mirem si s'activa C
incf AdreH,f ; Si s'ha activat, incrementem AdreH
movlw 1 ; Primera filera
movwf Filera
movlw 8 ; Número de fileres a enviar
movwf Compt ; Ho guarda al comptador
BucMat:
movlw 0 ; Per defecte, els tres colors apagats
movwf Sortida ; Vermells
movwf Sortida+2 ; Verds
movwf Sortida+4 ; Blaus
movf Filera,w ; Filera actual
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
call Llegir ; Llegeix la filera
btfsc Color,2 ; S'ha de posar vermell?
movwf Sortida ; Vermells
btfsc Color,1 ; S'ha de posar verd?
movwf Sortida+2 ; Verds
btfsc Color,0 ; S'ha de posar blau?
movwf Sortida+4 ; Blaus
incf AdreL,f ; Incrementa el punter
btfsc ZERO ; S'ha activat Z?
incf AdreH,f ; Si s'ha activat, incrementem AdreH
call Envia3max ; Ho envia al MAX7221
incf Filera,f ; Filera següent
decfsz Compt ; Decrementa el comptador
goto BucMat ; Si no és zero, envia el següent
return
;
; Apaga tots els LED
;
Apaga:
movlw 8 ; Hem d'apagar vuit fileres
movwf Filera ; Ho guarda al comptador
Repetir:
movf Filera,w ; Filera actual
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 00000000B ; Apagat
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia3max ; Ho envia al MAX7221
decfsz Filera,f ; Passem a una altra filera
goto Repetir
return
;
; Inicialització de tres MAX7221
;
Ini3max:
movlw 0x0C ; Shutdown mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x00 ; Desactivat
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
movlw 0x09 ; Decode mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x00 ; No decode
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
movlw 0x0B ; Scan limit
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x07 ; Vuit fileres
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
return
;
; Envia dades (48 bits) a tres MAX7221
; desactivant les interrupcions
;
Envia3max:
bcf T0IE ; Desactiva les interrupcions momentàniament
call Envia_max
bsf T0IE ; Reactiva les interrupcions a l'acabar
return
;
; Envia dades (48 bits) a tres MAX7221
;
; Els bits estan a les variables:
; Sortida Valor vermells
; Sortida+1 Adreça vermells
; Sortida+2 Valor verds
; Sortida+3 Adreça verds
; Sortida+4 Valor blaus
; Sortida+5 Adreça blaus
; Al final de la funció, el valor de Sortida queda corromput
; Si es vol conservar, cal copiar-lo a una altra variable
;
; Aquesta funció dura, aproximadament, 1 ms
Envia_max:
bcf Port,5 ; S'assegura que Clock està desactivat
bcf Port,6 ; S'assegura que Latch està desactivat
movf Port,w ; Agafa el valor de Port
movwf PORTB ; I el posa al port B
movlw 48 ; Número de bits a enviar
movwf Compta ; Variable per comptar els bits
Bucle3max:
bcf Port,4 ; Desactiva Data. Si toca activar-ho, ja ho farem
rlf Sortida,f ; Fa sortir el bit de més a l'esquerra cap a C
rlf Sortida+1,f ; i roda els altres a l'esquerra
rlf Sortida+2,f
rlf Sortida+3,f
rlf Sortida+4,f
rlf Sortida+5,f
btfsc CARRY ; Mira si el bit de l'esquerra era un 1
bsf Port,4 ; Si era 1, activa Data
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Data
movwf PORTB ; I el posa al port B
bsf Port,5 ; Activa Clock, forçant a llegir el bit
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Clock
movwf PORTB ; I el posa al port B
bcf Port,5 ; Desactiva Clock
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Clock
movwf PORTB ; I el posa al port B
decfsz Compta,f ; Decrementa Compta
goto Bucle3max ; Si Compta no és zero, repeteix el bucle
bsf Port,6 ; Torna a activar Latch
; Els valors es copiaran a la sortida del registre
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Latch
movwf PORTB ; I el posa al port B
return
;
; Funció de retard de 0,2 W s
;
Retard:
movwf Retard3
Bucles:
decfsz Retard1,f
goto Bucles
decfsz Retard2,f
goto Bucles
decfsz Retard3,f
goto Bucles
return
;
; Llegeix la taula amb les imatges
;
Llegir:
bcf T0IE ; Desactiva les interrupcions momentàniament
movf AdreH,w ; Llegim l'adreça de la variable
bsf RP1 ; Tria el banc 2
movwf EEADRH ; Adreça EEPROM
bcf RP1 ; Tria el banc 0
movf AdreL,w ; Llegim l'adreça de la variable
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
bsf T0IE ; Activa les interrupcions
return
Carac: ; Cada línia correspon a una xifra de 0 a 3 (vuit bytes per xifra) DB 00011100B, 00100010B, 00100110B, 00101010B, 00110010B, 00100010B, 00011100B, 00000000B ; 0 DB 00001000B, 00011000B, 00001000B, 00001000B, 00001000B, 00001000B, 00011100B, 00000000B ; 1 DB 00011100B, 00100010B, 00000010B, 00000100B, 00001000B, 00010000B, 00111110B, 00000000B ; 2 DB 00111110B, 00000100B, 00001000B, 00000100B, 00000010B, 00100010B, 00011100B, 00000000B ; 3 Text: DB 0, 2, 1, 3 END main
Si hem definit menys de 33 caràcters, podem fer servir una altra opció. En el programa següent hem fet servir les mateixes posicions de la taula per codificar el caràcter i el color que cal mostrar a cada moment. Els tres bits de més a l'esquerra representen el color (amb el mateix criteri que abans) i els cinc de la dreta indiquen el caràcter. En el moment de llegir la llista es guardarà el valor llegit a la variable Valor i a la variable Color. La variable Valor es roda sempre tres posicions a l'esquerra per multiplicar per vuit, de manera que la indicació del color ja es perd. Caldrà rodar la variable Color cinc posicions a la dreta per situar els tres bits a la posició correcta. Els valors s'han posat en hexadecimal, per interpretar els colors cal mirar la columna corresponent de la taula que hi ha més amunt.
PROCESSOR 16F690 #include <xc.inc> #define numcar 7 config FOSC = INTRCIO, WDTE = OFF, PWRTE = OFF, MCLRE = OFF, CP = OFF config CPD = OFF, BOREN = OFF, IESO = OFF, FCMEN = OFF
Port EQU 0x20 ; Bits a enviar al port B
Sortida EQU 0x21 ; Valors a enviar al MAX7221 (6 bytes, 48 bits)
Compta EQU 0x27 ; Variable per comptar els bits
Filera EQU 0x28 ; Variable per comptar fileres
Compt EQU 0x29 ; Comptador per al bucle d'enviar
AdreH EQU 0x2A ; Adreça on hi ha les dades
AdreL EQU 0x2B ; Adreça on hi ha les dades
Valor EQU 0x2C ; Valor a enviar
Posic EQU 0x2D ; Posició a la llista de caràcters
Color EQU 0x2E ; Color en el que es mostrarà el text
; 8 vermell 4 verd 2 blau E blanc
; C groc A magenta 6 cian 0 apagat
Actiu EQU 0x2F ; Variable que diu quin color està actiu
; Actiu = 0 Apagat
; Actiu = 1 Vermell
; Actiu = 2 Verd
; Actiu = 3 Blau
Retard1 EQU 0x30 ; Variables per als cicles de retard
Retard2 EQU 0x31
Retard3 EQU 0x32
; Zona de memòria de dades que no depèn del banc triat
W_Copia EQU 0x70 ; Guardarà el contingut de W durant la interrupció
ST_Copia EQU 0x71 ; Guardarà STATUS durant la interrupció
PSECT code, class=CODE, delta=2, abs main: ; Adreça 0 h goto Inici ; Saltem al lloc on hi ha el programa principal nop ; Zona de memòria de programa que no utilitzem nop nop
Interrup: ; Adreça 4 h
movwf W_Copia ; Copiem l'acumulador a W_Copia
swapf STATUS,w ; Copiem STATUS a l'acumulador permutant els nibbles
clrf STATUS ; Posa a 0 i així segur que el banc és el 0
movwf ST_Copia ; Guarda STATUS permutat a ST_Copia
btfss T0IF ; Mira si Timer0 ha arribat a zero
; Si hi ha arribat, no fa la instrucció següent
goto FiInt ; Si la interrupció no és del Timer0 no fem res
Timer0: ; Programa corresponent a Timer0
bcf T0IF ; Si ha arribat, desactivem el bit
movlw 100 ; Nova preselecció
movwf TMR0 ; Ho posem a TMR0
; Anem a gestionar el canvi de color
movlw 00000011B ; Descarta els bits que no serveixen
andwf Actiu,f
btfsc ZERO
goto NoZero ; Si Actiu val 0 no ho canvia
decf Actiu,f ; Passem a activar un altre color
btfss ZERO ; Si s'activa Z és que hem arribat a zero
goto NoZero ; Si és zero, tornem a 3
movlw 3
movwf Actiu
NoZero: ; Gestiona l'activació de tres MAX7221
; Segons Actiu, activa un color o un altre
movlw 00000011B ; Descarta els bits que no serveixen
andwf Actiu,f
btfsc ZERO ; Salta si el resultat no és zero
goto Apagat ; Si està apagat ho desactiva tot
movlw 1
xorwf Actiu,w
btfsc ZERO
goto Vermell ; Si val 1, activem el vermell
movlw 2
xorwf Actiu,w
btfsc ZERO
goto Verd ; Si val 2, activem el verd
; Si no és cap d'ells, activem el blau
movlw 0x01 ; Activat
movwf Sortida+4 ; Blau
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+2 ; Verd
movlw 1
goto Activa
Vermell:
movlw 0x01 ; Activat
movwf Sortida ; Vermell
movlw 0x00 ; Desactivat
movwf Sortida+2 ; Verd
movwf Sortida+4 ; Blau
nop ; Temps a afegir
nop
nop
nop
goto Activa
Verd:
movlw 0x01 ; Activat
movwf Sortida+2 ; Verd
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+4 ; Blau
goto Activa
Apagat:
movlw 0x00 ; Desactivat
movwf Sortida ; Vermell
movwf Sortida+2 ; Verd
movwf Sortida+4 ; Blau
Activa:
movlw 0x0C ; Shutdown mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
FiInt:
swapf ST_Copia,w ; Copia permutant ST_Copia a l'acumulador
movwf STATUS ; I ho passa a STATUS recuperant el valor d'abans
; de la interrupció
swapf W_Copia,f ; Permuta els bits de W_Copia
swapf W_Copia,w ; Torna a permutar els bits de W_Copia
; i els guarda a l'acumulador sense variar STATUS
retfie ; Torna al programa principal, on s'havia quedat
Inici:
bsf RP0 ; Tria el banc 1
movlw 10000101B ; Configuració de Timer0
; Com a temporitzador basat en rellotge
; 101 - Factor d'escala de 64
; I resistències de pull-up desactivades (valor per defecte)
movwf OPTION_REG ; Ho guarda al registre de configuració del Timer0
movlw 0xFF ; Posa l'acumulador a FFh (tot uns)
movwf TRISA ; Posa tots els bits del port A com a entrada
clrf TRISB ; Posa tots els bits del port B com a sortida
clrf TRISC ; Posa tots els bits del port C com a sortida
bcf RP0
bsf RP1 ; Tria el banc 2
movlw 00000101B
movwf ANSEL ; Configura AN0 i AN2 com entrada analògica
bcf RP0
bcf RP1 ; Tria el banc 0
clrf PORTC
clrf Port ; Posa a zero tots els bits de la variable Port
movf Port,w
movwf PORTB ; I ho envia al port B
call Ini3max ; Inicialitza la matriu
; Configura Timer 0 i activa la matriu i les interrupcions
; Una interrupció cada, aproximadament, 10 ms
movlw 1
movwf Actiu ; Posa en marxa el vermell
movlw 100 ; Presselecció de 100, que són 156 iteracions
movwf TMR0 ; Ho posa com a preselecció del temporitzador
movlw 10100000B ; Activem GIE i T0IE
movwf INTCON ; Activa les interrupcions globals i la de Timer0
call Apaga ; Apaga els LED
movlw 0 ; Comencem pel primer caràcter a mostrar
movwf Posic
Bucle:
movlw high Text ; Carrega la part alta de l'adreça de la taula
movwf AdreH ; Ho guarda per posar-ho a PCLATH
movlw low Text ; Carrega la part baixa de l'adreça de la taula
movwf AdreL ; Ho guarda per posar-ho a PCL
movf Posic,w ; Quin caràcter toca
addwf AdreL,f ; Ho suma a la posició
btfsc CARRY ; Mirem si s'activa C
incf AdreH,f ; Si s'ha activat, incrementem AdreH
call Llegir ; Llegeix la filera
movwf Valor ; No cal eliminar el color perquè es rodarà a EnviaMat
movwf Color ; Color fora de lloc, cal rodar cinc cops
rrf Color,f ; No cal posar a 0 el bit CARRY perquè no mirarem més que tres bits
rrf Color,f
rrf Color,f
rrf Color,f
rrf Color,f
call EnviaMat
movlw 5 ; Retard
call Retard
incf Posic,f
movlw numcar ; Nombre total de caràcters
xorwf Posic,w ; Mira si ja hi hem arribat
btfss ZERO
goto Diferents
Iguals:
clrf Posic ; Tornem al primer
Diferents:
goto Bucle ; Torna a repetir
;
; Envia les dades d'una de les matrius als MAX7221
;
; Atenció: El contingut de Valor es perd
EnviaMat:
movlw high Carac ; Carrega la part alta de l'adreça de la taula
movwf AdreH ; Ho guarda per posar-ho a PCLATH
movlw low Carac ; Carrega la part baixa de l'adreça de la taula
movwf AdreL ; Ho guarda per posar-ho a PCL
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,f ; Valor que volem enviar, multiplicat per 2
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,f ; Valor que volem enviar, multiplicat per 4
bcf CARRY ; Ens assegurem que entra un zero
rlf Valor,w ; Valor que volem enviar, multiplicat per 8; el deixem a w
addwf AdreL,f ; Ho suma a la posició
btfsc CARRY ; Mirem si s'activa C
incf AdreH,f ; Si s'ha activat, incrementem AdreH
movlw 1 ; Primera filera
movwf Filera
movlw 8 ; Número de fileres a enviar
movwf Compt ; Ho guarda al comptador
BucMat:
movlw 0 ; Per defecte, els tres colors apagats
movwf Sortida ; Vermells
movwf Sortida+2 ; Verds
movwf Sortida+4 ; Blaus
movf Filera,w ; Filera actual
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
call Llegir ; Llegeix la filera
btfsc Color,2 ; S'ha de posar vermell?
movwf Sortida ; Vermells
btfsc Color,1 ; S'ha de posar verd?
movwf Sortida+2 ; Verds
btfsc Color,0 ; S'ha de posar blau?
movwf Sortida+4 ; Blaus
incf AdreL,f ; Incrementa el punter
btfsc ZERO ; S'ha activat Z?
incf AdreH,f ; Si s'ha activat, incrementem AdreH
call Envia3max ; Ho envia al MAX7221
incf Filera,f ; Filera següent
decfsz Compt ; Decrementa el comptador
goto BucMat ; Si no és zero, envia el següent
return
;
; Apaga tots els LED
;
Apaga:
movlw 8 ; Hem d'apagar vuit fileres
movwf Filera ; Ho guarda al comptador
Repetir:
movf Filera,w ; Filera actual
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 00000000B ; Apagat
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia3max ; Ho envia al MAX7221
decfsz Filera,f ; Passem a una altra filera
goto Repetir
return
;
; Inicialització de tres MAX7221
;
Ini3max:
movlw 0x0C ; Shutdown mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x00 ; Desactivat
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
movlw 0x09 ; Decode mode
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x00 ; No decode
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
movlw 0x0B ; Scan limit
movwf Sortida+1 ; Ho prepara per enviar-ho
movwf Sortida+3 ; Ho prepara per enviar-ho
movwf Sortida+5 ; Ho prepara per enviar-ho
movlw 0x07 ; Vuit fileres
movwf Sortida ; Ho prepara per enviar-ho
movwf Sortida+2 ; Ho prepara per enviar-ho
movwf Sortida+4 ; Ho prepara per enviar-ho
call Envia_max ; Ho envia al MAX7221
return
;
; Envia dades (48 bits) a tres MAX7221
; desactivant les interrupcions
;
Envia3max:
bcf T0IE ; Desactiva les interrupcions momentàniament
call Envia_max
bsf T0IE ; Reactiva les interrupcions a l'acabar
return
;
; Envia dades (48 bits) a tres MAX7221
;
; Els bits estan a les variables:
; Sortida Valor vermells
; Sortida+1 Adreça vermells
; Sortida+2 Valor verds
; Sortida+3 Adreça verds
; Sortida+4 Valor blaus
; Sortida+5 Adreça blaus
; Al final de la funció, el valor de Sortida queda corromput
; Si es vol conservar, cal copiar-lo a una altra variable
;
; Aquesta funció dura, aproximadament, 1 ms
Envia_max:
bcf Port,5 ; S'assegura que Clock està desactivat
bcf Port,6 ; S'assegura que Latch està desactivat
movf Port,w ; Agafa el valor de Port
movwf PORTB ; I el posa al port B
movlw 48 ; Número de bits a enviar
movwf Compta ; Variable per comptar els bits
Bucle3max:
bcf Port,4 ; Desactiva Data. Si toca activar-ho, ja ho farem
rlf Sortida,f ; Fa sortir el bit de més a l'esquerra cap a C
rlf Sortida+1,f ; i roda els altres a l'esquerra
rlf Sortida+2,f
rlf Sortida+3,f
rlf Sortida+4,f
rlf Sortida+5,f
btfsc CARRY ; Mira si el bit de l'esquerra era un 1
bsf Port,4 ; Si era 1, activa Data
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Data
movwf PORTB ; I el posa al port B
bsf Port,5 ; Activa Clock, forçant a llegir el bit
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Clock
movwf PORTB ; I el posa al port B
bcf Port,5 ; Desactiva Clock
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Clock
movwf PORTB ; I el posa al port B
decfsz Compta,f ; Decrementa Compta
goto Bucle3max ; Si Compta no és zero, repeteix el bucle
bsf Port,6 ; Torna a activar Latch
; Els valors es copiaran a la sortida del registre
movf Port,w ; Agafa el valor de Port. El valor que ha canviat és Latch
movwf PORTB ; I el posa al port B
return
;
; Funció de retard de 0,2 W s
;
Retard:
movwf Retard3
Bucles:
decfsz Retard1,f
goto Bucles
decfsz Retard2,f
goto Bucles
decfsz Retard3,f
goto Bucles
return
;
; Llegeix la taula amb les imatges
;
Llegir:
bcf T0IE ; Desactiva les interrupcions momentàniament
movf AdreH,w ; Llegim l'adreça de la variable
bsf RP1 ; Tria el banc 2
movwf EEADRH ; Adreça EEPROM
bcf RP1 ; Tria el banc 0
movf AdreL,w ; Llegim l'adreça de la variable
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
bsf T0IE ; Activa les interrupcions
return
Carac: ; Cada línia correspon a una xifra de 0 a 3 (vuit bytes per xifra) DB 00011100B, 00100010B, 00100110B, 00101010B, 00110010B, 00100010B, 00011100B, 00000000B ; 0 DB 00001000B, 00011000B, 00001000B, 00001000B, 00001000B, 00001000B, 00011100B, 00000000B ; 1 DB 00011100B, 00100010B, 00000010B, 00000100B, 00001000B, 00010000B, 00111110B, 00000000B ; 2 DB 00111110B, 00000100B, 00001000B, 00000100B, 00000010B, 00100010B, 00011100B, 00000000B ; 3 Text: ; color i valor DB 0x80, 0x42, 0x21, 0xC3, 0xA1, 0x62, 0xE0 ; 0 vermell, 2 verd, 1 blau, 3 groc, 1 magenta, 2 cian, 0 blanc END main

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