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: