;**************************************************
;
; 
;
;                      CONTROLLO BATTERIA
;
; FUSES: WDT ON--  PWRT ON--  CP OFF--------
;      Watch Dog Timer (CON WDT ATTIVATO)
;
;  RA0  IN 25%          IN SE LOW LA BATTERIA E' CARICA               
;  RA1  IN 50%
;  RA2  IN 75%      
;  RA3  IN 100%
;  RB4  OUT TONI
;**************************************************

        PROCESSOR       16F84
        RADIX           DEC
        INCLUDE         "P16F84.INC"

        ;Setup of chip flags

        ;Enable watch dog timer
        ;Enable power up timer
        ;XT oscillator
        ;Disable code protect

        __CONFIG        3FF5H



        ORG     0CH

        ;16 bit counter used in the delay subroutine

Dly_Count_1	res	1		;Indirizzo ram 22H
Dly_Count_2	res	1
Count           res     2       ; assegno 2 bit
Conta           res     2       ; assegno 2 bit
DelayTone       res     2
DelayCounter    res     1
msDelayCounter  res     2
        ;Reset Vector
        ;Start point at CPU reset

        ORG     00H

        ;Jump to main body of program.

        goto    Start

        ;**********************************************************************
        ; Interrupt vector
        ; Start point for every interrupt handler
        ;**********************************************************************

        ORG     04H

        ;**********************************************************************
        ; Interrupt handler
        ;**********************************************************************

        bcf     INTCON,INTF     ;Reset INTF flag
        retfie                  ;Return to the main body

        ;**********************************************************************
        ; Main body
        ;**********************************************************************
Start:

        bsf     STATUS,RP0      ;Swap to data bank 1

         movlw B'00011111'    ; RA0-RA1 RA2-RA3-RA4 INPUT
         tris PORTA           ; contents of W copied to PORT A ...
         movlw B'11101111'    ; RB4 OUTPUT
         tris PORTB           ; and PORT B
      

        ;Set to 0 the INTEDG bit on OPTION register
        ;to have an interrupt on the falling edge of RB0/INT

        bcf     OPTION_REG & 0x7F,INTEDG

        ;Assign the PRESCALER to Watch dog timer

        bsf     OPTION_REG & 0x7F,PSA

        ;Set the PRESCALER to 1:128

        bsf     OPTION_REG & 0x7F,PS0
        bsf     OPTION_REG & 0x7F,PS1
        bsf     OPTION_REG & 0x7F,PS2

        bcf     STATUS,RP0      ;Swap to data bank 0

        bsf     INTCON,GIE      ;Enables interrupts
        bsf     INTCON,INTE     ;Enables RB0/INT interrupt
       
        bcf PORTB,0           ; RB0 LOW
        bcf PORTB,1           ; RB1 LOW
        bcf PORTB,2           ; RB2 LOW
        bcf PORTB,3           ; RB3 LOW
        bcf PORTB,4           ; RB4 LOW
        bcf PORTB,5           ; RB5 LOW
        
    
      ;------------------------BREVE STBY-----------

   
       clrf Conta                 
       movlw 2
       
       movwf Conta  
inizio        
      
       call Delay1
       call Delay1
       call Delay1
       call Delay1
       decfsz Conta,1
       goto inizio      
;-------------------------------
  
       
       
        ;**********************************************************************
        ; Main loop
        ;**********************************************************************
        ;call    segn_inizio 
Mainloop1

 	
 	 clrwdt                 ; clear WDT

         btfsc PORTA,0            ; SE RA0(IN 25%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         call  Beep_OFF           ; TONO FREQUENZA BASSA
         btfss PORTA,0            ; SE RA0(IN 25%) E' HIGHT BATT.SCARICA,  SALTA UNA RIGA
         call  Beep_ON            ; TONO FREQUENZA ALTA
 	
 	 btfsc PORTA,1            ; SE RA1(IN 50%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         call  Beep_OFF           ; TONO FREQUENZA BASSA
         btfss PORTA,1            ; SE RA1(IN 25%) E' HIGHT BATT.SCARICA,  SALTA UNA RIGA
         call  Beep_ON            ; TONO FREQUENZA ALTA
 	
 	 btfsc PORTA,2            ; SE RA2(IN 75%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         call  Beep_OFF           ; TONO FREQUENZA BASSA
         btfss PORTA,2            ; SE RA2(IN 75%) E' HIGHT BATT.SCARICA,  SALTA UNA RIGA
         call  Beep_ON            ; TONO FREQUENZA ALTA
        
         btfsc PORTA,3            ; SE RA3(IN 100%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         call  Beep_OFF           ; TONO FREQUENZA BASSA
         btfss PORTA,3            ; SE RA3(IN 100%) E' HIGHT BATT.SCARICA,  SALTA UNA RIGA
         call  Beep_ON            ; TONO FREQUENZA ALTA
        
       
                           
;--------------------  LOOP LIVELLO INFERIORE  ----------------------------------------
Secondloop                        ;LOOP SENZA FINE PERCHE' C'E' CLEAR WDT

         clrwdt                   ; clear WDT
         btfsc PORTA,0            ; SE RA0(IN 25%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         goto  Resetloop
         btfsc PORTA,1            ; SE RA1(IN 50%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         goto  Resetloop
         btfsc PORTA,2            ; SE RA2(IN 75%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         goto  Resetloop
         btfsc PORTA,3            ; SE RA3(IN 100%) E' HIGHT BATT.SCARICA, NON SALTA UNA RIGA
         goto  Resetloop
         goto  Secondloop
         
         
Resetloop                       ; NO CLEAR WDT , DOPO 2 SEC. RESET

        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        call  Milsecno_res
        goto  Resetloop
        
;***************** Beep circa 400 Hz

Beep_OFF
                clrwdt                 ; clear WDT
                
                clrw    
                call    msDelay

                movlw   1 
                movwf   DelayTone+0
                clrf    DelayTone+1
BeepLoop
                clrwdt                 ; clear WDT
                
                bsf     PORTB,4
                movlw   1     
                call    msDelay

                clrwdt                 ; clear WDT
                
                bcf     PORTB,4
                movlw   2     
                call    msDelay
                decfsz  DelayTone+1,F
                goto    BeepLoop

                clrwdt                 ; clear WDT
                
                decfsz  DelayTone+0,F
                goto    BeepLoop
                return

;***************** Beep circa 900 Hz

Beep_ON
                clrwdt                 ; clear WDT
                
                clrw    
                call    msDelay

                movlw   3 
                movwf   DelayTone+0
                clrf    DelayTone+1
BeepLoop1
                clrwdt                 ; clear WDT
               
                bsf     PORTB,4
                movlw   80     
                call    Delay2
                clrwdt                 ; clear WDT
                bcf     PORTB,4
                movlw   80     
                call    Delay2 
               
                clrwdt                 ; clear WDT

                decfsz  DelayTone+1,F
                goto    BeepLoop1

                decfsz  DelayTone+0,F
                goto    BeepLoop1
                return 
                

;***************** Delay subroutine

msDelay
                movwf   msDelayCounter+1
                clrf    msDelayCounter+0

msDelayLoop
                decfsz  msDelayCounter+0,F
                goto    msDelayLoop
                decfsz  msDelayCounter+1,F
                goto    msDelayLoop

                return
                
         
;***************** Delay2 subroutine

Delay2
                movwf   DelayCounter

DelayLoop2
                nop
                nop
                decfsz  DelayCounter,F
                goto    DelayLoop2

                return
;-----------------------------------------------------------------------------------
Delay6m                       ;RITARDO 6 MINUTI

        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        call  Delay30s
        return



Delay30s                       ;RITARDO 30 SECONDI
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
        call    Delay1s 
       
        return


Delay1s                         ; RITARDO 1 SECONDO
        call    Delay1
        call    Delay1
        call    Delay1
        call    Delay1
        call    Delay1
        return



         

Delay1                         ; RITARDO 0,20 SECONDI
        clrwdt                 ;Clear WDT
        clrf    Count
        clrf    Count+1

DelayLoop

        decfsz  Count,1
        goto    DelayLoop

        decfsz  Count+1,1
        goto    DelayLoop

        return
        
;======================	Routine ritardo millisec in base al contenuto di W
;SE W è 80 , IL RITARDO è DI CIRCA 80 MILLISECONDI
Mil_Secondi
                clrwdt                 ; clear WDT
                movwf   Dly_Count_2
                clrf    Dly_Count_1

                ;1 ms (about) internal loop
ms_Del_Loop
                nop
		decfsz	Dly_Count_1,F
		goto	ms_Del_Loop
                nop

		decfsz	Dly_Count_2,F
		goto	ms_Del_Loop

		return
		
		
Milsecno_res     ; 80 millisecondi no WDT
             
                movwf   Dly_Count_2
                clrf    Dly_Count_1

                ;1 ms (about) internal loop
ms_Del_Loop1
                nop
		decfsz	Dly_Count_1,F
		goto	ms_Del_Loop1
                nop

		decfsz	Dly_Count_2,F
		goto	ms_Del_Loop1

		return
           

    
         

           
;segn_inizio 
          ;call   Beep_ON
          ;call   Delay1
          ;call   Beep_OFF
          ;call   Delay1
          ;call   Beep_ON
          ;return
            
   

fine        
        END

 	
 	
        
 	

 
    