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 14:29, local time: 2024/11/17 11:44,
18.222.98.172:LOG IN
|
©2024 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://linistepper.com/techref/microchip/tacho.htm"> PIC Microcontoller IO Method - PIC Tachometer by Tony Nixon</A> |
Did you find what you needed? |