'
'  Mcar 2  
'  Carputer serial voltmeter
'  31/01/05 - 27/01/05
'  Version :   1 0
'
'
 DEFINE OSC 04                  'Set oscillatore a 4MHz
 DEFINE OSCCAL_1K 1             '
 DEFINE INTHAND  Myint          'define interrupt handler
 DEFINE DEBUG_REG GPIO          'Set Debugin pin por
 DEFINE DEBUG_BIT 5             'Set Debug pin bit
 DEFINE DEBUG_BAUD 2400         'Set Debug baud rate
 DEFINE DEBUG_MODE 0            'Set Debug mode: 0=true,1=inverted
'
 @ Device PIC12F675,WDT_ON,PWRT_ON,PROTECT_OFF,MCLR_OFF,BOD_ON
'
'
Cr          con     13          
Lf          con     10 
LedOn       con     1
LedOff      con     0
Vfs         con     20480       '20,480v 
K16         con     61441       'coefficiente filtro 15/16
'
Vbatt       var     word        'Vbatt filtrato
TmpW        var     word
Acc_Vbatt   var     word        'accumulatore Vbatt filtrato * 16
'
TimLed      var     byte        'timer per flash led
'
Flag        var     byte        '
Fl_int      var     Flag.0      'attivato ad ogi Tmr0 int
Fl_1        var     Flag.1      
Fl_2        var     Flag.2      
Fl_3        var     Flag.3          
'
SaveW       var     byte $5E system       'uso interrupt
SaveSt      var     byte $5F system      'uso interrupt
'
'                             pin 12F675
'Gnd                             pin 8
Ad0         var     GPIO.0      'pin 7   input A/D ch0
'           var     GPIO.1      'pin 6   output
'           var     GPIO.2      'pin 5   output  
'           var     GPIO.3      'pin 4   input                    
Led         var     GPIO.4      'pin 3   output 
Tx          var     GPIO.5      'pin 2   output serial port
'Vcc                             pin 1 
' .........................
'
        Goto avvio              ' Skip around interrupt handler
'
'
' Assembly language interrupt handler
asm
Myint
        movwf   SaveW           ;Save W
        swapf   STATUS,W        ;affects no STATUS bits
        bcf     STATUS,RP0      ;BACK TO LO REGS
        movwf   SaveSt          ;Save STATUS Reg
;
        bcf     INTCON,T0IF     ;remove Tmr0 int.
        bsf     _Fl_int         ;remember
        incf    _TimLed         ;timer led flash
;
        swapf   SaveSt,W
        movwf   STATUS          ;restore STATUS Reg
        swapf   SaveW,F
        swapf   SaveW,W         ;restore WREG
        retfie                  
endasm
'
'
Get_Vbatt:
'        pauseus 50                  'sample time
        ADCON0.1 = 1                'start A/D
        @ nop
        while ADCON0.1 = 1          
        wend
        TmpW.byte1 = ADRESH         'get A/D value
        TmpW.byte0 = ADRESL
        Acc_Vbatt = Acc_Vbatt ** K16 + TmpW  'filtro 15/16
        Vbatt = Acc_Vbatt / 16              ' / 16 valore normalizzato       
        return
'
Avvio:
        CMCON = 7               
        VRCON = 0               
        WPU = 0                 'no wake pullup
        IOCB = 0                'no int. on change
        ANSEL = %01010001       '16tosc gpio0 input analogico
        ADCON0 = %10000001      'right just , Vref=Vdd , ch.0 , A/D on
        GPIO = %00101001        'preset I/O
        TRISIO = %00001001      'configure direction  1=input 0=output
'
'  B7:   RBPU   - ENABLE PORT B PULL-UP            1=OFF
'  B6:   INTEDG - RB0 INT EDGE SEL                 0=fronte discesa
'  B5:   T0CS   - TMR0 SOURCE,       0=FOSC/4, 1=RA4 PIN
'  B4:   T0SE   - RA4CLK PIN EDGE SELECT,          0=+VE
'  B3:   PSA    - PRESCALE ASSIGN         0=TIMER, 1=WDG
'  B2-0: PS2-0  - PRESCALE RATE 111=256 FOR TIMER (=128 FOR WDT)
'  set prescaler = 256  (((4MHz/4) / 256) / 256) = 15,25Hz = 65,535ms.
        OPTION_REG = %10000111
'
' -- enable
'     B7: GIE  - GLOBAL INT enable                    0=OFF
'     B6: PEIE - PERIPHERAL INTERRUPT  enable         0=OFF
'     B5: T0IE - TMR0 O/FLOW INT enable               0=OFF
'     B4: INTE - RB0 INT enable                       0=OFF
'     B3: RBIE - PORTB CHANGE-OF-STATE INT enable     0=OFF
' -- flag
'     B2: T0IF - TMR0 O'FLOW      1=O/FLOW MUST RESET
'     B1: INTF - RB0 INT                            ACTIVE HIGH
'     B0: RBIF - PORTB CHANGE-OF-STATE flag,        ACTIVE HIGH
'
         Flag = 0                   'clr flags
         TimLed = 0
         INTCON = %10100000         'enable Tmr0 int         
'
         gosub Get_Vbatt
         Acc_Vbatt = TmpW * 16         'filter preload  Vbatt * 16
Lp_m:
        gosub Get_Vbatt               'make a new measure
        TmpW = Vbatt * Vfs            'AD * 20480
        TmpW = Div32 1024             '(AD * 20480) / 1024
        if Fl_int = 1 then            'sincro con Tmr0 int.
     	     Fl_int = 0    
           if TimLed > 1  and TimLed < 4 then 
              Led = LedOn              'pulse led  65mS * 2 = 130mS
           else
              Led = LedOff              
           endif 
           if TimLed > 15  then               '65mS * 15 = 1sec.
              debug  dec TmpW dig 4,dec TmpW dig 3,",",dec TmpW dig 2,Cr,Lf     	     
'            debug #Vbatt,Cr,Lf              'send Vbatt.   
              TimLed = 0                                         
           endif   
        endif
    goto Lp_m
'

