En aquest cas van considerar que la bàscula tenia un límit màxim de 6 kg. Quan s'assoleix aquest límit la bàscula avisa encenent un LED i fent sonar el brunzidor.
El programa final és:
#include <p16F690.inc> __config (_INTRC_OSC_NOCLKOUT&_WDT_OFF&_PWRTE_OFF&_MCLRE_OFF&_CP_OFF&_BOR_OFF&_IESO_OFF&_FCMEN_OFF)
cblock 0x20 Lectura:3 ; Lectura del sensor Tara:2 Resta:2 X:4 Resultat:4 Resul:3 Valor:2 max:2 Port ; Bits del port C ; RC0 a RC3 són els LED ; RC4 és DAT (DOUT del sensor) ; RC6 és CLK (PD_SCK del sensor) ; RC5 és on hi ha el brunzidor Caracter ; Caràcter o codi a enviar a la pantall Temp Compta ; Comptador d'iteracions D1 ; Variable unitats D2 ; Variable desenes D3 ; Variable centenes Retard1 ; Variables per als cicles de retard Retard2 Retard3 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
Inici bsf STATUS,RP1 ; Tria el banc 2 movlw b'00000101' movwf ANSEL ; Configura AN0 i AN2 com entrada analògica clrf ANSELH ; Desactiva les altres entrades analògiques bcf STATUS,RP1 bsf STATUS,RP0 ; Tria el banc 1 movlw 0xFF ; Posa l'acumulador a FFh (tot uns) movwf TRISA ; Posa tots els bits del port A com a entrada movlw b'00010000' ; Posa RC4 com a entrada movwf TRISC ; La resta del port C és de sortida clrf TRISB ; Tot el port B és de sortida bsf TXSTA,BRGH ; Configuració de velocitat bcf BAUDCTL,BRG16 ; Paràmetre de velocitat de 8 bits movlw .25 ; Velocitat de 9600 baud movwf SPBRG ; Paràmetre de velocitat bcf TXSTA,SYNC ; Comunicació asíncrona bcf TXSTA,TX9 ; Comunicació de 8 bits bcf STATUS,RP0 ; Tria el banc 0 bsf RCSTA,SPEN ; Activa comunicació sèrie bsf STATUS,RP0 ; Tria el banc 1 bsf TXSTA,TXEN ; Activa comunicació bcf STATUS,RP0 ; Tria el banc 0 clrf Tara ; Posa el valor Tara a zero clrf Tara+1 clrf max ; Posa el valor màxim a zero clrf max+1 clrf Port ; Desactiva tots els bits de Port clrf PORTB ; Desactiva tots els bits del port B clrf PORTC ; Desactiva tots els bits del port C Bucle call LlegirHX ; Llegeix el valor del sensor HX711 ; Enviem l'adreça i els valors movlw .254 ; Caràcter de control movwf Caracter ; Ho guarda a la variable call EnviaL ; Ho envia movlw .1 ; Esborra la pantalla i posa el cursor a l'inici movwf Caracter ; Ho guarda a la variable call EnviaL ; Ho envia bcf STATUS,C ; Volem entrar un zero rlf Lectura,f rlf Lectura+1,f rlf Lectura+2,f bcf STATUS,C ; Volem entrar un zero rlf Lectura,f rlf Lectura+1,f rlf Lectura+2,f movf Tara,f ; Mirem un dels dos bytes btfss STATUS,Z goto NoZero ; Si aquest no és zero ja estem movf Tara+1,f ; Si un és zero, mirem l'altre btfss STATUS,Z goto NoZero ; Si aquest no és zero ; Si es zero copiem Lectura a Tara movf Lectura+1,w movwf Tara movf Lectura+2,w movwf Tara+1 NoZero movf Tara,w movwf Resta movf Tara+1,w movwf Resta+1 comf Resta,f ; Complementa Resta incf Resta,f ; I l'incrementa (el conjunt equival a canviar el signe) btfsc STATUS,Z ; Mirem si s'activa Z decf Resta+1,f ; Si era zero cal decrementar Resta+1 comf Resta+1 ; Complementem Resta+1 movf Resta,w ; Llegim a W la variable que hem de sumar addwf Lectura+1,f ; L'afegim al byte de la dreta btfsc STATUS,C ; Mirem si s'activa C incf Lectura+2,f ; Si s'activa, incrementem el byte superior movf Resta+1,w ; Llegim a W la variable que hem de sumar addwf Lectura+2,f ; L'afegim al byte de la dreta ; Copiem Lectura a Resultat clrf Resultat+2 clrf Resultat+3 movf Lectura+1,w movwf Resultat movf Lectura+2,w movwf Resultat+1 ; Rotem 12 vegades cap a l'esquerra Resultat call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq call RotarResEsq ; Copiem Lectura en X clrf X+2 clrf X+3 movf Lectura+1,w movwf X movf Lectura+2,w movwf X+1 ; Rotem 9 vegades a la esquerra X call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq ; Sumem X a Resultat call SumaResX ; Copiem Lectura sobre X clrf X+2 clrf X+3 movf Lectura+1,w movwf X movf Lectura+2,w movwf X+1 ; Rotem X 8 vegades a la esquerra call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq ; Sumem X al Resultat call SumaResX ; Copiem Lectura sobre X clrf X+2 clrf X+3 movf Lectura+1,w movwf X movf Lectura+2,w movwf X+1 ; Rotem 6 cops X call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq ; sumem X a Resultat call SumaResX ; Copiem Lectura sobre X clrf X+2 clrf X+3 movf Lectura+1,w movwf X movf Lectura+2,w movwf X+1 ; Rotem X 4 veces a la esquerra call RotarXEsq call RotarXEsq call RotarXEsq call RotarXEsq ; Sumem X a Resultat call SumaResX ; Copiem Lectura sobre X clrf X+2 clrf X+3 movf Lectura+1,w movwf X movf Lectura+2,w movwf X+1 ; Rotem X 3 cops a l'esquerra call RotarXEsq call RotarXEsq call RotarXEsq ; Sumem X sobre Resultat call SumaResX ; Copiem Lectura sobre X clrf X+2 clrf X+3 movf Lectura+1,w movwf X movf Lectura+2,w movwf X+1 ; Sumem X a Resultar call SumaResX ; DIVIDIM Resultat ENTRE 16384 rotant 14 cops cap a la dreta call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD call RotarResD movf Resultat,w movwf Valor movf Resultat+1,w movwf Valor+1 ; ENVIA VALORES call BCD5 ; Ho converteix en BCD en 3 bytes call Separa ; Ho separem en 5 bytes movlw .5 ; Cal fer-ho 5 cops movwf Compta ; Ho posem al comptador movlw Resul+4 ; Adreça de la darrera xifra movwf FSR ; Adreçament indirecte ; ; Llegeix el valor del sensor HX711 ; ; Valor+2 té el byte més significatiu btfss PORTA,3 ; Mira si està activada l'entrada A3 ; Si està activada, no fa la instrucció següent ; Fa la instrucció si l'entrada està desactivada ; És a dir, si el polsador està premut call Premut ; Si està premut, cridem a la funció Premut btfsc Valor+1,8 ; Mira si el bit 8 del byte Valor+1 és zero ; Si ho és salta la seguent linea, sino ; vol dir que estrem tractan un número negatiu, ; per tant crida la funció Negativo call Negativo btfsc Valor+1,8 ; Mira si el bit 8 del byte Valor+1 és zero ; Si ho és salta la seguent linea, sino ; vol dir que estrem tractan un número negatiu, ; per tant no cal fer cap més operació i ; tornem al inici del Bucle goto Bucle ; Implementem un màxim de 6kg movlw b'00010111' movwf max+1 movlw b'01110000' movwf max ; Comparem el Resultat (que era la conversió de les dades significatives ; de Lectura en grams) amb el màxim establert movf max+1,w ; W té el màxim xorwf Resultat+1,w ; Comparem amb Resultat+1 btfss STATUS,Z ; Si Z = 1 eren iguals goto DifMax2 ; Si són diferents, provem el cas 2 movf max,w ; W té el màxim subwf Resultat,w ; W = Resultat - W = Resultat - max btfss STATUS,C ; C = 1 si Resultat >= max goto envio ; Si és més petit, no cal fer res call sup6kg ; Si és més gran, cridem la funció DifMax2 movf max+1,w ; W té el màxim subwf Resultat+1,w ; W = Resultat+1 - W = Resultat+1 - max+1 btfss STATUS,C ; C = 1 si Resultat+1 >= max+1 goto envio ; Si és més petit, no cal fer res call sup6kg envio movlw ' ' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL BuclePant movf INDF,w ; Llegeix el caràcter movwf Caracter ; Ho guarda a la variable call EnviaL ; Ho envia decf FSR,f ; Decrementa FSR decfsz Compta,f ; Decrementa el comptador goto BuclePant ; Si no és zero, repetim ; RETARDO movlw ' ' movwf Caracter call EnviaL movlw 'g' movwf Caracter call EnviaL movlw .5 call Rets goto Bucle
LlegirHX movlw .24 ; Llegim 24 bits movwf Compta ; Ho guarda a Compta bcf Port,6 ; Desactiva PD_SCK movf Port,w ; Copia Port a l'acumulador movwf PORTC ; I ho posa al PORTC BucleLec bsf Port,6 ; Activa PD_SCK movf Port,w ; Copia port a l'acumulador movwf PORTC ; I ho posa al PORTC bcf STATUS,C ; Preventivament posa C a zero btfsc PORTC,4 ; Llegeix DOUT bsf STATUS,C ; Si l'entrada està activada activem C rlf Lectura,f ; Entrem el bit a Lectura rlf Lectura+1,f ; I fem rodar els altres bits rlf Lectura+2,f bcf Port,6 ; Desactiva PD_SCK movf Port,w ; Copia Port a l'acumulador movwf PORTC ; I ho posa al PORTC nop ; Espera 3 us per fer els polsos de la mateixa amplada nop nop decfsz Compta,f ; Ja hem llegit un bit goto BucleLec ; Repetim fins tenir els 24 bsf Port,6 ; Activa PD_SCK per dir-li el guany movf Port,w ; Copia Port a l'acumulador movwf PORTC ; I ho posa al PORTC nop ; Espera 6 us per fer els polsos de la mateixa amplada nop nop nop nop nop bcf Port,6 ; Desactiva PD_SCK movf Port,w ; Copia Port a l'acumulador movwf PORTC ; I ho posa al PORTC return ; ; Envia un valor a la pantalla ; ; El valor està a W ; ; Enviem caràcters a visualitzar ; EnviaL movf Caracter,w ; Agafa el caràcter movwf TXREG ; L'envia nop nop ; Espera 2 us btfss PIR1,TXIF ; El registre TXREG ha quedat lliure? goto $-1 ; No, doncs esperem return ; Tornem al lloc des d'on hem vingut ; ; Funció de retard de 0,2 W s BCD5 bcf STATUS,C ; Posa a zero C per entrar zeros a les rotacions movlw .16 ; Nombre d'iteracions movwf Compta ; Comptador d'iteracions clrf Resul+2 ; Desenes de miler clrf Resul+1 ; Unitats de miler i centenes clrf Resul ; Desenes i unitats BucleBCD rlf Valor,f ; Girem bits a l'esquerra a valor rlf Valor+1,f ; Cap a valor+1 rlf Resul,f ; I cap als resultats rlf Resul+1,f rlf Resul+2,f decfsz Compta,f ; Decrementa Compta goto ajust ; Si no és zero, ajustem el resultat retlw 0 ; Si és zero ja estem; tornem un 0 a W ajust ; funció d'ajust dels resultats movlw Resul ; Agafem l'adreça del byte de menys pes movwf FSR ; La posa a l'adreçament indirecte call ajustBCD ; Ajusta el byte de més a la dreta movlw Resul+1 ; Agafem l'adreça del byte del mig movwf FSR ; La posa a l'adreçament indirecte call ajustBCD ; Ajusta el byte del mig movlw Resul+2 ; Agafem l'adreça del byte de més pes movwf FSR ; La posa a l'adreçament indirecte call ajustBCD ; Ajusta el byte de més a l'esquerra goto BucleBCD ; Torna a repetir el bucle (fins a 16 cops) ; ; funció d'ajust d'un byte, primer el nibble de la dreta, després l'altre ; ajustBCD movlw 0x03 ; Agafa el valor 03h addwf INDF,w ; El suma al byte que ajustem movwf Temp ; Ho guarda a Temp btfsc Temp,3 ; És més gran que 07h (s'ha activat el bit 3)? movwf INDF ; Si és cert, sobreposa el resultat movlw 0x30 ; Agafa el valor 30h addwf INDF,w ; El suma al byte que ajustem movwf Temp ; Ho guarda a Temp btfsc Temp,7 ; És més gran que 70h (s'ha activat el bit 7)? movwf INDF ; Si és cert, sobreposa el resultat retlw 0 ; Retorna amb un zero a W ; ; Separa els digits i els converteix a ASCII ; Separa movf Resul+2,w ; Agafa les desenes de miler movwf Resul+4 ; Les posa al seu lloc swapf Resul+1,w ; Llegeix les unitats de miler i les centenes i les guarda, permutades, a w andlw 0x0F ; Es queda amb les unitats de miler movwf Resul+3 ; Les posa al seu lloc movf Resul+1,w ; Llegeix les unitats de miler i les centenes i les guarda a w andlw 0x0F ; Es queda amb les centenes movwf Resul+2 ; Les posa al seu lloc swapf Resul,w ; Llegeix les desenes i les unitats i les guarda, permutades, a w andlw 0x0F ; Es queda amb les desenes movwf Resul+1 ; Les posa al seu lloc movf Resul,w ; Llegeix les desenes i les unitats i les guarda a w andlw 0x0F ; Es queda amb les unitats movwf Resul ; Les posa al seu lloc movlw .5 ; Cal fer-ho 5 cops movwf Compta ; Ho posem al comptador movlw Resul+4 ; Adreça de la darrera xifra movwf FSR ; Adreçament indirecte movlw '0' ; Carrega el codi ASCII del número 0 Bucle1 addwf INDF,f ; Ho afegeix al dígit decf FSR,f ; Decrementa FSR decfsz Compta,f ; Decrementa el comptador goto Bucle1 ; Si no és zero, repetim movlw .4 ; Cal fer-ho 4 cops movwf Compta ; Ho posem al comptador movlw Resul+4 ; Adreça de la darrera xifra movwf FSR ; Adreçament indirecte Bucle2 movf INDF,w ; Llegeix el dígit xorlw '0' ; Compara amb 0 btfss STATUS,Z ; Si Z està activat eren iguals goto Final1 ; Si no eren iguals, ja estem movlw ' ' ; Carrega un espai en blanc movwf INDF ; Substitueix el 0 per l'espai decf FSR,f ; Decrementa FSR decfsz Compta,f ; Decrementa el comptador goto Bucle2 Final1 retlw 0 ; Retorna amb un 0 a W sup6kg 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'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 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 call RetM ; Espera 0,2 s LED banksel TRISC ; Tria el banc 1 bcf TRISC,0 ; Posa el bit 0 del port C com a sortida banksel PORTC ; Tria el banc 0 bsf PORTC,0 ; Activa el bit 0 del port C movlw ' ' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL movlw '6' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL movlw 'k' movwf Caracter call EnviaL movlw 'g' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL movlw 'M' movwf Caracter call EnviaL movlw 'A' movwf Caracter call EnviaL movlw 'X' movwf Caracter call EnviaL movlw .5 call Rets goto Bucle return RetM ; Funció de retard de 0,2 s decfsz Retard1,f goto RetM decfsz Retard2,f goto RetM return Negativo banksel TRISC ; Tria el banc 1 bcf TRISC,0 ; Posa el bit 0 del port C com a sortida banksel PORTC ; Tria el banc 0 bsf PORTC,0 ; Activa el bit 0 del port C movlw ' ' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL movlw ' ' movwf Caracter call EnviaL movlw 'N' movwf Caracter call EnviaL movlw 'e' movwf Caracter call EnviaL movlw 'g' movwf Caracter call EnviaL movlw 'a' movwf Caracter call EnviaL movlw 't' movwf Caracter call EnviaL movlw 'i' movwf Caracter call EnviaL movlw 'v' movwf Caracter call EnviaL movlw 'o' movwf Caracter call EnviaL movlw .5 call Rets return Premut clrf Tara clrf Tara+1 return RotarResEsq bcf STATUS,C ; Volem entrar un zero rlf Resultat,f rlf Resultat+1,f rlf Resultat+2,f rlf Resultat+3,f return RotarResD bcf STATUS,C ; Volem entrar un zero rrf Resultat+3,f rrf Resultat+2,f rrf Resultat+1,f rrf Resultat,f return RotarXEsq bcf STATUS,C ; Volem entrar un zero rlf X,f rlf X+1,f rlf X+2,f rlf X+3,f return SumaResX movf X,w ; Llegim a W la variable que hem de sumar addwf Resultat,f ; L'afegim al byte de la dreta btfss STATUS,C ; Mirem si s'activa C goto sum1 incf Resultat+1,f ; Si s'activa, incrementem el byte superior btfss STATUS,Z goto sum1 incf Resultat+2,f btfsc STATUS,Z incf Resultat+3,f sum1 movf X+1,w ; Llegim a W la variable que hem de sumar addwf Resultat+1,f ; L'afegim al byte de la dreta btfss STATUS,C ; Mirem si s'activa C goto sum2 incf Resultat+2,f ; Si s'activa, incrementem el byte superior btfsc STATUS,Z incf Resultat+3,f sum2 movf X+2,w ; Llegim a W la variable que hem de sumar addwf Resultat+2,f ; L'afegim al byte de la dreta btfsc STATUS,C ; Mirem si s'activa C incf Resultat+3,f ; Si s'activa, incrementem el byte superior movf X+3,w ; Llegim a W la variable que hem de sumar addwf Resultat+3,f ; L'afegim al byte de la dreta return ; Rets movwf Retard3 Bucles decfsz Retard1,f goto Bucles decfsz Retard2,f goto Bucles decfsz Retard3,f goto Bucles return end

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