El programa del grup 2 té present la posició del potenciòmetre per escollir entre dos modes de funcionament. En el primer mode, els LED grocs van mostrant una seqüència. Quan es prem el polsador presenta el número que ha triat aleatòriament mentre sona una melodia. Passat un temps, torna la seqüència i espera que es premi altre cop el polsador.
El segon mode és per al joc del parxís i hi intervenen els LED de la placa PICkit 2. Cada LED indica el torn d'un jugador i després de la tirada passa el torn al jugador següent. El funcionament, pel que fa a la resta, és igual al de l'altre mode. El sistema té en compte que si surt un sis cal tornar a tirar (per tant, no avança torn) i que si surten tres sisos seguits es perd el torn.
El programa d'aquest grup és el següent:
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
cblock 0x20 Visualit ; Variable on guardarem el resultat de TMR1 adequat Visualit2 ; Utilitzada en els LED vermells Visualit3 ; Utilitzada en el valor del potenciomentre Conta6 ; Conta les vegades seguides que treu el numero 6 Retard1 ; Definim una variable de comptatge 2 Retard2 ; Definim una variable de comptatge 1 ValPR2 ; Aquí hi guardarem el valor de PR2 ValCCPR1L ; Aquí hi guardarem el valor de CCPR1L ValDC1B ; Aquí hi guardarem el valor de DC1B ValCCP1CON ; Aquí hi guardarem el valor de CCP1CON endc
org 0 Inici bsf STATUS,RP0 ; Tria el banc 1 movlw b'00100000' ; Definim com volem les E/S del port C movwf TRISC ; RC5 (sortida del PWM) com a entrada clrf TRISC ; Posa tots els bits del port C com a sortida clrf TRISB ; Posa tots els bits del port B com a sortida movlw 0xFF ; Posa l'acumulador a FFh (tot uns) movwf TRISA ; Posa tots els bits del port A com a entrada movlw b'10000000' ; Configuració de Timer0 ; Com a temporitzador basat en rellotge ; 000 - Factor d'escala de 1/2 ; I resistències de pull-up desactivades (valor per defecte) movwf OPTION_REG ; Ho guarda al registre de configuració del Timer0 movlw b'00010000' ; Posa el conversor a 1/8 de la freqüència movwf ADCON1 ; Copia W a la configuració del conversor A/D bcf STATUS,RP0 bsf STATUS,RP1 ; Tria el banc 2 movlw 0xFF ; Posa l'acumulador a FFh (tot uns) movwf ANSEL ; Configura AN0-AN7 com entrades analògiques bcf STATUS,RP0 bcf STATUS,RP1 ; Tria el banc 0 movlw b'00000001' ; activa el conversor A/D connectat a AN0 movwf ADCON0 ; amb el resultat justificat per l'esquerra movlw b'00000001' ; Activa el bit 0 al registre W movwf Visualit2 ; Copia el valor de W a la variable Visualit clrf PORTB ; Esborra PORTB clrf PORTC ; Esborra PORTC clrf Visualit ; Esborra la variable Visualit clrw ; Esborra l'acumulador (posa a zero) movlw b'00000001' ; Configuració de Timer1 ; 000 - Factor d'escala de 1/1 movwf T1CON ; Ho guarda al registre de configuració del Timer1 clrf PORTC ; Desactiva les sortides del port C movlw b'00001100' ; Configura el PWM, bits P1M (bits 7-6) a 00 mode senzill ; DC1B = 00 (bits 5-4) els dos bits de menys pes són 0 ; CCP1M = 11xx en mode senzill els bit 0 i 1 no afecten movwf ValCCP1CON ; Ho guarda per fer-ho servir més tard movwf CCP1CON ; Ho posa com a configuració del PWM movlw b'00000001' ; Configura el Timer 2 ; bits T2KCPS (bits 1-0) a 01 prescalat de 4 ; bit 2 (TMR2ON) a 0, Timer aturat ; Postscaler TOUTPS (bits 6-3) no afecten al PWM movwf T2CON ; Ho posa com a configuració del Timer 2 movlw b'00000000' movwf Conta6 Animacio btfss PORTA,3 ; Comprova l'estat del polsador. ; Si activat (no premut), canvi de fase d'animació goto Llegir ; Direccionament a bucle on calcula el número clrf PORTB ; Abans de canviar apaga els LED grocs call Canvic ; Direccionament a bucle on es fa compatible l'encessa ; dels LED grocs i vermells alhora. movlw b'00100000' movwf PORTB ; Nova posició dels LED groc durant l'animació call RetardAnimacio ; Retard per mantenir encesa la nova fase un temps determinat btfss PORTA,3 ; Repetició cíclica del mateix procediment alternant fases en l'encesa goto Llegir movlw b'11000000' movwf PORTB call RetardAnimacio clrf PORTB call Canvic btfss PORTA,3 goto Llegir movlw b'11000000' movwf PORTC call RetardAnimacio clrf PORTB call Canvic btfss PORTA,3 goto Llegir movlw b'00010000' movwf PORTB call RetardAnimacio clrf PORTB call Canvic btfss PORTA,3 goto Llegir movlw b'00010000' movwf PORTC call RetardAnimacio clrf PORTB call Canvic btfss PORTA,3 ; Comprova abans de tornar a l'inici de l'animació l'estat del polsador goto Llegir goto Animacio AnimacioSenseVermells ; Mateix bucle que l'anterior però ; sense la compatibilitat de LED vermells i grocs btfss PORTA,3 goto Llegir clrf PORTB clrf PORTC movlw b'00100000' movwf PORTB call RetardAnimacio btfss PORTA,3 goto Llegir movlw b'11000000' movwf PORTB call RetardAnimacio clrf PORTB clrf PORTC btfss PORTA,3 goto Llegir movlw b'11000000' movwf PORTC call RetardAnimacio clrf PORTB clrf PORTC btfss PORTA,3 goto Llegir movlw b'00010000' movwf PORTB call RetardAnimacio clrf PORTB clrf PORTC btfss PORTA,3 goto Llegir movlw b'00010000' movwf PORTC call RetardAnimacio clrf PORTB clrf PORTC btfss PORTA,3 goto Llegir goto AnimacioSenseVermells Llegir ; Bucle en el que es guarda el número calculat a la variable Visualit clrf Visualit movf TMR1L,w andlw b'00000111' btfsc STATUS,Z ; Si Z es 0 salta i no cal tornar a calcular un altre número goto Llegir movwf Visualit xorlw b'00000111' ; Compara el 7 amb acumulador activara Z si son iguals Z=1 btfsc STATUS,Z ; Si Z es 0 salta i no cal tornar a calcular un altre número goto Llegir Comparar call Potenciometre btfsc Visualit3,3 ; si es 0 el potenciometre, no reinicialitzarà ; els LED vermells a la posició inicial goto Comparars movlw b'00000001' ; Activa el bit 3 al registre W movwf Visualit2 Comparars ; funció en la qual es redirecciona a bucles diferents segons resultat movf Visualit,w xorlw b'00000001' btfsc STATUS,Z goto Bucle1 movf Visualit,w xorlw b'00000010' btfsc STATUS,Z goto Bucle2 movf Visualit,w xorlw b'00000011' btfsc STATUS,Z goto Bucle3 movf Visualit,w xorlw b'00000100' btfsc STATUS,Z goto Bucle4 movf Visualit,w xorlw b'00000101' btfsc STATUS,Z goto Bucle5 movf Visualit,w xorlw b'00000110' btfsc STATUS,Z goto Bucle6 Bucle1 clrf Conta6 ; Esborra el comptador de sisos. Ja s'ha obtingut un valor diferent clrf PORTB ; Neteja el PORTB (apaga els LED) clrf PORTC ; Neteja el PORTC call Musica ; Crida la funció que realitza la música abans de mostrar el número movlw b'00100000' movwf PORTB ; Encèn el LED central (Corresponent al 1) call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Potenciometre ; Permet obtenir l'estat del potenciòmetre btfsc Visualit3,3 ; si es 0 el potenciometre, no fara els vermells call Vermells ; Rota la posició dels LED vermells (canvi de torn) btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Animació compatible amb el torn goto Animacio goto AnimacioSenseVermells Bucle2 clrf Conta6 ; Esborra el comptador de sisos. Ja s'ha obtingut un valor diferent clrf PORTB ; Neteja el PORTB (apaga els LED) clrf PORTC ; Neteja el PORTC call Musica ; Crida la funció que realitza la música abans de mostrar el número movlw b'11000000' ; Encèn els LED corresponents al 2 (Una diagonal) movwf PORTB call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Retard12 call Potenciometre ; Permet obtenir l'estat del potenciòmetre btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Vermells call Vermells ; Rota la posició dels LED vermells (canvi de torn) btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Animació compatible amb el torn goto Animacio goto AnimacioSenseVermells Bucle3 clrf Conta6 ; Esborra el comptador de sisos. Ja s'ha obtingut un valor diferent clrf PORTB ; Neteja el PORTB (apaga els LED) clrf PORTC ; Neteja el PORTC call Musica ; Crida la funció que realitza la música abans de mostrar el número call Retard3 ; Cada Retard6 dura un segon call Retard3 call Retard3 call Retard3 call Retard3 call Retard3 call Potenciometre ; Permet obtenir l'estat del potenciòmetre btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Vermells call Vermells ; Rota la posició dels LED vermells (canvi de torn) btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Animació compatible amb el torn goto Animacio goto AnimacioSenseVermells Bucle4 clrf Conta6 ; Esborra el comptador de sisos. Ja s'ha obtingut un valor diferent clrf PORTB ; Neteja el PORTB (apaga els LED) clrf PORTC ; Neteja el PORTC call Musica ; Crida la funció que realitza la música abans de mostrar el número call Retard4 call Retard4 call Retard4 call Retard4 call Retard4 call Retard4 call Potenciometre ; Permet obtenir l'estat del potenciòmetre btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Vermells call Vermells ; Rota la posició dels LED vermells (canvi de torn) btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Animació compatible amb el torn goto Animacio goto AnimacioSenseVermells Bucle5 clrf Conta6 ; Esborra el comptador de sisos. Ja s'ha obtingut un valor diferent clrf PORTB ; Neteja el PORTB (apaga els LED) clrf PORTC ; Neteja el PORTC call Musica ; Crida la funció que realitza la música abans de mostrar el número call Retard5 call Retard5 call Retard5 call Retard5 call Potenciometre ; Permet obtenir l'estat del potenciòmetre btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Vermells call Vermells ; Rota la posició dels LED vermells (canvi de torn) btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Animació compatible amb el torn goto Animacio goto AnimacioSenseVermells Bucle6 clrf PORTB ; Neteja el PORTB (apaga els LED) clrf PORTC ; Neteja el PORTC call Musica ; Crida la funció que realitza la música abans de mostrar el número call Retard6 call Retard6 call Retard6 call Retard6 incf Conta6, f ; Cada cop que s'obté un sis aquesta variable aumenta 1. ; En el moment que s'obté un altre número es fa zero movlw b'00000011' xorwf Conta6, w ; Si la variable Conta6 arriba a 3, es perd el torn btfsc STATUS, Z ; Comprova l'estat del bit Z,si és 0 ; vol dir que Conta6 ha arribat a 3, cal perdre el torn call Vermellssisens ; funció de pèrdua del torn per la tirada de 3 sisos seguits btfsc Visualit3,3 ; Si és 0 el potenciòmetre, no farà Animació compatible amb el torn goto Animacio goto AnimacioSenseVermells
RetardAnimacio btfss PORTA,3 ; Comprova l'estat del polsador per calcular número o continuar animació goto Llegir decfsz Retard1,f ; Decrementa la variable 1 ; si dona zero, no es fa la instrucció següent goto RetardAnimacio ; Salta, excepte si el resultat ha estat zero decfsz Retard2,f ; Decrementa la variable 2 goto RetardAnimacio ; Salta, excepte si el resultat ha estat zero return Retard12 ; funció pel retard específic dels números 1 i 2 decfsz Retard1,f ; Decrementa la variable 1 ; si dona zero, no es fa la instrucció següent goto Retard12 ; Salta, excepte si el resultat ha estat zero decfsz Retard2,f ; Decrementa la variable 2 goto Retard12 ; Salta, excepte si el resultat ha estat zero return Retard3 ; funció pel retard específic del número 3 movlw b'11000000' ; Alternança de posicions dels LED grocs ; per aconseguir la diagonal del tres movwf PORTB nop nop nop nop movlw b'00100000' movwf PORTB decfsz Retard1,f ; Decrementa la variable 1 goto Retard3 ; Salta, excepte si el resultat ha estat zero decfsz Retard2,f ; Decrementa la variable 2 goto Retard3 ; Salta, excepte si el resultat ha estat zero return Retard4 ; funció pel retard específic del número 4 movlw b'11000000' ; Alternança de posicions dels LED grocs pel 4 movwf PORTB nop nop nop nop movlw b'00010000' movwf PORTB decfsz Retard1,f ; Decrementa la variable 1 goto Retard4 ; Salta, excepte si el resultat ha estat zero decfsz Retard2,f ; Decrementa la variable 2 goto Retard4 ; Salta, excepte si el resultat ha estat zero return Retard5 ; funció pel retard específic del número 5 movlw b'11000000' ; Alternança de posicions dels LED grocs pel 5 movwf PORTB nop nop nop nop movlw b'00010000' movwf PORTB nop nop nop nop movlw b'00100000' movwf PORTB decfsz Retard1,f ; Decrementa la variable 1 goto Retard5 ; Salta, excepte si el resultat ha estat zero decfsz Retard2,f ; Decrementa la variable 2 goto Retard5 ; Salta, excepte si el resultat ha estat zero return Retard6 ; Subutina pel retard específic del número 5 movlw b'00010000' ; Alternança de posicions dels LED grocs pel 4 movwf PORTB nop nop nop nop nop movlw b'11000000' movwf PORTB nop nop movlw b'00010000' movwf PORTC decfsz Retard1,f ; Decrementa la variable 1 ; si dona zero, no es fa la instrucció següent goto Retard6 ; Salta, excepte si el resultat ha estat zero decfsz Retard2,f ; Decrementa la variable 2 goto Retard6 ; Salta, excepte si el resultat ha estat zero return Musica movlw .238 ; Valor que correspon aproximadament a do3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .119 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada movlw .189 ; Valor que correspon aproximadament a mi3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .95 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .0 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada movlw .158 ; Valor que correspon aproximadament a sol3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .79 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada call RetPetit movlw .158 ; Valor que correspon aproximadament a sol3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .79 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada call RetM movlw .189 ; Valor que correspon aproximadament a mi3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .95 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .0 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada movlw .158 ; Valor que correspon aproximadament a sol3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .79 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada return TocaNota movf ValPR2,w ; Valor de PR2 per a la nota desitjada bsf STATUS,RP0 ; Tria el banc 1 bsf TRISC,5 ; Posem RC5 (sortida del PWM) com a entrada movwf PR2 ; Ho posem com a comparació al Timer 2 bcf STATUS,RP0 ; Tria el banc 0 movf ValCCP1CON,w ; Agafa la configuració de CCP1CON andlw b'11001111' ; Posa els bits que corresponen a DC1B a zero per precaució movwf ValCCP1CON ; I ho torna a guardar swapf ValDC1B,w ; Agafa el valor que ha d'anar a DC1B ; I el guarda, permutat, a W ; Els dos bits han de quedar a les posicions 4-5 andlw b'00110000' ; Posa els altres sis bits a zero per precaució iorwf ValCCP1CON,w ; I ho afegeix a CCP1CON movwf CCP1CON ; Ho posa com a configuració del PWM movf ValCCPR1L,w ; Valor de CCPR1L movwf CCPR1L ; Registre que ens dona l'amplada de tON bcf PIR1,TMR2IF ; Desactiva el bit d'interrupció del Timer 2 bsf T2CON,TMR2ON ; Activa el Timer 2 ; No convé engegar el PWM fins que el Timer 2 no ha fet un cicle btfss PIR1,TMR2IF ; Espera l'activació del bit d'interrupció del Timer 2 goto $-1 bsf STATUS,RP0 ; Tria el banc 1 bcf TRISC,5 ; Posem RC5 (sortida del PWM) com a sortida bcf STATUS,RP0 ; Tria el banc 0 call RetM ; Espera 0,2 s bsf STATUS,RP0 ; Tria el banc 1 bsf TRISC,5 ; Posem RC5 (sortida del PWM) com a entrada ; Fem silenci bcf STATUS,RP0 ; Tria el banc 0 return RetM ; Funció de retard de 0,2 s movlw b'11001000' movwf Retard2 RetM2 decfsz Retard1,f goto RetM2 decfsz Retard2,f goto RetM2 return RetPetit movlw b'01001000' movwf Retard2 goto RetM2 Canvic ; funció compatibilitat LED vermells i grocs movf Visualit,w andlw b'11110000' movwf Visualit movf Visualit2,w andlw b'00001111' movwf Visualit2 movf Visualit,w iorwf Visualit2,w movwf PORTC return Vermells ; funció de rotació de LED vermells cap a la dreta movf Visualit,w andlw b'11110000' movwf Visualit movf Visualit2,w ; Copia la variable Visualit sobre el registre W bcf STATUS,C ; posa a zero el bit d'arrossegament rrf Visualit2,f ; Fa rodar els bits cap a la dreta ; el bit d'arrossegament entra per l'esquerra ; i el bit de la dreta passa a l'arrossegament btfsc STATUS,C ; Comprova si s'ha activat l'arrossegament ; Si no s'ha activat, salta una instrucció bsf Visualit2,3 ; Si s'ha activat, torna a posar un 1 return Vermellssisens ; funció per la pèrdua de torn call Potenciometre clrf Conta6 ; Esborrem el valor de la variable Conta6 call MusicaPerdre ; Cridem a la música de derrota call Vermells ; Rotem els LED vermells una posició return Potenciometre ; funció per obtenir el valor del potenciòmetre 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 1 swapf ADRESH,w ; Permuta els nibbles dels bits superiors movwf Visualit3 return MusicaPerdre ; funció de la música de la derrota call Potenciometre btfss Visualit3,3 return bcf STATUS,RP0 bcf STATUS,RP1 ; Tria el banc 0 movlw b'00000011' ; Configura el Timer 2 ; bits T2KCPS (bits 1-0) a 11 prescalat de 16 ; bit 2 (TMR2ON) a 0, Timer aturat ; Postscaler TOUTPS (bits 6-3) no afecten al PWM movwf T2CON ; Ho posa com a configuració del Timer 2 movlw .200 ; Valor que correspon aproximadament a do3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .100 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada call RetM movlw .212 ; Valor que correspon aproximadament a mi3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .106 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada call RetM movlw .224 ; Valor que correspon aproximadament a sol3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .112 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP movwf ValDC1B ; Valor de DC1B call TocaNota ; Toca la nota configurada movlw .238 ; Valor que correspon aproximadament a sol3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .119 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP call TocaNota call TocaNota movlw .238 ; Valor que correspon aproximadament a sol3 movwf ValPR2 ; Ho posem com a valor de PR2 movlw .119 ; Valor que correspon a un cicle del 50 % movwf ValCCPR1L ; Valor de CCPR1L movlw .2 ; Valor dels bits de menys pes del CCP call TocaNota movlw b'00000001' ; Configura el Timer 2 ; bits T2KCPS (bits 1-0) a 11 prescalat de 16 ; bit 2 (TMR2ON) a 0, Timer aturat ; Postscaler TOUTPS (bits 6-3) no afecten al PWM movwf T2CON ; Ho posa com a configuració del Timer 2 return end

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