;*******************************************************************
;    CONTASECONDI 0 -> 9
;
;    di Walter Giocoso
;    http://digilander.iol.it/wgiocoso
;
;    compilato con MPLAB IDE 6.20
;    
;    
;     ______________________
;   |Nota importante    !!!|
;    ----------------------
;   NON E' UN CONTASECONDI DI PRECISIONE!
;   il programma è stato messo a punto come esercitazione nell'uso di 
;   alcuni blocchi di uso frequente in altri programmi, in particolare
;   quelli di gestione del PRESCALER e del registro TMR0
;   La ROUTINE "RITARDO" introduce un ritardo di esattamente 1 secondo
;   Questo ritardo viene poi aumentato dall'esecuzione di tutte le altre 
;   istruzioni; inoltre, a causa della struttura della ROUTINE "PRINT" 
;   che effettua un numero di confronti (quindi di istruzioni) differente 
;   in base alla cifra da rappresentare, questo ritardo non conteggiato 
;   non è neanche costante
;    
;*******************************************************************





    PROCESSOR   16F84
    __CONFIG    3FF1H
    RADIX       DEC
    INCLUDE     "P16F84.INC"
    ERRORLEVEL  -302



;                                            PIN_LCD    | SEGM.     | PORTB |
;            a                                  pin1    | comm      |       |
;         -------                               pin2    | f         | RB5   | 
;        |        |                             pin3    | g         | RB6   |  
;        |f       |b                            pin4    | e         | RB4   |   
;        |   g    |                             pin5    | d         | RB3   |
;         -------                               pin6    | comm      |       |
;        |        |                             pin7    | DP        | RB7   |
;        |e       |c                            pin8    | c         | RB2   |
;        |        |                             pin9    | b         | RB1   |
;         -------  []DP                        pin10    | a         | RB0   |
;            d




    ORG         0CH                 ;prima locazione registri per uso generico

COUNT   RES     1                   ;riserva 1 byte alla variabile - usata in RITARDO
SECONDI RES     1                   ;conteggio SECONDI



;               Definizione costanti per display (1 = acceso , 0 = spento)        
;                  hgfedcba
ZERO    EQU        b'00111111'            ;codifica numero 0
UNO     EQU        b'00000110'            ;codifica numero 1 
DUE     EQU        b'01011011'            ;codifica numero 2 
TRE     EQU        b'01001111'            ;codifica numero 3
QUATTRO EQU        b'01100110'            ;codifica numero 4 
CINQUE  EQU        b'01101101'            ;codifica numero 5 
SEI     EQU        b'01111101'            ;codifica numero 6 
SETTE   EQU        b'00000111'            ;codifica numero 7 
OTTO    EQU        b'01111111'            ;codifica numero 8 
NOVE    EQU        b'01101111'            ;codifica numero 9 
PUNTO   EQU        b'10000000'            ;codifica puntino
SPEGNI  EQU        b'00000000'            ;spegni tutto




    ORG         00H                 ;area programma del PIC

    BSF         STATUS, RP0         ;seleziona il banco 1 per definire I/O
    MOVLW       00000000B                
    MOVWF       TRISB               ;definisci porte B in uscita





;############################################################################
MAIN
    BCF         STATUS, RP0         ;banco 0
    CALL        RESET               ;azzera contatore SECONDI
STAMPA
    CALL        PRINT               ;stampa SECONDI
    CALL        RITARDO             ;attendi 1 s
    CALL        TEST_9              ;reset se l'ultima cifra stampata == 9
    INCF        SECONDI, 1          ;SECONDI:= SECONDI + 1
    GOTO        STAMPA
    
;############################################################################



TEST_9                              ;quando viene chiamata in W c'è la cifra
                                    ;inviata al display
    SUBLW       6FH                 ;6FH = codifica esadecimale del 9 sul display
    BTFSC       STATUS, Z
    GOTO        RIAVVIA
    RETURN
    
RIAVVIA
    CALL        RESET
    GOTO        STAMPA
    RETURN    
;____________________________________________________________________________    


PRINT
    MOVLW       9                   ; W == 9
    SUBWF       SECONDI,0           ;(SECONDI)-(W) -> (W)   Z==1 se differenza nulla
    BTFSC       STATUS, Z           ; SECONDI == 9 ?        se NO salta istruzione succ.
    GOTO        STAMPA_9            ;                       se SI visualizza numero
    MOVLW       8
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_8
    MOVLW       7
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_7
    MOVLW       6
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_6
    MOVLW       5
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_5
    MOVLW       4
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_4
    MOVLW       3
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_3
    MOVLW       2
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_2
    MOVLW       1
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_1
    MOVLW       0
    SUBWF       SECONDI,0           
    BTFSC       STATUS, Z           
    GOTO        STAMPA_0
STAMPA_9
    MOVLW       NOVE
    GOTO        ESCI
STAMPA_8
    MOVLW       OTTO
    GOTO        ESCI
STAMPA_7
    MOVLW       SETTE
    GOTO        ESCI
STAMPA_6
    MOVLW       SEI
    GOTO        ESCI
STAMPA_5
    MOVLW       CINQUE
    GOTO        ESCI
STAMPA_4
    MOVLW       QUATTRO
    GOTO        ESCI
STAMPA_3
    MOVLW       TRE
    GOTO        ESCI
STAMPA_2
    MOVLW       DUE
    GOTO        ESCI
STAMPA_1
    MOVLW       UNO
    GOTO        ESCI
STAMPA_0
    MOVLW       ZERO
    GOTO        ESCI
ESCI    
    MOVWF       PORTB

    RETURN
;_____________________________________________________



RESET
    MOVLW       0
    MOVWF       SECONDI             ;riazzera variabile "SECONDI"
    RETURN
;_______________________________________________________________________________






    


                                    
RITARDO                             ;utilizza il registro TMR0 e il prescaler
                                    ;serve ad ottenere un ritardo di 1 secondo
                                    
                                    
    BSF         STATUS, RP0         ;vai al banco 1 per accedere al registro OPTION_REG
    MOVLW       00000100B           ;impostiamo il PRESCALER
    MOVWF       OPTION_REG

;                       OPTION_REG:     -RBPU   INTDEG  T0CS    T0SE    PSA PS2 PS1 PS0
;                                       0       0       0       0       0   1   0   0

;                       T0CS=0         usa quarzo interno = 4/4 MHz
;                       PSA=0          usa prescaler
;                       PS2/1/0=100    dividi per 32 = 31250 Hz
    
    
    
    
    BCF         STATUS, RP0         ;vai al banco 0 per accedere al registro TMR0                                    
    MOVLW       6                   ;TMR0 conta da 6 a 255 = 250 conteggi
    MOVWF       TMR0                ;frequenza di azzeramento 31250/250 = 125 Hz
    MOVLW       125
    MOVWF       COUNT
CICLO    

; ----------- test del simulatore    
;    BCF         STATUS, RP0            ;seleziona il banco 0 per definire H/L
;    MOVLW       PUNTO
;    MOVWF       PORTB                  ; ___________________________________
;    NOP                                ;|QUESTO BLOCCO TEST E' UTILE IN FASE|
;    NOP                                ;|DI SVILUPPO DEL PROGRAMMA          |
;    MOVLW       SPEGNI                 ;|MA ALTERA IL TEMPO DI RIFERIMENTO  |
;    MOVWF       PORTB                  ; -----------------------------------
; -------------------------------        


    MOVF        TMR0,   W           ;se W = 0, TMR0 viene copiato su W 
                                    ;se W = 1, TMR0 viene copiato su se stesso 
                                    ;il flag Z viene posto a 1 quando TMR0=0
    BTFSS       STATUS, Z           ;salta prossima istruzione se Z=1 (ovvero TMR0=0)
    GOTO        CICLO               ;se Z=0   (TMR0 != 0) ripeti il ciclo
    MOVLW       6                   ;se Z=1 ricarica TMR0
    MOVWF       TMR0
    DECFSZ      COUNT,  1           ;ripeti 125 volte; frequenza finale 125/125 = 1 Hz
    GOTO        CICLO
    RETURN
; ____________________________________________________________________________________





    
    
    END    
