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: