Programació en pic-as del PIC 16F690

Referència Trucs Perifèrics   Recursos CITCEA
Tutorial Exemples Projectes   Inici

Exemple ML - Mostrem uns dibuixos a la matriu de LED

En l'exemple següent mostrarem un parell de dibuixos a la matriu de LED. El programa és llarg però senzill. En la part d'inicialització configura el microcontrolador. En el bucle simplement va alternant els dos patrons de les figures següents deixant un temps entre canvi i canvi per tal que els patrons es puguin veure suficientment bé.

Sentit prohibit           Fletxa verda amunt

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
Actiu EQU 0x29  ; Variable que diu quin color està actiu
                ; Actiu = 0   Apagat
                ; Actiu = 1   Vermell
                ; Actiu = 2   Verd
                ; Actiu = 3   Blau
Retard1 EQU 0x2A  ; Variables per als cicles de retard
Retard2 EQU 0x2B  
Retard3 EQU 0x2C  
; 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 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
  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:
  ; Matriu 1
  movlw 0x01  ; Filera 1
  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 00111100B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x02  ; Filera 2
  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 01111110B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x03  ; Filera 3
  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 11111111B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x04  ; Filera 4
  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 11111111B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 01111110B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 01111110B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x05  ; Filera 5
  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 11111111B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 01111110B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 01111110B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x06  ; Filera 6
  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 11111111B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x07  ; Filera 7
  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 01111110B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x08  ; Filera 8
  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 00111100B  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  ; Fi de la matriu 1
  movlw 7  ; Retard d'1,4 segons que realment són 1,6
  call Retard
  ; Matriu 2
  movlw 0x01  ; Filera 1
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00011000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x02  ; Filera 2
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00111100B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x03  ; Filera 3
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 01111110B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x04  ; Filera 4
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 11111111B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x05  ; Filera 5
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00011000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x06  ; Filera 6
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00011000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x07  ; Filera 7
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00011000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  movlw 0x08  	; Filera 8
  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  ; Vermells				
  movwf Sortida  ; Ho prepara per enviar-ho
  movlw 00011000B  ; Verds
  movwf Sortida+2  ; Ho prepara per enviar-ho
  movlw 00000000B  ; Blaus
  movwf Sortida+4  ; Ho prepara per enviar-ho
  call Envia3max  ; Ho envia al MAX7221
  ; Fi de la matriu 2
  movlw 7  ; Retard d'1,4 segons que realment són 1,6
  call Retard
  goto Bucle  ; Torna a repetir
;
; 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
END main

El següent programa fa el mateix que el primer que hem vist però guardant els dibuixos amb la directiva IRP i recuperant-los modificant el comptador de 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 per al salt
AdreL EQU 0x2B  ; Adreça per al salt
Actiu EQU 0x2C  ; Variable que diu quin color està actiu
                ; Actiu = 0		Apagat
                ; Actiu = 1		Vermell
                ; Actiu = 2		Verd
                ; Actiu = 3		Blau
Retard1 EQU 0x2D  ; Variables per als cicles de retard
Retard2 EQU 0x2E
Retard3 EQU 0x2F
; 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 high Matriu1  ; Carrega la part alta de l'adreça de la taula
  movwf AdreH  ; Ho guarda per posar-ho a PCLATH
  movlw low Matriu1  ; Carrega la part baixa de l'adreça de la taula
  movwf AdreL  ; Ho guarda per posar-ho a PCL
  call EnviaMat
  movlw 7  ; Retard d'1,4 segons que realment són 1,6
  call Retard
  movlw high Matriu2  ; Carrega la part alta de l'adreça de la taula
  movwf AdreH  ; Ho guarda per posar-ho a PCLATH
  movlw low Matriu2  ; Carrega la part baixa de l'adreça de la taula
  movwf AdreL  ; Ho guarda per posar-ho a PCL
  call EnviaMat
  movlw 7  ; Retard d'1,4 segons que realment són 1,6
  call Retard
  goto Bucle  ; Torna a repetir
;
; Es prepara per llegir la taula amb les imatges
;
Llegir:
  bcf	T0IE	; Desactiva les interrupcions momentàniament
  call	Llegeix
  bsf	T0IE	; Reactiva les interrupcions a l'acabar
  return
;
; Llegeix la taula amb les imatges
;
Llegeix:
  movf	AdreH,w		; Agafa l'adreça de destí
  movwf	PCLATH		; Modifica el valor de PCLATH
  movf	AdreL,w		; Agafa l'adreça de destí
  movwf	PCL		; Modifica el valor de PCL (i, per tant, també el de PCH)
Matriu1:  ; Cada línia són vermell, verd i blau per a dues fileres
IRP valors, 00111100B, 00000000B, 00000000B, 01111110B, 00000000B, 00000000B
  retlw valors
ENDM
IRP valors, 11111111B, 00000000B, 00000000B, 11111111B, 01111110B, 01111110B
  retlw valors
ENDM
IRP valors, 11111111B, 01111110B, 01111110B, 11111111B, 00000000B, 00000000B
  retlw valors
ENDM
IRP valors, 01111110B, 00000000B, 00000000B, 00111100B, 00000000B, 00000000B
  retlw valors
ENDM
Matriu2:
IRP valors, 00000000B, 00011000B, 00000000B, 00000000B, 00111100B, 00000000B
  retlw valors
ENDM
IRP valors, 00000000B, 01111110B, 00000000B, 00000000B, 11111111B, 00000000B
  retlw valors
ENDM
IRP valors, 00000000B, 00011000B, 00000000B, 00000000B, 00011000B, 00000000B
  retlw valors
ENDM
IRP valors, 00000000B, 00011000B, 00000000B, 00000000B, 00011000B, 00000000B
  retlw valors
ENDM
;
; Envia les dades d'una de les matrius als MAX7221
;
EnviaMat:
  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
  incf AdreL,f  ; Incrementa el punter	
  btfsc ZERO  ; S'ha activat Z?
  incf AdreH,f  ; Si s'ha activat, incrementem AdreH
  call Llegir  ; Llegeix la filera
  movwf Sortida+2  ; Verds
  incf AdreL,f  ; Incrementa el punter	
  btfsc ZERO  ; S'ha activat Z?
  incf AdreH,f  ; Si s'ha activat, incrementem AdreH
  call Llegir  ; Llegeix la filera
  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
END main

I aquesta tercera versió fa el mateix però guardant els dibuixos a la memòria de 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
Actiu EQU 0x2C  ; Variable que diu quin color està actiu
                ; Actiu = 0		Apagat
                ; Actiu = 1		Vermell
                ; Actiu = 2		Verd
                ; Actiu = 3		Blau
Retard1 EQU 0x2D  ; Variables per als cicles de retard
Retard2 EQU 0x2E
Retard3 EQU 0x2F
; 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 high Matriu1  ; Carrega la part alta de l'adreça de la taula
  movwf AdreH  ; Ho guarda per posar-ho a PCLATH
  movlw low Matriu1  ; Carrega la part baixa de l'adreça de la taula
  movwf AdreL  ; Ho guarda per posar-ho a PCL
  call EnviaMat
  movlw 7  ; Retard
  call Retard
  movlw high Matriu2  ; Carrega la part alta de l'adreça de la taula
  movwf AdreH  ; Ho guarda per posar-ho a PCLATH
  movlw low Matriu2  ; Carrega la part baixa de l'adreça de la taula
  movwf AdreL  ; Ho guarda per posar-ho a PCL
  call EnviaMat
  movlw 7  ; Retard
  call Retard
  goto Bucle  ; Torna a repetir
;
; Envia les dades d'una de les matrius als MAX7221
;
EnviaMat:
  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
  incf AdreL,f  ; Incrementa el punter	
  btfsc ZERO  ; S'ha activat Z?
  incf AdreH,f  ; Si s'ha activat, incrementem AdreH
  call Llegir  ; Llegeix la filera
  movwf Sortida+2  ; Verds
  incf AdreL,f  ; Incrementa el punter	
  btfsc ZERO  ; S'ha activat Z?
  incf AdreH,f  ; Si s'ha activat, incrementem AdreH
  call Llegir  ; Llegeix la filera
  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
Matriu1:  ; Cada línia són vermell, verd i blau per a dues fileres
  DB  00111100B, 00000000B, 00000000B, 01111110B, 00000000B, 00000000B
  DB  11111111B, 00000000B, 00000000B, 11111111B, 01111110B, 01111110B
  DB  11111111B, 01111110B, 01111110B, 11111111B, 00000000B, 00000000B
  DB  01111110B, 00000000B, 00000000B, 00111100B, 00000000B, 00000000B
Matriu2:
  DB  00000000B, 00011000B, 00000000B, 00000000B, 00111100B, 00000000B
  DB  00000000B, 01111110B, 00000000B, 00000000B, 11111111B, 00000000B
  DB  00000000B, 00011000B, 00000000B, 00000000B, 00011000B, 00000000B
  DB  00000000B, 00011000B, 00000000B, 00000000B, 00011000B, 00000000B
END main

 

 

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