En aquest exemple farem servir els polsadors per anar movent un cursor per la matriu de LED i encendre del color triat els punts seleccionats. D'aquesta manera, aconseguirem fer un dibuix. El cursor serà del color que està triat en aquell moment i intermitent. Les funcions assignades a cada polsador són les següents:
| Polsador | Funció |
| 0 | Lliure |
| 1 | Desplaçament horitzontal |
| 2 | Desplaçament vertical |
| 3 | Encendre o apagar LED |
| 4 | Canvia el color |
| 5 | Esborrar dibuix |
L'ordre dels colors serà el següent:
| Valor | Color | |
| Decimal | Binari | |
| 0 | 000 | Apagat |
| 1 | 001 | Vermell |
| 2 | 010 | Verd |
| 3 | 011 | Groc |
| 4 | 100 | Blau |
| 5 | 101 | Magenta |
| 6 | 110 | Cian |
Fixem-nos que hem ordenat els colors de manera que cada bit ens representa un dels colors bàsics, això ens facilitarà la programació. Per poder veure el cursor, quan el color triat coincideixi amb el de la casella farem la intermitència amb blanc. Ens hem reservat el color blanc per aquesta finalitat. Podríem haver fet servir la pantalla LCD per indicar el color actual i llavors el cursor podria alternar dos colors que sempre fossin els mateixos i així podríem disposar del blanc per al dibuix.
Encara que en aquest programa no gastem molta memòria de dades (92 bytes, que cabrien al banc 0) hem optat per guardar la matriu figura, que és el que conté els punts del dibuix, al banc 1 de la memòria; així al banc 0 hi ha més espai disponible per si fem servir aquest programa com a base per a futurs projectes. En aquest cas, tots els accessos a la matriu que guarda el dibuix es fan emprant adreçament indirecte. Atès que l'adreçament indirecte treballa amb adreces de vuit bits, es pot accedir directament a les dades del banc 1 sense necessitat de canviar de banc.
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 #define cic_int 35 ; Nombre de cicles per a la intermitència
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 a Envia_max
Compt EQU 0x28 ; Variable per comptar
compY EQU 0x29 ; Comptador per enviar fileres
compX EQU 0x2A ; Comptador per enviar columnes
Filera EQU 0x2B ; Variable per comptar fileres
Actiu EQU 0x2C ; Variable que diu quin color està actiu
; Actiu = 0 Apagat
; Actiu = 1 Vermell
; Actiu = 2 Verd
; Actiu = 3 Blau
Polsador EQU 0x2D ; Variable que conté un bit per a cada polsador per saber si està premut
x EQU 0x2E ; Coordenada X del cursor (0 a 7)
; X = 0 és la columna de la dreta
y EQU 0x2F ; Coordenada Y del cursor (0 a 7)
yact EQU 0x30 ; Filera que estem enviant
xact EQU 0x31 ; Casella que estem enviant
mirar EQU 0x32 ; Espera que es deixi anar el polsador
temp EQU 0x33 ; Variable temporal
compt_int EQU 0x34 ; Comptador de cicles per a la intermitència
cur_on EQU 0x35 ; Controla l'estat del cursor
color EQU 0x36 ; Color seleccionat
mascara EQU 0x37 ; Màscara per preparar els colors
Retard1 EQU 0x38 ; Variables per als cicles de retard
Retard2 EQU 0x39
; 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ó
; Zona de memòria de dades del banc 1
figura EQU 0xA0 ; Aquí guardarem el dibuix (64 bytes, 8 x 8 posicions)
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 als 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
movlw 00010000B
movwf ADCON1 ; Posa el conversor a 1/8 de la freqüència
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
movlw 00001001B
movwf ADCON0 ; Activa el conversor A/D connectat a AN2
; amb el resultat justificat per l'esquerra
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
clrf x ; Posa x a zero
clrf y ; Posa y a zero
movlw 1
movwf mirar ; Posa mirar a 1
movwf cur_on ; Posa cur_on a 1
movwf color ; Posa color a 1, o sigui vermell
movlw cic_int ; Nombre de cicles per a la intermitència
movwf compt_int
call PosaZero ; Posa a zero els bytes del vector figura
Bucle: ; Mirem els polsadors
; Un cop s'ha fet l'acció del polsador, no es tornarà a fer fins
; que es detecti que s'han deixat anar
call Llegir ; Llegeix els polsadors
movf mirar,f ; S'han de mirar els polsadors?
btfsc ZERO ; Si és zero no s'han de mirar
goto NoMirar ; Anem a veure si ja s'ha deixat anar
movf Polsador,w
xorlw 00000001B ; Mirem si s'ha premut el polsador 1
btfss ZERO ; Si és l'1, salta
goto NoEsPol1 ; No és l'1
; S'ha premut el polsador 1
incf x,f ; Incrementem x del cursor
movlw 00000111B ; Valor 7
andwf x,f ; Limitem x entre 0 i 7
goto Zmirar ; Ja estem del polsador 1
NoEsPol1:
movf Polsador,w
xorlw 00000010B ; Mirem si s'ha premut el polsador 2
btfss ZERO ; Si és el 2, salta
goto NoEsPol2 ; No és el 2
; S'ha premut el polsador 2
incf y,f ; Incrementem y del cursor
movlw 00000111B ; Valor 7
andwf y,f ; Limitem y entre 0 i 7
goto Zmirar ; Ja estem del polsador 2
NoEsPol2:
movf Polsador,w
xorlw 00000100B ; Mirem si s'ha premut el polsador 3
btfss ZERO ; Si és el 3, salta
goto NoEsPol3 ; No és el 3
; S'ha premut el polsador 3
movf y,w ; Agafem la filera
movwf temp ; Ho guardem a una variable temporal
bcf CARRY ; Volem entrar zeros
rlf temp,f ; Rodem a l'esquerra i entrem el zero, equival a multiplicar per 2
rlf temp,f ; Rodem a l'esquerra
rlf temp,f ; Rodem a l'esquerra, en total hem multiplicat per 8
movf x,w ; Agafem la columna
addwf temp,f ; Ho sumem al contingut de la variable temporal
movlw figura ; Agafem l'adreça de la primera posició de la matriu
addwf temp,w ; Ho sumem al contingut de la variable temporal, el resultat està a W
movwf FSR ; Ja tenim el punter d'adreçament indirecte
movf color,w ; Agafem el color actual
movwf INDF ; I el posem a la posició corresponent de la matriu
goto Zmirar ; Ja estem del polsador 3
NoEsPol3:
movf Polsador,w
xorlw 00001000B ; Mirem si s'ha premut el polsador 4
btfss ZERO ; Si és el 4, salta
goto NoEsPol4 ; No és el 4
; S'ha premut el polsador 4
incf color,f ; Passem al color següent
movlw 00000111B ; Valor 7
xorwf color,w ; Mirem si és 7
btfss ZERO ; Si és 7 hem de canviar-lo
goto no7 ; Si no és 7 no cal fer res
clrf color ; El posem a zero
no7:
goto Zmirar ; Ja estem del polsador 4
NoEsPol4:
movf Polsador,w
xorlw 00010000B ; Mirem si s'ha premut el polsador 5
btfss ZERO ; Si és el 5, salta
goto NoEsPol5 ; No és el 5
; S'ha premut el polsador 5
call PosaZero ; Posa a zero els bytes del vector figura
Zmirar: ; Ja estem del polsador 5
clrf mirar ; Posa mirar a zero fins que es deixi el polsador
NoEsPol5:
goto Matriu ; Envia la figura actual a la matriu
NoMirar:
movf Polsador,w ; Agafem la lectura dels polsadors
btfss ZERO ; Mira si és zero
goto Matriu ; Si no és zero cal seguir esperant
movlw 1 ; Si és zero, s'ha deixat el polsador
movwf mirar ; Posa mirar a 1
Matriu: ; Anem a mostrar la figura actual a la matriu de LED
clrf yact ; Primer enviem la filera 0
movlw figura ; Agafem l'adreça de la primera posició del vector
movwf FSR ; La posem com a punter d'adreçament indirecte
movlw 8 ; Número de fileres que cal enviar
movwf compY ; Fileres
bucleY: ; Bucle que recorre les fileres
clrf xact ; Primer enviem la casella 0
movlw 8 ; Número de caselles de la filera
movwf compX ; Columnes
clrf Sortida ; Vermell, en principi, a zero
clrf Sortida+2 ; Verd, en principi, a zero
clrf Sortida+4 ; Blau, en principi, a zero
bucleX: ; Bucle que recorre les caselles de cada filera
; Anem a veure si estem a la casella del cursor
; El cursor es mostra en el color actual però si coincideix
; amb el color de la casella el mostrem blanc
movf yact,w ; Mirem la filera que estem enviant
xorwf y,w ; I comparem amb la del cursor
btfss ZERO ; Si és zero, són iguals
goto noCur ; No és la filera del cursor
movf xact,w ; Mirem la casella que estem enviant
xorwf x,w ; I comparem amb la del cursor
btfss ZERO ; Si és zero, són iguals
goto noCur ; No és la casella del cursor
; Mirem si s'ha de mostrar el cursor
movf cur_on,w ; Mirem el valor de cur_on
btfsc ZERO ; Si no és zero, mostrem el cursor
goto noCur ; Si és zero no hem de mostrar el cursor
movf color,w ; Agafem el color actual
movwf temp ; El guardem a la variable temporal
xorwf INDF,w ; Comparem amb el color de la casella actual
btfss ZERO ; Si és zero, són iguals
goto fiCur ; Si no és 0 no cal fer res
movlw 7 ; Si són iguals posa blanc
movwf temp ; El guardem a la variable temporal
goto fiCur ; Ja està el cursor a punt
noCur: ; Si no toca mostrar el cursor o estem en una casella normal
movf INDF,w ; Agafem el color de la casella actual
movwf temp ; El guardem a la variable temporal
fiCur: ; Ja estem del cursor
; Ara anem a preparar els colors de la casella actual
; i els anirem afegint a la filera
; Primer el vermell
movf temp,w ; Agafem la casella actual
andlw 00000001B ; Serà 1 si hi ha vermell
movwf mascara ; Ho posa com a màscara per al vermell
; Anem a posar aquest 1 a la columna que li toca
movf xact,w ; Agafem la x actual
btfsc ZERO ; Mirem si és zero
goto xnulR ; Si és zero no cal fer res, ja està a lloc
movwf Compt ; Hem de rodar els bits x posicions
giraR:
bcf CARRY ; Volem entrar zeros
rlf mascara,f ; Rodem a l'esquerra i entrem el zero
decfsz Compt,f ; Decrementa temp
goto giraR ; Si Comp no és zero, repeteix el bucle
xnulR: ; Ja tenim l'1 posat a la columna per a cada color
movf mascara,w ; Agafem la màscara del vermell
iorwf Sortida,f ; L'aplica al color vermell
; Ara al verd
movf temp,w ; Agafem la casella actual
andlw 00000010B ; Serà 10 si hi ha verd
movwf mascara ; Ho posa com a màscara per al verd
bcf CARRY ; Volem entrar zeros
rrf mascara,f ; Posem l'1 a la dreta
; Anem a posar aquest 1 a la columna que li toca
movf xact,w ; Agafem la x actual
btfsc ZERO ; Mirem si és zero
goto xnulG ; Si és zero no cal fer res, ja està a lloc
movwf Compt ; Hem de rodar els bits x posicions
giraG:
bcf CARRY ; Volem entrar zeros
rlf mascara,f ; Rodem a l'esquerra i entrem el zero
decfsz Compt,f ; Decrementa temp
goto giraG ; Si Comp no és zero, repeteix el bucle
xnulG: ; Ja tenim l'1 posat a la columna per a cada color
movf mascara,w ; Agafem la màscara del verd
iorwf Sortida+2,f ; L'aplica al color verd
; Ara al blau
movf temp,w ; Agafem la casella actual
andlw 00000100B ; Serà 100 si hi ha blau
movwf mascara ; Ho posa com a màscara per al blau
bcf CARRY ; Volem entrar zeros
rrf mascara,f ; Movem l'1 a la dreta
bcf CARRY ; Volem entrar zeros
rrf mascara,f ; Posem l'1 a la dreta
; Anem a posar aquest 1 a la columna que li toca
movf xact,w ; Agafem la x actual
btfsc ZERO ; Mirem si és zero
goto xnulB ; Si és zero no cal fer res, ja està a lloc
movwf Compt ; Hem de rodar els bits x posicions
giraB:
bcf CARRY ; Volem entrar zeros
rlf mascara,f ; Rodem a l'esquerra i entrem el zero
decfsz Compt,f ; Decrementa temp
goto giraB ; Si Comp no és zero, repeteix el bucle
xnulB: ; Ja tenim l'1 posat a la columna per a cada color
movf mascara,w ; Agafem la màscara del blau
iorwf Sortida+4,f ; L'aplica al color blau
; Hem preparat la casella actual, passem a la següent
incf FSR,f ; Passem a la casella següent
incf xact,f ; Passem a la casella següent
decfsz compX,f ; Decrementa compX
goto bucleX ; Si Compt no és zero, encara no hem acabat la filera
; Hem acabat la filera, anem a enviar-la
incf yact,w ; A la matriu se li envien les fileres numerades de l'1 al 8
movwf Sortida+1 ; Filera per al vermell
movwf Sortida+3 ; Filera per al verd
movwf Sortida+5 ; Filera per al blau
call Envia3max ; Ho envia al MAX7221
; Hem enviat la filera, passem a la següent
incf yact,f ; Passem a la filera següent
decfsz compY,f ; Decrementa compY
goto bucleY ; Si Compt no és zero, encara no hem acabat d'enviar la matriu
; Després d'enviar la matriu fem un petit retard
movlw 1 ; Retard de 0,771 ms
call Retms
; Un cop enviada la matriu, gestionem el cursor
decfsz compt_int,f ; Decrementa el comptador per a la intermitència
goto Bucle ; Si no és zero, torna a l'inici del bucle
movlw cic_int ; Nombre de cicles per a la intermitència
movwf compt_int
movlw 00000001B ; Valor 1
xorwf cur_on,f ; Inverteix cur_on
goto Bucle ; Torna a repetir
;
; Posa a zero els bytes de la matriu figura
;
PosaZero:
movlw 64 ; Número de bytes que cal posar a zero
movwf Compt ; Variable per comptar els bytes
movlw figura ; Agafem l'adreça de la primera posició del vector
movwf FSR ; La posem com a punter d'adreçament indirecte
BucleZero:
clrf INDF ; Posa a zero la posició actual
incf FSR,f ; Incrementa el punter
decfsz Compt,f ; Decrementa Compt
goto BucleZero ; Si Compt no és zero, repeteix el bucle
return
;
; Funció que llegeix els polsadors
;
Llegir:
clrf Polsador ; Si aquest valor no es canvia és que no hi ha cap polsador premut
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon
nop ; espera un microsegon, en total 5
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
; Comparació P1
movlw 220 ; Límit superior de P1
subwf ADRESH,w ; W = ADRESH - W
btfsc CARRY ; C = 1 si ADRESH >= W
goto NoEsP1 ; ADRESH >= W
movlw 200 ; Límit inferior de P1
subwf ADRESH,w ; W = ADRESH - W
btfss CARRY ; C = 1 si ADRESH >= W
goto NoEsP1 ; ADRESH < W
movlw 00000001B ; Polsador P1
movwf Polsador ; Ho copia a Polsador
goto NoEsP5
NoEsP1: ; Comparació P2
movlw 194 ; Límit superior de P2
subwf ADRESH,w ; W = ADRESH - W
btfsc CARRY ; C = 1 si ADRESH >= W
goto NoEsP2 ; ADRESH >= W
movlw 174 ; Límit inferior de P2
subwf ADRESH,w ; W = ADRESH - W
btfss CARRY ; C = 1 si ADRESH >= W
goto NoEsP2 ; ADRESH < W
movlw 00000010B ; Polsador P2
movwf Polsador ; Ho copia a Polsador
goto NoEsP5
NoEsP2: ; Comparació P3
movlw 163 ; Límit superior de P3
subwf ADRESH,w ; W = ADRESH - W
btfsc CARRY ; C = 1 si ADRESH >= W
goto NoEsP3 ; ADRESH >= W
movlw 143 ; Límit inferior de P3
subwf ADRESH,w ; W = ADRESH - W
btfss CARRY ; C = 1 si ADRESH >= W
goto NoEsP3 ; ADRESH < W
movlw 00000100B ; Polsador P3
movwf Polsador ; Ho copia a Polsador
goto NoEsP5
NoEsP3: ; Comparació P4
movlw 90 ; Límit superior de P4
subwf ADRESH,w ; W = ADRESH - W
btfsc CARRY ; C = 1 si ADRESH >= W
goto NoEsP4 ; ADRESH >= W
movlw 70 ; Límit inferior de P4
subwf ADRESH,w ; W = ADRESH - W
btfss CARRY ; C = 1 si ADRESH >= W
goto NoEsP4 ; ADRESH < W
movlw 00001000B ; Polsador P4
movwf Polsador ; Ho copia a Polsador
goto NoEsP5
NoEsP4: ; Comparació P5
movlw 55 ; Límit superior de P5
subwf ADRESH,w ; W = ADRESH - W
btfsc CARRY ; C = 1 si ADRESH >= W
goto NoEsP5 ; ADRESH >= W
movlw 35 ; Límit inferior de P5
subwf ADRESH,w ; W = ADRESH - W
btfss CARRY ; C = 1 si ADRESH >= W
goto NoEsP5 ; ADRESH < W
movlw 00010000B ; Polsador P5
movwf Polsador ; Ho copia a Polsador
NoEsP5:
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,771 W ms
;
Retms:
movwf Retard2
Buclems:
decfsz Retard1,f
goto Buclems
decfsz Retard2,f
goto Buclems
return
END main

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