' ========================================================================= ' File....... milltach.SXB ' Purpose.... Display optical RPM reading to 4 element matrix'd 7led display ' 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. ' ' 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 5_000_000 ID "MILLTACH" ' -----[ I/O Definitions ]------------------------------------------------- Sensor PIN RB.0 INPUT SCHMITT INTR_RISE '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 'wanna be local variables tmpW1 VAR Word tmpW2 VAR Word tmpB1 VAR Byte tmpB2 VAR Byte pWidth0 VAR word ' Variable "pWidth0" will use the same memory space as variable "tmpW1". pWidth1 VAR tmpW2r ' Variable "pWidth1" will use the same memory space as variable "tmpW2". 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 WATCH pWidth0 WATCH Segs, 8, UBIN WATCH Digs, 4, UBIN WATCH dug, 8, UDEC ' ------------------------------------------------------------------------- ' Subroutine Declarations ' ------------------------------------------------------------------------- DELAY_MS SUB 1, 2 ' delay in milliseconds SHOW_DISPLAY SUB DIG FUNC 1, 2, 3 ' ========================================================================= PROGRAM Start ' ========================================================================= ' ------------------------------------------------------------------------- ' Program Code ' ------------------------------------------------------------------------- Start: ST_B = %00000001 ' make RB.1 schmitt triggered PLP_B = %00000001 ' pullup (1=up) unused pins Digs = %1110 ' rightmost digit ground on segs = %10000000 ' light up decimal point to show resets/etc DELAY_MS 1000 ' pause to show init/resets/brownouts/etc DO ' Measure pulse low time PULSIN Sensor, 0, pWidth0 ' Measure pulse high time PULSIN Sensor, 1, pWidth1 ' Find total pulse time (high + low) pWidth0 = pWidth0 + pWidth1 ' 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 SHOW_DISPLAY 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 pwidth0=10 'how many times to show rpm to display. I need to add banking, recycling this var for now, locals please god! pwidth0= pwidth0 << 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 pWidth0 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 BREAK 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 pWidth0 <= 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 ' -----[ 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