By Tony Nixon [sales at bubblesoftonline.com]
Here is a quick tacho program I just whipped up.
The IRQ is based on a 100uS TMR0 overflow. It is responsible for points status, rpm counting, and display updates The main loop calculates the new display data based on the 100uS count value.
Enter your cylinders in the space shown.
You will have to write you own display multiplex code in the IRQ routine. Only digits A, B and C are used and digit D = '0' always.
include "P16f873.inc"
CBLOCK 0x20
nratorH
nratorM
nratorL
denomH
denomM
denomL
remainH
remainM
remainL
shiftH
shiftM
shiftL
numahi
numalo
rsltal
rsltah
rsltbh
rsltbl
LoopCt
temp
debounce
flag1
dispA
dispB
dispC
holdA
holdB
holdC
loopsH
loopsM
loopsL
DispCnt
W_hold
S_hold
ENDC
; Xtal = 8MHz
p_stat equ 0h ; points STATUS flag
u_range equ 1h ; RPM under range
do_div equ 2h ; do division routine
n_disp equ 3h ; new display data available
Points equ 0h ; portA,0
Cylinders = 1 ; set engine cylinders
;
; CALCULATIONS BASED ON
; RPM = 927C0 / 100uS LOOPS
;
RPMconst = 927C0h / Cylinders
rpm_H = Upper(RPMconst)
rpm_M = High(RPMconst & 0xFFFF)
rpm_L = RPMconst & 0xFF
org 0h
goto start
org 4h
IRQvec movwf W_hold
swapf STATUS,W
movwf S_hold
bcf INTCON,T0IF
movlw 0xA0
movwf TMR0
bsf flag1,do_div ; flag do division routine
movf debounce ; test points only if debounce = 0
btfsc STATUS,Z
goto ChkPts
decf debounce
goto Inc_Cnt ; increment RPM counters
ChkPts btfsc PORTA,Points ; test points
goto P_Shut
btfss flag1,p_stat
goto Inc_Cnt ; already flagged as open
bcf flag1,p_stat
movlw 8h
movwf debounce
movf loopsH,W ; prepare for calculations
movwf denomH
movf loopsM,W
movwf denomM
movf loopsL,W
movwf denomL
clrf loopsH
clrf loopsM
clrf loopsL
bsf flag1,do_div ; flag do division routine
bcf flag1,u_range
goto Exirq
P_Shut btfsc flag1,p_stat
goto Inc_Cnt ; already flagged as shut
bsf flag1,p_stat
movlw 8h
movwf debounce
Inc_Cnt btfsc flag1,u_range ; increment if under max count
goto Exirq
incfsz loopsL
goto Udt_Disp
incf loopsM
goto Udt_Disp
incf loopsH
movlw 0ah ; if = ah then RPM is < 1
xorwf loopsH,W
btfsc STATUS,Z
bsf flag1,u_range
;
; ROUTINE TO UPDATE 3 x 7 SEG DISPLAYS
; DISPLAY 4 = PERMANANT 0
;
Udt_Disp decfsz DispCnt ; update every 100th second
goto Exirq
movlw d'100'
movwf DispCnt
btfss flag1,n_disp
goto Olddata
movf holdA,W
movwf dispA
movf holdB,W
movwf dispB
movf holdC,W
movwf dispB
bcf flag1,n_disp
; update display code here
Olddata
Exirq swapf S_hold,W
movwf STATUS
swapf W_hold
swapf W_hold,W
retfie
;
; DIGIT A
; A = RB0
; B = RB1
; C = RB2
; D = RB3
; E = RB4
; F = RB5
; G = RB6
;
Nib_7seg addwf PCL
retlw b'00111111' ; 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'01101111' ; 9
; SETUP A 100uS LOOP
start bsf STATUS,RP0
movlw b'00000000'
movwf OPTION_REG
bcf STATUS,RP0
clrf flag1
clrf dispA
clrf dispB
clrf dispC
clrf loopsH
clrf loopsM
clrf loopsL
movlw d'100'
movwf DispCnt
bsf INTCON,T0IE ; enable TMR0 IRQ
bsf INTCON,GIE
MnLoop btfss flag1,do_div
goto MnLoop
bcf flag1,do_div
movlw rpm_H ; calculate RPM for display
movwf nratorH
movlw rpm_M
movwf nratorM
movlw rpm_L
movwf nratorL
call divizn ; update display data
movf nratorM,W
movwf numahi
movf nratorL,W
movwf numalo
call HexBCD ; result is returned in rsltbl, rsltah, and rsltal
swapf rsltah,W
andlw 0Fh
call Nib_7seg ; bcd to 7 seg
movwf holdA
movf rsltah,W
andlw 0Fh
call Nib_7seg ; bcd to 7 seg
movwf holdB
swapf rsltal,W
andlw 0Fh
call Nib_7seg ; bcd to 7 seg
movwf holdC
bsf flag1,n_disp ; flag new display data available
goto MnLoop
;
; ------------------------------------------
; SUBROUTINE - 24 BIT DIVISION
; numerator: nratorH nratorM nratorL
; denominator: denomH denomM denomL
;
; result: nratorH nratorM nratorL
; remainder: remainH remainM remainL
;
divizn movlw .24
movwf temp
movf nratorH,w
movwf shiftH
movf nratorM,w
movwf shiftM
movf nratorL,w
movwf shiftL
clrf nratorH
clrf nratorM
clrf nratorL
;
clrf remainH
clrf remainM
clrf remainL
dloop bcf STATUS,C
rlf shiftL
rlf shiftM
rlf shiftH
rlf remainL
rlf remainM
rlf remainH
movf denomH,w
subwf remainH,w
btfss STATUS,Z
goto nochk
;
movf denomM,w
subwf remainM,w
btfss STATUS,Z
goto nochk
;
movf denomL,w
subwf remainL,w
nochk btfss STATUS,C
goto nogo
;
movf denomL,w
subwf remainL
btfss STATUS,C
decf remainM
movf remainM,w
xorlw 0xff
btfsc STATUS,Z
decf remainH
movf denomM,w
subwf remainM
btfss STATUS,C
decf remainH
movf denomH,w
subwf remainH
bsf STATUS,C
nogo rlf nratorL
rlf nratorM
rlf nratorH
decfsz temp
goto dloop
;
return
;
; ----------------------------------------------
; SUBROUTINE: CONVERT A NUMBER FROM HEX TO BCD
; 16 bit number to convert is in numahi, numalo
; result is returned in rsltbl, rsltah, and rsltal
;
HexBCD bcf STATUS,C
movlw .16
movwf temp
clrf rsltbl
clrf rsltah
clrf rsltal
;
loop16 rlf numalo
rlf numahi
rlf rsltal
rlf rsltah
rlf rsltbl
;
decfsz temp
goto adjDEC
return
;
adjDEC movlw rsltal
movwf FSR
call adjBCD
movlw rsltah
movwf FSR
call adjBCD
movlw rsltbl
movwf FSR
call adjBCD
goto loop16
;
adjBCD movlw .3
addwf INDF,w
movwf rsltbh ; temp storage
btfsc rsltbh,3
movwf INDF
movlw 30h
addwf INDF,w
movwf rsltbh
btfsc rsltbh,7
movwf INDF
return
end
Questions:
See also:
See:
| file: /Techref/microchip/tacho.htm, 9KB, , updated: 2008/10/21 15:29, local time: 2025/10/23 19:40,
216.73.216.53,10-2-207-162:LOG IN
|
| ©2025 These pages are served without commercial sponsorship. (No popup ads, etc...).Bandwidth abuse increases hosting cost forcing sponsorship or shutdown. This server aggressively defends against automated copying for any reason including offline viewing, duplication, etc... Please respect this requirement and DO NOT RIP THIS SITE. Questions? <A HREF="http://techref.massmind.org/techref/microchip/tacho.htm"> PIC Microcontoller IO Method - PIC Tachometer by Tony Nixon</A> |
| Did you find what you needed? |
Welcome to massmind.org! |
|
The Backwoods Guide to Computer Lingo |
.