;===================================================================
;       CONVERTITORE 8421 -> DECIMALE CON DISPLAY A 2 CIFRE
;       E TABELLA DI CONVERSIONE MEMORIZZATA SU EEPROM
;       con tasto di abilitazione lettura
;       versione per PIC16F876
;
;	    di Walter Giocoso
;	    http://digilander.iol.it/wgiocoso
;
;	    compilato con MPLAB IDE 6.20
;
;===================================================================

;   PORTE RB0-RB7:  uscita display
;   PORTE RC4-RC7:  ingresso tasti
;   PORTA RC3:      tasto abilitazione lettura (con molla di rilascio)
;
;
;                               PORTB ->76543210                        76543210
;
;                               0 ->    abcdef..    OxFC        10->    abcdef.h    0xFD
;     _____       _____         1 ->    .bc.....    0x60        11->    .bc....h    0x61
;    |     |h   f|  a  |b       2 ->    ab.de.g.    0xDA        12->    ab.de.gh    0xDB
;    |     |     |     |        3 ->    abcd..g.    0xF2        13->    abcd..gh    0xF3
;     -----       -----         4 ->    .bc..fg.    0x66        14->    .bc..fgh    0x67
;    |     |h   e|  g  |c       5 ->    a.cd.fg.    0xB6        15->    a.cd.fgh    0xB7
;    |     |     |     |        6 ->    a.cdefg.    0xBE
;     -----       -----         7 ->    abc.....    0xE0
;                   d           8 ->    abcdefg.    0xFE
;                               9 ->    abcd.fg.    0xF6
;



        PROCESSOR   16F876
	    __CONFIG    3FF1H
	    RADIX 	    DEC
	    INCLUDE     "P16F876.INC"
	    ERRORLEVEL  -302
	
	
	
        ORG	        110H		            ;prima locazione registri per uso generico
                                            ;nel banco 2
        
;   BIT0    EQU         4                   ;RC4    bit di peso 1
;   BIT1    EQU         5                   ;RC5    bit di peso 2
;   BIT2    EQU         6                   ;RC6    bit di peso 4
;   BIT3    EQU         7                   ;RC7    bit di peso 8
        
INGRESSO RES        1    
CONT    RES         1                   ;variabile di conteggio
DATO    RES         1


        ORG         00H                 ;prima locazione area programma

        BSF         STATUS, RP0         ;banco 1 per definire I/O
        BCF         STATUS, RP1         ;==
        MOVLW       00000000B           ;porte B in uscita
        MOVWF       TRISB
        MOVLW       11111000B           ;porte RC3->RC7 ingresso
        MOVWF       TRISC

;######################################################################################
MAIN
        CALL        TABELLA             ;creazione tabella di conversione nella EEPROM
NUOVO        
        CALL        LEGGI               ;leggi ingresso
        CALL        AZZERA              ;azzera contatore        
        CALL        CERCA               ;cerca corrispondenza in tabella
        CALL        STAMPA              ;stampa cifra sul display
        GOTO        NUOVO

;######################################################################################




;-------------------------------------------------------------------------------------
STAMPA
                                        ;in questo istante la variabile CONT contiene
                                        ;il numero della posizione della tabella
                                        ;in cui è stato trovato il dato.
                                        ;CONT+16 conterrà la corrispondente codifica
                                        ;del display

        BSF         STATUS, RP1         ;banco 2 : accesso alle variabili
        BCF         STATUS, RP0                                        
        MOVLW       16
        ADDWF       CONT,   1           ;CONT := CONT+16                                        
        CALL        LEGGI_EE            ;leggi contenuto della EEPROM all'indirizzo CONT
                                        ;   il risultato si troverà nel registro W
        BCF         STATUS, RP0         ;seleziona banco 0 per accedere alle porte
        BCF         STATUS, RP1         ;==
        MOVWF       PORTB

        RETURN




;-------------------------------------------------------------------------------------
CERCA
        CALL        LEGGI_EE            ;restituisce il contenuto della cella in "DATO"
                                        ;banco selezionato: 2
        MOVF        DATO,   0           ;copia DATO in W
        SUBWF       INGRESSO,0          ;confronta combinazione di ingresso con DATO tabella
        BTFSS       STATUS, Z           ;se DATO==INGRESSO termina ricerca
        GOTO        PROSEGUI            ;altrimenti prosegui
        GOTO        FINE_RICERCA
PROSEGUI
        INCF        CONT,   1
        GOTO        CERCA

FINE_RICERCA        
        RETURN
                
        
        
;----------------------------------------------------------------------------------
AZZERA                                   
        MOVLW       0
        MOVWF       CONT                ;cont:=0

        RETURN




;----------------------------------------------------------------------------------        
LEGGI_EE

        BCF         STATUS, RP0         ;banco 2 per accedere ai registri EEADR - EEDATA
        BSF         STATUS, RP1         ;e alle variabili
        MOVF        CONT,   0           ;W:=CONT        
        MOVWF       EEADR
        BSF         STATUS, RP0         ;banco 3 per accedere ai registri EECON1 - EECON2
;        BSF         STATUS, RP1         ;==
        BCF         EECON1, EEPGD       ;punta all'area dati della EEPROM 
        BSF         EECON1, RD          ;abilita lettura
TEST_RD                                 ;attendi completamento lettura
        BTFSC       EECON1, RD
        GOTO        TEST_RD        

        BCF         STATUS, RP0         ;banco 2 per accedere ai registri EEADR - EEDATA
;        BSF         STATUS, RP1         ;==
        MOVF        EEDATA, 0           ;il dato è adesso in W
        MOVWF       DATO                ;dato:=W
        
        RETURN       






;----------------------------------------------------------------------------------------
LEGGI
        BCF         STATUS, RP0         ;banco 0 per lettura /scrittura porte B / C
        BCF         STATUS, RP1         ;==

LEGGI_TASTO
	    BTFSS	    PORTC,	3	        ;verifica pressione RC3
	    GOTO	    LEGGI_TASTO
ANTIRIMBALZO			                ;prosegui solo se rilasciato
	    BTFSC	    PORTC,	3
	    GOTO	    ANTIRIMBALZO
	
	        
        MOVF        PORTC,  0           ;copia PORTC su W
        BSF         STATUS, RP1         ;banco 2 per accedere alle variabili
        BCF         STATUS, RP0
        MOVWF       INGRESSO
                                        ;partendo da        INGRESSO=dddd????
                                        ;vogliamo ottenere  INGRESSO=0000dddd
        BCF         STATUS, C           ;azzera CARRY
        RRF         INGRESSO,1          ;shift a destra, scrittura su INGRESSO        
        BCF         STATUS, C
        RRF         INGRESSO,1
        BCF         STATUS, C
        RRF         INGRESSO,1
        BCF         STATUS, C
        RRF         INGRESSO,1
        RETURN








;----------------------------------------------------------------------------------------
TABELLA                                 ;scrittura della tabella di conversione su EEPROM
                                        ;negli indirizzi da 0 a 15 sono contenuti 
                                        ;i valori in BCD 8421 delle cifre decimali
                                        ;corrispondenti agli indirizzi stessi
                                        ;all'indirizzo n+16 troviamo i segmenti del display
                                        ;che si devono illuminare in corrispondenza del 
                                        ;decimale n


                                        ;verifica dell'esistenza della tabella nella EEPROM
                                        ;   tramite controllo di due locazioni di memoria
                                        ;--------------------------------------------------

        BCF         STATUS, RP0         ;seleziona banco2 per accedere ai registri
        BSF         STATUS, RP1         ;EEADR - EEDATA
                                        
        MOVLW       5
        MOVWF       CONT
        CALL        LEGGI_EE            ;il dato viene restituito in DATO; banco attivo: 2
        MOVLW       5
        SUBWF       DATO,   0
        BTFSS       STATUS, Z
        GOTO        COMPILA_TAB         ;ricompila tabella se i dati sono diversi (Z==0)
        MOVLW       30
        MOVWF       CONT
        CALL        LEGGI_EE            
        MOVLW       01100111B
        SUBWF       DATO,   0
        BTFSC       STATUS, Z
        GOTO        FINE_TAB            ;non ricompilare tabella se i due confronti sono 
                                        ;corretti (Z==1)
                                        
COMPILA_TAB        
;        BCF         STATUS, RP0         ;seleziona banco2 per accedere ai registri
;        BSF         STATUS, RP1         ;EEADR - EEDATA
                                        ;le chiamate successive vengono effettuate dentro
                                        ;"SCRIVI_EE"
                                        
        MOVLW       0                   ;codifica BCD 8421 del decimale 0
        MOVWF       EEADR
        MOVLW       0000B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE           ;scrive sulla EEPROM e restituisce banco 2
        MOVLW       1                   ;codifica BCD 8421 del decimale 1
        MOVWF       EEADR
        MOVLW       0001B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       2                   ;codifica BCD 8421 del decimale 2
        MOVWF       EEADR
        MOVLW       0010B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       3                   ; . . .
        MOVWF       EEADR
        MOVLW       0011B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       4
        MOVWF       EEADR
        MOVLW       0100B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       5
        MOVWF       EEADR
        MOVLW       0101B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       6
        MOVWF       EEADR
        MOVLW       0110B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       7
        MOVWF       EEADR
        MOVLW       0111B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       8
        MOVWF       EEADR
        MOVLW       1000B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       9
        MOVWF       EEADR
        MOVLW       1001B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       10
        MOVWF       EEADR
        MOVLW       1010B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       11
        MOVWF       EEADR
        MOVLW       1011B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       12
        MOVWF       EEADR
        MOVLW       1100B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       13
        MOVWF       EEADR
        MOVLW       1101B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       14
        MOVWF       EEADR
        MOVLW       1110B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       15
        MOVWF       EEADR
        MOVLW       1111B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        

        MOVLW       16                      ;codifica cifra 0 (=16-16)
        MOVWF       EEADR
        MOVLW       11111100B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       17                      ;codifica cifra 1 (=17-16)
        MOVWF       EEADR
        MOVLW       01100000B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       18                      ;codifica cifra 2 (=18-16)
        MOVWF       EEADR
        MOVLW       11011010B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       19                      ; . . .
        MOVWF       EEADR
        MOVLW       11110010B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       20
        MOVWF       EEADR
        MOVLW       01100110B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       21
        MOVWF       EEADR
        MOVLW       10110110B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       22
        MOVWF       EEADR
        MOVLW       10111110B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       23
        MOVWF       EEADR
        MOVLW       11100000B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       24
        MOVWF       EEADR
        MOVLW       11111110B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       25
        MOVWF       EEADR
        MOVLW       11110110B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       26
        MOVWF       EEADR
        MOVLW       11111101B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       27
        MOVWF       EEADR
        MOVLW       01100001B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       28
        MOVWF       EEADR
        MOVLW       11011011B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       29
        MOVWF       EEADR
        MOVLW       11110011B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       30
        MOVWF       EEADR
        MOVLW       01100111B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        MOVLW       31
        MOVWF       EEADR
        MOVLW       10110111B
        MOVWF       EEDATA 
        CALL        SCRIVI_EE
        BSF         STATUS, RP0         ;seleziona banco 3 per accedere a EECON1
        BSF         STATUS, RP1         ;==
        BCF         EECON1, WREN        ;disabilita accesso in scrittura sulla EEPROM
FINE_TAB
        BCF         STATUS, RP0         ;seleziona banco 0 per accedere alle porte
        BCF         STATUS, RP1         ;==
   	    MOVLW       00000010B
	    MOVWF       PORTB               ;pronto a ricevere ingresso
	                                    ;utile nella simulazione per indicare il 
	                                    ;completamento della scrittura tabella
        RETURN






;------------------------------------------------------------------------
SCRIVI_EE
        BSF         STATUS, RP0         ;seleziona banco 3 per accedere 
        BSF         STATUS, RP1         ;ai registri EECON1 - EECON2
        BSF         EECON1, WREN        ;abilita scrittura su EEPROM
        MOVLW       55H                 ;elimina  protezione in scrittura
        MOVWF       EECON2
        MOVLW       0xAA
        MOVWF       EECON2
        BSF         EECON1, WR          ;scrivi    
TEST_WR                                 ;attendi avvenuta scrittura
        BTFSC       EECON1, WR
        GOTO        TEST_WR      
        BCF         EECON1, EEIF        ;azzera FLAG di conferma scrittura
        BCF         STATUS, RP0         ;torna al banco 2 per accedere 
        BSF         STATUS, RP1         ;ai registri EEADR - EEDATA
        
        RETURN
;------------------------------------------------------------------------               




        
        END
        
        
