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.
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF) #define cic_int .35 ; Nombre de cicles per a la intermitència
cblock 0x20 Port ; Bits a enviar al port B Sortida:6 ; Valors a enviar al MAX7221 (48 bits) Compta ; Variable per comptar els bits a Envia_max Compt ; Variable per comptar compY ; Comptador per enviar fileres compX ; Comptador per enviar columnes Filera ; Variable per comptar fileres Actiu ; Variable que diu quin color està actiu ; Actiu = 0 Apagat ; Actiu = 1 Vermell ; Actiu = 2 Verd ; Actiu = 3 Blau Polsador ; Variable que conté un bit per a cada polsador per saber si està premut x ; Coordenada X del cursor (0 a 7) ; X = 0 és la columna de la dreta y ; Coordenada Y del cursor (0 a 7) yact ; Filera que estem enviant xact ; Casella que estem enviant mirar ; Espera que es deixi anar el polsador temp ; Variable temporal compt_int ; Comptador de cicles per a la intermitència cur_on ; Controla l'estat del cursor color ; Color seleccionat mascara ; Màscara per preparar els colors Retard1 ; Variables per als cicles de retard Retard2 endc cblock 0x70 ; Zona de memòria de dades que no depèn del banc triat W_Copia ; Guardarà el contingut de W durant la interrupció ST_Copia ; Guardarà STATUS durant la interrupció endc cblock 0xA0 ; Zona de memòria de dades del banc 1 figura:.64 ; Aquí guardarem el dibuix (8 x 8 posicions) endc
org 0 goto Inici ; Saltem al lloc on hi ha el programa principal nop ; Zona de memòria de programa que no utilitzem nop nop
Interrup 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 INTCON,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 INTCON,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 b'00000011' ; Descarta els bits que no serveixen andwf Actiu,f btfsc STATUS,Z goto NoZero ; Si Actiu val 0 no ho canvia decf Actiu,f ; Passem a activar un altre color btfss STATUS,Z ; 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 b'00000011' ; Descarta els bits que no serveixen andwf Actiu,f btfsc STATUS,Z ; Salta si el resultat no és zero goto Apagat ; Si està apagat ho desactiva tot movlw .1 xorwf Actiu,w btfsc STATUS,Z goto Vermell ; Si val 1, activem el vermell movlw .2 xorwf Actiu,w btfsc STATUS,Z 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 STATUS,RP0 ; Tria el banc 1 movlw b'10000101' ; 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 b'00010000' movwf ADCON1 ; Posa el conversor a 1/8 de la freqüència bcf STATUS,RP0 bsf STATUS,RP1 ; Tria el banc 2 movlw b'00000101' movwf ANSEL ; Configura AN0 i AN2 com entrada analògica bcf STATUS,RP0 bcf STATUS,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 b'00001001' 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 b'10100000' ; 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 STATUS,Z ; Si és zero no s'han de mirar goto NoMirar ; Anem a veure si ja s'ha deixat anar movf Polsador,w xorlw b'00000001' ; Mirem si s'ha premut el polsador 1 btfss STATUS,Z ; Si és l'1, salta goto NoPol1 ; No és l'1 ; S'ha premut el polsador 1 incf x,f ; Incrementem x del cursor movlw b'00000111' ; Valor 7 andwf x,f ; Limitem x entre 0 i 7 goto Zmirar ; Ja estem del polsador 1 NoPol1 movf Polsador,w xorlw b'00000010' ; Mirem si s'ha premut el polsador 2 btfss STATUS,Z ; Si és el 2, salta goto NoPol2 ; No és el 2 ; S'ha premut el polsador 2 incf y,f ; Incrementem y del cursor movlw b'00000111' ; Valor 7 andwf y,f ; Limitem x entre 0 i 7 goto Zmirar ; Ja estem del polsador 2 NoPol2 movf Polsador,w xorlw b'00000100' ; Mirem si s'ha premut el polsador 3 btfss STATUS,Z ; Si és el 3, salta goto NoPol3 ; 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 STATUS,C ; 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 NoPol3 movf Polsador,w xorlw b'00001000' ; Mirem si s'ha premut el polsador 4 btfss STATUS,Z ; Si és el 4, salta goto NoPol4 ; No és el 4 ; S'ha premut el polsador 4 incf color,f ; Passem al color següent movlw b'00000111' ; Valor 7 xorwf color,w ; Mirem si és 7 btfss STATUS,Z ; 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 NoPol4 movf Polsador,w xorlw b'00010000' ; Mirem si s'ha premut el polsador 5 btfss STATUS,Z ; Si és el 5, salta goto NoPol5 ; 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 NoPol5 goto Matriu ; Envia la figura actual a la matriu NoMirar movf Polsador,w ; Agafem la lectura dels polsadors btfss STATUS,Z ; 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 STATUS,Z ; 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 STATUS,Z ; 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 STATUS,Z ; 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 STATUS,Z ; 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 b'00000001' ; 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 STATUS,Z ; 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 STATUS,C ; 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 b'00000010' ; Serà 10 si hi ha verd movwf mascara ; Ho posa com a màscara per al verd bcf STATUS,C ; 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 STATUS,Z ; 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 STATUS,C ; 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 b'00000100' ; Serà 100 si hi ha blau movwf mascara ; Ho posa com a màscara per al blau bcf STATUS,C ; Volem entrar zeros rrf mascara,f ; Movem l'1 a la dreta bcf STATUS,C ; 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 STATUS,Z ; 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 STATUS,C ; 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 b'00000001' ; 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 ADCON0,GO ; Inicia la conversió btfsc ADCON0,GO ; 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 STATUS,C ; C = 1 si ADRESH >= W goto NoP1 ; ADRESH >= W movlw .200 ; Límit inferior de P1 subwf ADRESH,w ; W = ADRESH - W btfss STATUS,C ; C = 1 si ADRESH >= W goto NoP1 ; ADRESH < W movlw b'00000001' ; Polsador P1 movwf Polsador ; Ho copia a Polsador goto NoP5 NoP1 ; Comparació P2 movlw .194 ; Límit superior de P2 subwf ADRESH,w ; W = ADRESH - W btfsc STATUS,C ; C = 1 si ADRESH >= W goto NoP2 ; ADRESH >= W movlw .174 ; Límit inferior de P2 subwf ADRESH,w ; W = ADRESH - W btfss STATUS,C ; C = 1 si ADRESH >= W goto NoP2 ; ADRESH < W movlw b'00000010' ; Polsador P2 movwf Polsador ; Ho copia a Polsador goto NoP5 NoP2 ; Comparació P3 movlw .163 ; Límit superior de P3 subwf ADRESH,w ; W = ADRESH - W btfsc STATUS,C ; C = 1 si ADRESH >= W goto NoP3 ; ADRESH >= W movlw .143 ; Límit inferior de P3 subwf ADRESH,w ; W = ADRESH - W btfss STATUS,C ; C = 1 si ADRESH >= W goto NoP3 ; ADRESH < W movlw b'00000100' ; Polsador P3 movwf Polsador ; Ho copia a Polsador goto NoP5 NoP3 ; Comparació P4 movlw .90 ; Límit superior de P4 subwf ADRESH,w ; W = ADRESH - W btfsc STATUS,C ; C = 1 si ADRESH >= W goto NoP4 ; ADRESH >= W movlw .70 ; Límit inferior de P4 subwf ADRESH,w ; W = ADRESH - W btfss STATUS,C ; C = 1 si ADRESH >= W goto NoP4 ; ADRESH < W movlw b'00001000' ; Polsador P4 movwf Polsador ; Ho copia a Polsador goto NoP5 NoP4 ; Comparació P5 movlw .55 ; Límit superior de P5 subwf ADRESH,w ; W = ADRESH - W btfsc STATUS,C ; C = 1 si ADRESH >= W goto NoP5 ; ADRESH >= W movlw .35 ; Límit inferior de P5 subwf ADRESH,w ; W = ADRESH - W btfss STATUS,C ; C = 1 si ADRESH >= W goto NoP5 ; ADRESH < W movlw b'00010000' ; Polsador P5 movwf Polsador ; Ho copia a Polsador NoP5 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 b'00000000' ; 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 INTCON,T0IE ; Desactiva les interrupcions momentàniament call Envia_max bsf INTCON,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 STATUS,C ; 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

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