' ========================================================================= ' File....... milltach_isr.SXB ' Purpose.... Display optical RPM reading to 4 element matrix'd 7led display using ISR ' Author..... David Mcanulty ' E-mail..... dave000@hellspark.com ' Started.... NOV 2007 ' Updated.... NOV 14 2007 pre-bells and whistles edition ' ========================================================================= ' -----[ Program Description ]--------------------------------------------- ' This program is designed to read via rb.0 (schmitt triggered) pulses from ' An IR reciever that are being reflected off a spinning spindle of a micro ' milling machine. Its modified to use an ISR to display. ' ' Eventually i want to add a EEPROM to store diffrent rpm rates. I'd also ' Like to experemint with running this via a battery and "sleep" the SX '------{ Device Settings ]------------------------------------------------- DEVICE SX28,TURBO,BANKS8,OSCHS3,SYNC,OPTIONX FREQ 50_000_000 ID "MILLTACH" ' -----[ I/O Definitions ]------------------------------------------------- Sensor PIN RB.0 INPUT SCHMITT '7 segment display vars Segs PIN RC OUTPUT ' Segments on RC.0 - RC.7 Digs PIN RA OUTPUT ' Digit control pins (gnd) ' -----[ Constants ]------------------------------------------------------- Blank CON %00000000 ' all segments off ' -----[ Variables ]------------------------------------------------------- ' have room for 3 more words ' tach vars rpm VAR WORD dividendMSW VAR WORD dividendLSW VAR WORD 'combine these into 2 vars pWidth0 VAR word pWidth1 VAR word pov VAR WORD 'wanna be local variables tmpW1 VAR Word tmpW2 VAR Word tmpB1 VAR Byte tmpB2 VAR Byte flags VAR Byte isrFlag VAR flags.0 Tach_Array VAR BYTE(16) ' Create a 16-byte array to hold tach variables. overflow VAR Tach_Array(0).0 'Uses byte 0, bit 0 of Tach_Array. doneBit VAR Tach_Array(0).1 'Uses byte 0, bit 1 of Tach_Array. theDig VAR Tach_Array(1) 'Uses byte 1 of Tach_Array. dug VAR Tach_Array(2) 'Uses byte 2 of Tach_Array. ' Watch statements for debuging WATCH rpm, 16, UDEC WATCH pWidth0, 16, UDEC WATCH pWidth1, 16, UDEC watch pov, 16, UDEC WATCH Segs, 8, UBIN WATCH Digs, 4, UBIN WATCH dug, 8, UDEC INTERRUPT NOCODE 50_000 ISR_Start: GOTO Int_Start ' ------------------------------------------------------------------------- ' Subroutine Declarations ' ------------------------------------------------------------------------- HIGHTIME FUNC 1 LOWTIME FUNC 1 DELAY_MS SUB 1, 2 ' delay in milliseconds SHOW_DISPLAY SUB DIG FUNC 1, 2, 3 Int_Start: \ SETB isrFlag 'SHOW_DISPLAY RETURNINT ISR_Exit: RETURNINT ' ========================================================================= ' ------------------------------------------------------------------------- ' Program Code ' ------------------------------------------------------------------------- ' ========================================================================= PROGRAM Start ' ========================================================================= Start: Digs = %1110 ' rightmost digit ground on segs = %10000000 ' light up decimal point to show resets/etc DO ' Measure pulse low time pWidth0 = LOWTIME ' Measure pulse high time pWidth1 = HIGHTIME ' Find total pulse time (high + low) pov = pWidth0 + pWidth1 rpm = pov break ' Set dividend to 6,000,000 ($5B8D80) this many 10u/seconds in a minute dividendMSW = $005B dividendLSW = $8D80 ' Perform 32 bit division (rpm = dividend / pWidth0) rpm = 1 overflow = 0 DO doneBit = rpm.15 rpm = rpm << 1 IF overflow = 1 THEN rpm.0 = 1 dividendMSW = dividendMSW - pWidth0 ELSE IF dividendMSW >= pWidth0 THEN rpm.0 = 1 dividendMSW = dividendMSW - pWidth0 ENDIF ENDIF overflow = dividendMSW.15 dividendMSW = dividendMSW << 1 dividendMSW.0 = dividendLSW.15 dividendLSW = dividendLSW << 1 LOOP UNTIL doneBit = 1 rpm = rpm << 1 rpm.0 = overflow IF dividendMSW >= pWidth0 THEN rpm.0 = 1 ENDIF ' rpm now holds the correct value the ISR will print it LOOP END ' ------------------------------------------------------------------------- ' Subroutine Code ' ------------------------------------------------------------------------- 'use: DELAY_MS msecs SUB DELAY_MS IF __PARAMCNT = 1 THEN tmpW1 = __PARAM1 ' save byte value ELSE tmpW1 = __WPARAM12 ' save word value ENDIF PAUSE tmpW1 RETURN ENDSUB 'takes no input (rpm is global) SUB SHOW_DISPLAY 'Reminder, i'm calling DIG and DELAY in here, so tmpW1-2 and tmpB1-2 are off limits! 'Don't get fancy and try to pass the loop number in using those "local" vars pov=10 'how many times to show rpm to display. I need to add banking, recycling this var for now, locals please god! pov= pov << 2 '(<< 2 is just *4)this number has to be a multiple of 4 since we need to loop 4 times to get 4 digits DO Dec pov READ DigSel + theDig, Digs ' select digit column number (theDig) from Digs dug = DIG rpm, theDig ' get the digit in rpm we are about to lookup and draw READ Digit0 + dug, Segs ' move digit drawing DATA pattern to segs pins inc theDig ' Update the, theDig = theDig // 4 ' ,digit column pointer DELAY_MS 5 'how long to light each singular digit (POV) Segs = Blank 'clear the gnds or we will light up the next digit column before we are ready LOOP UNTIL pov <= 0 RETURN ENDSUB ' Use: result = DIG value, position ' -- "value" is byte or word ' -- "position" is byte, 0 to 4 FUNC DIG IF __PARAMCNT = 2 THEN tmpW1 = __PARAM1 tmpB1 = __PARAM2 ELSE tmpW1 = __WPARAM12 tmpB1 = __PARAM3 ENDIF tmpB2 = 0 IF tmpB1 < 4 THEN LOOKUP tmpB1, 1, 10, 100, 1000, tmpW2 tmpW1 = tmpW1 / tmpW2 tmpW1 = tmpW1 // 10 tmpB2 = tmpW1_LSB ENDIF RETURN tmpB2 ENDFUNC FUNC LOWTIME PWidth0 = 0 \ JNB Sensor, @$ ' let low clear \ JB Sensor, @$ ' let old high clear DO \ CLRB isrFlag ' clear old ISR marker \ JNB isrFlag, @$ ' wait for new marker INC PWidth0 IF PWidth0 = 0 THEN EXIT LOOP UNTIL Sensor = 1 RETURN PWidth0 ENDFUNC FUNC HIGHTIME PWidth1 = 0 \ JB Sensor, @$ ' let old high clear \ JNB Sensor, @$ ' let low clear DO \ CLRB isrFlag ' clear old ISR marker \ JNB isrFlag, @$ ' wait for new marker INC PWidth1 IF PWidth1 = 0 THEN EXIT LOOP UNTIL Sensor = 0 RETURN PWidth1 ENDFUNC ' -----[ Data ]----------------------------------------------------- ' %.GFEDCBA Digit0: DATA %00111111 Digit1: DATA %00000110 Digit2: DATA %01011011 Digit3: DATA %01001111 Digit4: DATA %01100110 Digit5: DATA %01101101 Digit6: DATA %01111101 Digit7: DATA %00000111 Digit8: DATA %01111111 Digit9: DATA %01100111 DigSel: DATA %1110 ' digit 0 active DATA %1101 ' digit 1 active DATA %1011 ' digit 2 active DATA %0111 ' digit 3 active