BENEDICIC SAMO [samo.benedicic at HIT.SI] says:
Hi!
I made this to monitor working hours of an oil burner. Clock works only when
RA4 is low. Elapsed time is displayed on four common cathode 7 segment LED
displays, so the clock counts to 9999 hours. It's easy to change it so that
it counts seconds or minutes. Displays are connected like this: RA0-RA3 are
going on bases of four 2N2222 transistors, emitors on GND and collectors on
cathodes of displays. RA2-thousands, RA3-hundreds, RA1-tens, RA0-ones ( I
ones connected them like that and then changed the code to display numbers
right ). Anodes are connected A = RB0  to G=RB6. RA4 has a 10k pullup
resistor connected to +5V and a switch to ground. Code is partially taken
from Microchip AN557, so is the schematics. If you have any questions about
the code, don't hesitate to ask. I would appreciate any comments and
suggestions. If anybody needs english comments on the code, I can translate
it in, like, 10 minutes. Attached is an txt file, you just copy and paste it
to MPLAB. Regards, Samo
;**********************************************************************
;                                                                     *
;    Filename:          gorilec.asm                                   *
;    Date:              20.12.2000                                    *
;    File Version:      1                                             *
;                                                                     *
;    Author:            Benedièiè  Samo                               *
;    Company:           Hit                                           *
;                                                                     * 
;                                                                     *
;**********************************************************************
;                                                                     *
;    Files required:                                                  *
;                                                                     *
;                                                                     *
;                                                                     *
;**********************************************************************
;                                                                     *
;    Notes: This is a clock, used to measure the time that oil burner *                                                       *
; is on                                                               *
;                                                                     *
;**********************************************************************
        list      p=16F84A             ; list directive to define processor
        #include <p16F84A.inc>         ; processor specific variable definitions
        __CONFIG   _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
; '__CONFIG' directive is used to embed configuration data within .asm file.
; The lables following the directive are located in the respective .inc file.
; See respective data sheet for additional information on configuration word.
;**************************************************************************************
;
; definition of some shit ( used for easier remembering )                             *
;
;**************************************************************************************
        w       equ     0       ;direction for byte oriented instructions
        f       equ     1
        Z       equ     2       ;zero flag
;**************************************************************************************
;
;definition of some registers I'll use
;
;**************************************************************************************
        CBLOCK  0Ch             ;it's way easier to define registers this way
        COUNTER1
        COUNTER2
        SECONDS
        MINUTES
        MSD
        LSD
        OSVEZI
        SINK
        RES_STEVEC1
        RES_STEVEC2
        RES_STEVEC3
        A_TEMP
        UGASNJENO
        ENDC
	
	
	
        	
	
;**************************************************************************************
;
;and some useful macros
;
;**************************************************************************************
BANK0   macro
        bcf     STATUS, RP0     ;switch to bank0
        endm
BANK1   macro
        bsf     STATUS, RP0     ;bank1
        endm	
;**************************************************************************************
;
        ORG     0               ;main program location
        goto    START
;
;
;
        ORG     4               ;interrupt vector
        goto    SERVICE_INTERRUPT	
;
;
;
START
;
;
        call    INIT_COUNTERS   ;clear counters 
        call    INIT_PORTS      ;inicializiraj porte
        call    INIT_TIMER      ;start tmr0
;
;	
MAIN
;       clrf    PORTA
        goto    MAIN            ;37 ciklov do zanke
;
;
;
INIT_COUNTERS
;
        clrf    COUNTER1
        clrf    COUNTER2
        clrf    SECONDS
        clrf    MINUTES
        clrf    MSD
        clrf    LSD
        clrf    OSVEZI
        clrf    RES_STEVEC1
        clrf    RES_STEVEC2
        clrf    RES_STEVEC3
        clrf    UGASNJENO
        return
;
INIT_PORTS
        BANK1
        clrf    TRISA
        bsf     TRISA, 4        ;èetrti pin PORTA je vhod, ostalo izhodi
        clrf    TRISB           ;portb so izhodi
;
        BANK0
        clrf    PORTA
        clrf    PORTB
        bsf     PORTA, 3        ;omogoèi ponor za najbolj levi display
        return
;
INIT_TIMER
        BANK1
        movlw   b'00001000'     ;prescaler 1:1
        movwf   OPTION_REG
;
        movlw   b'10100000'     ;enable TMR0 interrupt
        movwf   INTCON
;
        BANK0                   ;we aim to have interrupt every 250 microsec,so we 
        movlw   .8              ;write (256-250+2)=8 to TMR0, because
;       movlw   .230            ;TEST!!!!
        movwf   TMR0            ;two clock cycles go by before 
                                ;TMR0 is incremented for the first time	
        return
;	
;
;*************************************************************************
;
;       All our work will be done here
;
;*************************************************************************
SERVICE_INTERRUPT
        BANK0                   ;I need 3 cycles to write new
        movlw   .13             ;value to TMR0+2 cycles to start counting again
;       movlw   .220            ;TEST!!!!!
        movwf   TMR0
        bcf INTCON, 2           ;clear interrupt flag
;
;****************************************************************************
;
;       Vsakih 99 TMR0 interruptov (cca. 40 x na sekundo ) osveim display.
;       99 je izbrana zato, da se èimmanjkrat primeri, da gre tok 
;       programa skozi vse rutine, torej, da se ne izvajajo hkrati
;       rutine osveevanja displaya in inkrementiranja vseh tevcev.
;
;****************************************************************************
;
;
	
        call    OSVEZI_DISPLAY  ;ja, osvei display
;
;
;***************************************************************************
;
;       Preverim tudi stanje reset tipke, ki je povezana na RB0 preko ibkega
;       pull-up upora 10k proti masi.	
;
;***************************************************************************
;
        movf    PORTA, w
        movwf   A_TEMP          ;shrani vrednost PORTA
;
        clrf    PORTA           ;poèisti PORTA
        BANK1
        movlw   b'00000001'
        movwf   TRISB           ;RB0 je vhod
        bcf     OPTION_REG, 7   ;omogoèi pull-up upore
        BANK0
        btfss   PORTB, 0
        call    RESET           ;iz reseta se vrnem Z RB0 kot vhodom
;
        BANK1
        clrf    TRISB
        BANK0
;
        movf    A_TEMP, w
        movwf   PORTA           ;povrni stanje PORTA
;
;
;***************************************************************************	
;
;       Pred poveèanjem tevcev preverim, èe je gorilec  prigan
;
;***************************************************************************
;
        btfsc   PORTA, 4        ;ali je gorilec prigan?  NI DEBOUNCA
        retfie                  ;ne, odpujsaj nazaj
;
;
        incf    COUNTER1        ; nadaljuj kot da ni niè	
        movf    COUNTER1, w
        xorlw   .200            ;ali je 200 (50 ms)?
;       xorlw   .2              ;TEST!!!!
        btfss   STATUS, Z       ;da, poveèaj naslednjega
        retfie                  ;no, I'm done here
        clrf    COUNTER1
        incf    COUNTER2        ;inc next one
        movf    COUNTER2, w
        xorlw   .20             ;is it one second yet
;       xorlw   .2              ; test to make it faster
        btfss   STATUS, Z	
        retfie                  ;no, exit
;
;
        clrf    COUNTER2        ;yes, clear counter
        incf    SECONDS         ;and increment seconds
        movf    SECONDS, w
        xorlw   .60             ;is it one minute yet?
;       xorlw   .2              ;test
        btfss   STATUS, Z
        retfie                  ;no, get out
;
        clrf    SECONDS         ;clear seconds
        incf    MINUTES         ;and inc minutes
        movf    MINUTES, w
        xorlw   .60             ;is it an hour?
;       xorlw   .2              ;test
        btfss   STATUS, Z       ;ja, pojdi poservisirat
        retfie                  ;no, go away
;
;**********************************************************************
;
;       Vrednost, katero hoèemo imeti na displayu, je shranjena v registrih ZGORNJI
;       in VISOKI v obliki tirih BCD vrednosti. Vsakemu displayu pripadajo po 
;       tirje biti v registru. Tukaj inkrementiram te BCD cifre.
;
;************************************************************************
        	
        clrf    COUNTER2        ;TEST!!!!!!!!!!!!!!!!!!!!
        clrf    MINUTES         ;pobrii minute
        incf    MSD, w          ;poveèaj v w
        andlw   b'00001111'     ;maskiraj LSD nibble
        xorlw   .10             ;=10?
        btfsc   STATUS, Z       ;ne, pojdi na naslednjega
        goto    POVECAJ_DRUGEGA
        incf    MSD, f          ;ja, inkrementiraj prvega
        retfie                  ;in pojdi nazaj
;
;
POVECAJ_DRUGEGA
;
        swapf   MSD, w          ;zamenjaj nibble v w
        andlw   b'00001111'     ;maskiraj visoki nibble
        addlw   .1              ;poveèaj
        movwf   MSD
        swapf   MSD, f          ;vzpostavi pravo stanje
        xorlw   .10             ;=10?
        btfsc   STATUS, Z
        goto    NIZKI           ;ja,poveèaj drugi register
        retfie
;
NIZKI
        clrf    MSD             ;poèisti LSD(vse 0)
;
        incf    LSD, w          ;poveèaj
        andlw   b'00001111'     ;maskiraj visoki nibble
        xorlw   .10             ;=10?
        btfsc   STATUS, Z
        goto    POVECAJ_ZADNJEGA;ja, pobrii in pojdi na èetrti display
        incf    LSD, f          ;ne, poveèaj tega in pojdi nazaj
        retfie
;
;
POVECAJ_ZADNJEGA
;
        swapf   LSD, w          ;zamenjaj nibble
        andlw   b'00001111'     ;maskiraj visoke bite
        addlw   .1              ;poveèaj
        movwf   LSD
        swapf   LSD, f  ;=10?
        xorlw   .10
        btfss   STATUS, Z
        retfie                  ;ne, pojdi nazaj
;
        clrf    LSD             ;ja, ponovi celo vajo
        clrf    MSD
;
        retfie
;****************************************************************************
;
;       Rutina osveevanja displaya, pobrana iz Mchipovega
;       AN557
;
;****************************************************************************
;
OSVEZI_DISPLAY                  ;30 ciklov
;
;
        movf    PORTA, w        ;preberi, kateri digit sink je omogoèen
        clrf    PORTA           ;na vhode ta ukaz ne vpliva, ker procesor prebere dejansko stanje
        andlw   b'00001111'     ;obdri samo pomembne tiri bite
        movwf   SINK            ;in shrani to vrednost
        bsf     SINK, 4         ;pripravi vrednost za levi display
        rrf     SINK, f         ;ugotovi, kateri display je za osveit
        btfss   STATUS, C       ;c=1?
        bcf     SINK, 3
        btfsc   SINK, 0
        goto    OSVEZI_CETRTEGA
        btfsc   SINK, 1
        goto    OSVEZI_TRETJEGA
        btfsc   SINK, 2
        goto    OSVEZI_DRUGEGA
;
OSVEZI_PRVEGA
        movf    LSD, w
        andlw   b'00001111'
        goto    DISPLAY_OUT
;
OSVEZI_DRUGEGA
;
        swapf   LSD, w  ;obrni bite
        andlw   b'00001111'     ;maskiraj nepotrebne
        goto    DISPLAY_OUT
;
OSVEZI_CETRTEGA
;
        movf    MSD, w
        andlw   b'00001111'     ;maskiraj vije bite
        goto    DISPLAY_OUT
;
OSVEZI_TRETJEGA
;
        swapf   MSD, w
        andlw   b'00001111'
;
DISPLAY_OUT
;
        call    LED_TABELA      ;rezultat bo maska za doloèeno tevilko
        movwf   PORTB           ;polji na izhod
        movf    SINK, w         ;poièi sink vrednost
        movwf   PORTA           ;in jo polji na izhod
        return
;
LED_TABELA
;
        addwf   PCL, f
        retlw   b'00111111'     ;led drive za 0
        retlw   b'00000110'     ;1
        retlw   b'01011011'     ;2
        retlw   b'01001111'     ;3
        retlw   b'01100110'     ;4
        retlw   b'01101101'     ;5
        retlw   b'01111101'     ;6
        retlw   b'00000111'     ;7
        retlw   b'01111111'     ;8
        retlw   b'01100111'     ;9
;       	
        return
	
        end
Questions:
James Newton replies: The author is samo.benedicic@HIT.SI. Please contact him directly.
Would you please send me the English version of this code? I'm a beginner with PIC micros and it'll be easier for me to understand in English. Please email to chrisalick@gmail.com
Hello,
Can you send me the "English" version of this code? I have a few errors when I "Build" this code with "MPLAB." One of the errors is "RESET" not defined. Any ideas on this?
Thanks,
Tim
Hi, I need to measure the time elapsed between two signals. I generated the first signal and the second signal is its response. I'm trying to measure distance using an ultrasonic transducer. My first signal is the transmit pulse (INIT), I need to read the time elapsed between that and its recieved pulse(ECHO). I then divide this by 2 to give me my distance. If anyone can help me, I'd really appreciate it!
Comments:
I don't know if this is commercially available but a reasonably priced clock that measures the on time of an oil burner that has the ability to call the home heating oil dealer when a set elapsed time occurs so a delivery can be scheduled could be profitable. If a company wants to make 180 gallon oil deliveries to an account and the oil input is 1 gallon per hour, the clock could be set for 175-180 hours and would have to be reset by the oil driver or automatically. Maybe there can be a clock that measures multiple burners in a single location for a furnace and direct fired hot water heater for example. I am surprised at the difficulty of finding a device like this. Maybe I am not looking in the right places. Low level alarms for underground tanks are too expensive to make installations practical in most cases. I would appreciate a reply.
Carl Chapman
James Newton replies: How would you sense when the burner is on or off? Would a high temperature probe be required?
Seealso: