'+-------------------------------------------------------------------------+ '* _____ _ _____ _ * '* / __ \ | | |_ _(_) * '* | / \/ ___ __| | ___ | | _ _ __ ___ ___ _ __ * '* | | / _ \ / _` |/ _ \ | | | | '_ ` _ \ / _ \ '__| * '* | \__/\ (_) | (_| | __/ | | | | | | | | | __/ | * '* \____/\___/ \__,_|\___| \_/ |_|_| |_| |_|\___|_| * '* * '* __ __________________ * '* / _| | ___ \ ___ \ ___ \ * '* | |_ ___ _ __ | |_/ / |_/ / |_/ / * '* | _/ _ \| '__| | __/| ___ \ __/ * '* | || (_) | | | | | |_/ / | * '* |_| \___/|_| \_| \____/\_| * '* * '+-------------------------------------------------------------------------+ '|Name : CodeTimer.bas | '|Author : Steve Burrow | '|Date : 09/13/2006 | '|Version: 1.2.3d | '|Notes : This allows for the timing of PBP code routines for the PIC18 | '| series. There are two methods of use. One simply times any | '| block of code (or multiple blocks of code). The other uses | '| PIC BASIC Pro's built in DEBUG function to time individual | '| PBP commands. | '| (Although not tested, it will probably work with some PIC16s.) | '+-------------------------------------------------------------------------+ '*************************************************************************** '* Special thanks to Darrel Taylor (www.darreltaylor.com). It was his * '* code that was the seed for this project. He also provided important * '* answers and help directly. Additionally, it was through careful study * '* of his projects that I was able to learn what I needed to put this * '* together. * '*************************************************************************** '+-------------------------------------------------------------------------+ '| IMPORTANT!!! | '| | '| This module operates using the HSEROUT command. | '| THE HARDWARE SERIAL PORT MUST BE CONFIGURED SEPERATELY. | '| | '| If this is not desirable, the HSEROUT commands in this module can be | '| replaced by another command (such as "SEROUT pin, mode,"), by using | '| using search/replace. | '| DO NOT change the code inside the brackets of these commands!!! | '+-------------------------------------------------------------------------+ '| Other Important notes about Code Timer: | '| | '| * There will sometimes be unavoidable rounding errors (like with OSC | '| values 12, 24, 33 and 48) in calculating the period of each timer- | '| tick. The routines have been designed to help minimize these | '| errors as much as possible. | '| | '| * Steps 3) and 4) below can be used multiple times to time any | '| number of code sections, outputing the results for each. | '| | '| * Code Timer will increase the code size of your project | '| | '| * If an overflow of the timer occurs (indicated by a 1 in the | '| output text "Overflow:") the timing result will not be valid. | '| Select a higher prescale value. | '| | '| * The higher the prescale, the less accurate the timing will be. | '| So select the smallest prescale possible that will not overflow. | '| | '| * Due to the nature of PBP commands, there is the possibility that | '| some of the commands will not alway use the same number of | '| instruction cycles to complete a task. So, You are likely to see | '| some variablility, and should keep this in mind if trying to do | '| anything which relies on critical timing (which should probably | '| be handled in an interrupt). | '+-------------------------------------------------------------------------+ ' ___ _ _ _ | ' |_ _|_ __ ___| |_ _ __ _ _ ___| |_(_) ___ _ __ ___ | ' | || '_ \/ __| __| '__| | | |/ __| __| |/ _ \| '_ \/ __| | ' | || | | \__ \ |_| | | |_| | (__| |_| | (_) | | | \__ \ | ' |___|_| |_|___/\__|_| \__,_|\___|\__|_|\___/|_| |_|___/ | ' | '+-------------------------------------------------------------------------+ '| | '| (----------------------------------------------) | '| | /------------------------------------------\ | | '| | | TIMING BLOCKS OF CODE | | | '| | \------------------------------------------/ | | '| (----------------------------------------------) | '| | '| 1) Add an INCLUDE statement for this file | '| | '| INCLUDE "CodeTimer.bas" | '| | '| 2) Setup the timer with the following statement syntax: | '| | '| @ SETUP_CODE_TIMER tmr, ps | '| | '| Where tmr = Timer number (0-3) | '| ps = Valid Prescale Value (see below) | '| Timer0: 1,2,4,8,16,32,64,128,256 | '| Timer1: 1,2,4,8 | '| Timer2: 1,4,16 | '| Timer3: 1,2,4,8 | '| Examples: | '| @ SETUP_CODE_TIMER 0, 128 ; Timer0, Prescale 1:128 | '| | '| @ SETUP_CODE_TIMER 3, 1, ; Timer3, Prescale 1:1 | '| | '| 2b) If you have a separate clock source for the timer, you | '| can use the following DEFINE to set it for the Code Timer. | '| This must be typed exactly as shown. Add the appropriate | '| value in MHz. | '| | '| DEFINE CODETIMER_EXTCLK 10 ;10MHz clock for Timer | '| | '| 3) Place the following statement just PRIOR to the section of | '| code you want to time: | '| | '| @ START_CODE_TIMER | '| | '| 4) Place the following statement just AFTER to the section of | '| code you want to time: | '| | '| @ STOP_CODE_TIMER | '| | '|You will end up with output similar to: | '| | '| -------------------------- | '| Time: 15.0276 msec | '| Tick Period: 0.4 usec | '| Timer Ticks: 37569 | '| OSC Freq: 40 Mhz | '| Prescale: 4 | '| Overflow: 0 | '| -------------------------- | '| | '+-------------------------------------------------------------------------+ '| | '| (----------------------------------------------) | '| | /------------------------------------------\ | | '| | | USE PBP's DEBUG FUNCTION TO | | | '| | | TIME INDIVIDUAL PBP COMMANDS | | | '| | \------------------------------------------/ | | '| (----------------------------------------------) | '| | '| 1) Add an INCLUDE statement for this file | '| | '| INCLUDE "CodeTimer.bas" | '| | '| 2) Setup the timer with the following statement syntax: | '| | '| @ SETUP_CODE_TIMER_DEBUG trm | '| | '| Where tmr = Timer number (0-3) | '| | '| Examples: | '| @ SETUP_CODE_TIMER_DEBUG 0, ; Timer0 | '| | '| @ SETUP_CODE_TIMER_DEBUG 3, ; Timer3 | '| | '| 3) Place the following statement just PRIOR to the section of | '| code you want to time: | '| | '| @ START_CODE_TIMER_DEBUG | '| ENABLE DEBUG | '| | '| 4) Place the following statement just AFTER to the section of | '| code you want to time: | '| | '| @ STOP_CODE_TIMER_DEBUG | '| DISABLE DEBUG | '| | '|You will end up with output similar to: | '| | '| !!!!!!!!!!!!!!!!!!!!!!!!! | '| ------------------------- | '| Debug Addr: $5444 | '| Time: .0404 msec | '| Tick Period: 0.1 usec | '| Timer Ticks: 404 | '| OSC Freq: 40 Mhz | '| Prescale: 1 | '| Overflow: 0 | '| ------------------------- | '| ------------------------- | '| Debug Addr: $547A | '| Time: .0012 msec | '| Tick Period: 0.1 usec | '| Timer Ticks: 12 | '| OSC Freq: 40 Mhz | '| Prescale: 1 | '| Overflow: 0 | '| ------------------------- | '| ------------------------- | '| Debug Addr: $548A | '| Time: .0006 msec | '| Tick Period: 0.1 usec | '| Timer Ticks: 6 | '| OSC Freq: 40 Mhz | '| Prescale: 1 | '| Overflow: 0 | '| ------------------------- | '| Total Ticks: 422 | '| Time: .0422 msec | '| ^^^^^^^^^^^^^^^^^^^^^^^^^ | '| | '| This shows the timing results for 3 PBP commands. The starting | '| address for these commands is shown as "Debug Addr." At the | '| bottom, if the number of timer ticks was less than 65536, then it | '| will give you the Total Time of all the instructions. Otherwise, | '| it will only give the total number of timer ticks | '| | '|IMPORTANT NOTES ABOUT USING DEBUG: | '| * This code timer will not work with a prescale | '| or external timer clock. | '| | '| * Since PBP's DEBUG function add additional assembly instructions to | '| code, code size will increase, so it's advised to use only with | '| a small number of instructions. | '| | '| * There is some likelyhood the the number of ticks could actually be | '| slightly less than reported. This is due to PBP adding code for | '| the debug functions and it is not possible to predetermine the | '| exact number of instructions added. | '| | '+-------------------------------------------------------------------------+ ' Example Program For Timing Blocks of Code ' (config. fuses not included) '""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" ' ' DEFINE OSC 40 ' ' 'Setup for 115200 baud ' DEFINE HSER_RCSTA 90h ' Enable serial port & continuous receive ' DEFINE HSER_TXSTA 24h ' Enable transmit, BRGH = 1 ' DEFINE HSER_CLROERR 1 ' Clear overflow automatically ' DEFINE HSER_SPBRG 86 ' 86 = 115200 Baud @ -0.22% ' SPBRGH = 0 ' BAUDCON.3 = 1 ' Enable 16 bit baudrate generator ' ' INCLUDE "C:\PIC_code\MODULES\Code_Timer\CodeTimer.bas" ' @ SETUP_CODE_TIMER 0, 1 ' ' X VAR WORD ' y VAR WORD ' z VAR WORD ' x = 0 ' y = 123 ' z = 100 ' ' Main: ' ' HSEROUT [dec x,10,13] ' HSEROUT [dec y,10,13] ' HSEROUT [dec z,10,13] ' ' HSEROUT ["x = z * y",10,13] ' @ START_CODE_TIMER ' x = z * y ' @ STOP_CODE_TIMER ' HSEROUT[dec x,10,13] ' ' HSEROUT ["z = z / 2",10,13] ' @ START_CODE_TIMER ' z = z / 2 ' @ STOP_CODE_TIMER ' HSEROUT[dec z,10,13] ' ' HSEROUT ["y = x / z",10,13] ' @ START_CODE_TIMER ' y = x / z ' @ STOP_CODE_TIMER ' HSEROUT[dec y,10,13] ' ' HSEROUT ["Done!"] ' ' ALLDONE: ' GOTO ALLDONE ' ' END '+-------------------------------------------------------------------------+ ' ____ _ ____ _ ' | __ ) ___ __ _(_)_ __ / ___|___ __| | ___ ' | _ \ / _ \/ _` | | '_ \ | | / _ \ / _` |/ _ \ ' | |_) | __/ (_| | | | | | | |__| (_) | (_| | __/ ' |____/ \___|\__, |_|_| |_| \____\___/ \__,_|\___| ' |___/ '+-------------------------------------------------------------------------+ @ errorlevel -207 ;Hide "Warning[207]: Found label after column 1" ;Constants rep0 con EXT OSCFreq con EXT TPS con EXT Period con EXT ;Debug Constants Debug_Adjust con 10 Debug_Adjust_Last con 4 ;Variables Timer_Ticks Var Word TimeDivTemp var byte TimeH Var Word TimeL Var Word ;Timer Variables TOF var bit TXCON var byte EXT PIRX var byte EXT TMRXIF VAR BYTE EXT TMRXH VAR BYTE EXT TMRXL VAR BYTE EXT TMRXON VAR BYTE EXT ;Debug Variables DebugSkipFirst var bit DebugLast var bit DebugOutput var bit DEBUG_ADDRESS var word bankA system ' Program address Last_DEBUG_ADDRESS var word bankA system TotalTicks_Debug var WORD[2] TotalTicks_DebugH var TotalTicks_Debug(1) TotalTicks_DebugL var TotalTicks_Debug(0) ; Initialize Variables 'DebugRoutine = 0 DebugSkipFirst = 0 DebugLast = 0 DebugOutput = 0 TotalTicks_DebugH = 0 TotalTicks_DebugL = 0 Timer_Ticks = 0 goto endofshowtimeroutine ;------------------------------------------------------------------------------- ; CodeTimer Macros ;------------------------------------------------------------------------------- ;---=== Load a 32-bit (Dword) variable into ===--- ;---=== PBP registers, Prior to DIV32 ===--- Asm NOLIST PutMulResult?D macro Din MOVE?BB Din, R2 MOVE?BB Din + 1 , R2 + 1 MOVE?BB Din + 2, R0 MOVE?BB Din + 3, R0 + 1 RST?RP endm ;---=== Calculate time Macro ===--- CODETIMERDEBUG = 0 CALC_TIME? macro endasm timeH = Timer_Ticks * Period timeH = DIV32 10000 timeL = R2 asm endm ;---=== Find Number of Significant Digits Macro ===--- SIGNIFICANT_DIGITS? macro if (PER % 10000) == 0 EXPONENT -= 4 PER = PER / 10000 else if (PER % 1000) == 0 EXPONENT -= 3 PER = PER / 1000 else if (PER % 100) == 0 EXPONENT -= 2 PER = PER / 100 else if (PER % 10) == 0 EXPONENT -= 1 PER = PER / 10 endif endif endif endif if PER <= 9 SIGDIG = 1 else if PER <= 99 SIGDIG = 2 else if PER <= 999 SIGDIG = 3 else if PER <= 9999 SIGDIG = 4 else SIGDIG = 5 endif endif endif endif endm ;---=== Output the Tick Periods Macro ===--- OUTPUT_PERIOD? macro if EXPONENT == 6 if SIGDIG > 3 ENDASM hserout ["Tick Period: ",Dec Period/1000,".",Dec3 Period//1000," msec",13,10] asm else ENDASM hserout ["Tick Period: ",Dec Period," usec",13,10] asm endif endif if EXPONENT == 7 if SIGDIG > 1 ENDASM hserout ["Tick Period: ",Dec Period/10,".",Dec1 Period//10," usec",13,10] asm else ENDASM hserout ["Tick Period: 0.",Dec Period," usec",13,10] asm endif endif if EXPONENT == 8 if SIGDIG > 2 ENDASM hserout ["Tick Period: ",Dec Period/100,".",Dec2 Period//100," usec",13,10] asm else rep0 equ (2 - SIGDIG) ENDASM hserout ["Tick Period: 0.",rep "0"\rep0,Dec Period," usec",13,10] asm endif endif if EXPONENT == 9 if SIGDIG > 3 ENDASM hserout ["Tick Period: ",Dec Period/1000,".",Dec3 Period//1000," usec",13,10] asm else rep0 equ (3 - SIGDIG) ENDASM hserout ["Tick Period: 0.",rep "0"\rep0,Dec Period," usec",13,10] asm endif endif if EXPONENT == 10 if SIGDIG > 4 ENDASM hserout ["Tick Period: ",Dec Period/10000,".",Dec4 Period//10000," usec",13,10] asm else if SIGDIG < 4 ENDASM hserout ["Tick Period: ",Dec Period," nsec",13,10] asm else ENDASM hserout ["Tick Period: 0.",Dec Period," usec",13,10] asm endif endif endif if EXPONENT == 11 if SIGDIG > 2 ENDASM hserout ["Tick Period: ",Dec Period/100,".",Dec2 Period//100," nsec",13,10] asm else if SIGDIG < 2 ENDASM hserout ["Tick Period: ",Dec Period," nsec",13,10] asm else ENDASM hserout ["Tick Period: 0.",Dec Period," usec",13,10] asm endif endif endif endm ;---=== Output the total time Macro ===--- OUTPUT_TIME? macro endasm Output_Time: Hserout ["Time: "] @ if EXPONENT == 11 TimeDivTemp = TimeH/10000 if TimeDivTemp = 0 then Hserout [dec timeh/10,".",DEC1 timeh//10, Dec4 timel," u"] else Hserout [dec TimeDivTemp,".",DEC4 timeh//10000, Dec4 timel," m"] endif @ endif @ if EXPONENT == 10 if TimeH = 0 then Hserout ["0.", Dec4 timel," u"] else TimeDivTemp = TimeH/1000 if TimeDivTemp = 0 then Hserout [Dec timeH,".", Dec4 timel," u"] else Hserout [dec TimeDivTemp,".",DEC3 timeh//1000, Dec4 timel," m"] endif endif @ endif @ if EXPONENT == 9 if TimeH = 0 then Hserout [Dec1 timel/1000,".",Dec3 timel//1000," u"] else TimeDivTemp = TimeH/100 if TimeDivTemp = 0 then Hserout [dec timeh, Dec1 timel/1000,".",Dec3 timel//1000," u"] else Hserout [dec TimeDivTemp,".",DEC2 timeh//100, Dec4 timel," m"] endif endif @ endif @ if EXPONENT == 8 if TimeH = 0 then Hserout [Dec timel/100,".",Dec2 timel//100," u"] else TimeDivTemp = TimeH/10 if TimeDivTemp = 0 then Hserout [dec timeh, Dec2 timel/100,".",Dec2 timel//100," u"] else Hserout [dec TimeDivTemp,".",DEC1 timeh//10, Dec4 timel," m"] endif endif @ endif @ if EXPONENT == 7 if TimeH > 0 then Hserout [dec TimeH] Hserout [".",Dec4 timel," m"] else Hserout [DEC timel/10, ".",Dec1 timel//10," u"] endif @ endif @ if EXPONENT == 6 if TimeH = 0 then Hserout [Dec1 timel/1000,".",Dec3 timel//1000," m"] else TimeDivTemp = TimeH/100 if TimeDivTemp = 0 then Hserout [dec timeh, Dec1 timel/1000,".",Dec3 timel//1000," m"] else Hserout [dec TimeDivTemp,".",DEC2 timeh//100, Dec4 timel," "] endif endif @ endif hserout ["sec",13,10] if DebugOutput = 1 then return asm endm ;---=== Setup Macro ===--- SETUP_CODE_TIMER macro TMR, PS OSCD = 0 ifdef CODETIMER_EXTCLK if (TMR == 2) error Timer 2 Cannot Use an External Clock endif OSCFreq equ CODETIMER_EXTCLK OSCFRQ = CODETIMER_EXTCLK else OSCFreq equ OSC OSCFRQ = OSC endif if TMR == 0 if (PS == 256) || (PS == 128) || (PS == 64) || (PS == 32) || (PS == 16) || (PS == 8) || (PS == 4) || (PS == 2) || (PS == 1) TXCON = T0CON PIRX = INTCON TMRXIF = TMR0IF TMRXH = TMR0H TMRXL = TMR0L TMRXON = TMR0ON if (PS == 256) MOVE?CB 007h, TXCON TPS EQU 00100h ;TMR0 Prescale 256 endif if (PS == 128) MOVE?CB 006h, TXCON TPS EQU 00080h ;TMR0 Prescale 128 endif if (PS == 64) MOVE?CB 005h, TXCON TPS EQU 00040h ;TMR0 Prescale 64 endif if (PS == 32) MOVE?CB 004h, TXCON TPS EQU 00020h ;TMR0 Prescale 32 endif if (PS == 16) MOVE?CB 003h, TXCON TPS EQU 00010h ;TMR0 Prescale 16 endif if (PS == 8) MOVE?CB 002h, TXCON TPS EQU 00008h ;TMR0 Prescale 8 endif if (PS == 4) MOVE?CB 001h, TXCON TPS EQU 00004h ;TMR0 Prescale 4 endif if (PS == 2) MOVE?CB 000h, TXCON TPS EQU 00002h ;TMR0 Prescale 2 endif if (PS == 1) MOVE?CB 008h, TXCON TPS EQU 00001h ;TMR0 Prescale 1 endif ifdef CODETIMER_EXTCLK bsf TXCON, T0CS OSCD = 1 else bcf TXCON, T0CS OSCD = 4 endif else error PS not valid prescale value for Timer0 (256,128,64,32,16,8,4,2,1) endif endif if (TMR == 1) if (PS == 8) || (PS == 4) || (PS == 2) || (PS == 1) TXCON = T1CON PIRX = PIR1 TMRXIF = TMR1IF TMRXH = TMR1H TMRXL = TMR1L TMRXON = TMR1ON if (PS == 8) MOVE?CB 030h, TXCON TPS EQU 00008h ;TMR0 Prescale 8 endif if (PS == 4) MOVE?CB 020h, TXCON TPS EQU 00004h ;TMR0 Prescale 4 endif if (PS == 2) MOVE?CB 010h, TXCON TPS EQU 00002h ;TMR0 Prescale 2 endif if (PS == 1) MOVE?CB 000h, TXCON TPS EQU 00001h ;TMR0 Prescale 1 endif ifdef CODETIMER_EXTCLK bsf TXCON, TMR1CS bsf TXCON, T1SYNC OSCD = 1 else bcf TXCON, TMR1CS bcf TXCON, T1SYNC OSCD = 4 endif else error PS not valid prescale value for Timer1 (8,4,2,1) endif endif if (TMR == 3) if (PS == 8) || (PS == 4) || (PS == 2) || (PS == 1) TXCON = T3CON PIRX = PIR2 TMRXIF = TMR3IF TMRXH = TMR3H TMRXL = TMR3L TMRXON = TMR3ON if (PS == 8) MOVE?CB 030h, TXCON TPS EQU 00008h ;TMR0 Prescale 8 endif if (PS == 4) MOVE?CB 020h, TXCON TPS EQU 00004h ;TMR0 Prescale 4 endif if (PS == 2) MOVE?CB 010h, TXCON TPS EQU 00002h ;TMR0 Prescale 2 endif if (PS == 1) MOVE?CB 000h, TXCON TPS EQU 00001h ;TMR0 Prescale 1 endif ifdef CODETIMER_EXTCLK bsf TXCON, TMR3CS bsf TXCON, T3SYNC OSCD = 1 else bcf TXCON, TMR3CS bcf TXCON, T3SYNC OSCD = 4 endif else error PS not valid prescale value for Timer3 (8,4,2,1) endif endif if (TMR == 2) if (PS == 16) || (PS == 4) || (PS == 1) TXCON = T2CON PIRX = PIR1 TMRXIF = TMR2IF TMRXH = TMR2H TMRXL = TMR2L TMRXON = TMR2ON OSCD = 4 if (PS == 16) MOVE?CB 002h, TXCON TPS EQU 00010h ;TMR0 Prescale 16 endif if (PS == 4) MOVE?CB 001h, TXCON TPS EQU 00004h ;TMR0 Prescale 4 endif if (PS == 1) MOVE?CB 000h, TXCON TPS EQU 00001h ;TMR0 Prescale 1 endif else error PS not valid prescale value for Timer2 (16,4,1) endif endif if ((( OSCD * 100000 ) / OSCFRQ ) * PS ) < 32768 EXPONENT = 11 PER = (((OSCD*100000)/OSCFRQ)*PS) else if ((( OSCD * 10000 ) / OSCFRQ ) * PS ) < 32768 EXPONENT = 10 PER = (((OSCD*100000)/OSCFRQ)*PS)/10 else if ((( OSCD * 1000 ) / OSCFRQ ) * PS ) < 32768 EXPONENT = 9 PER = (((OSCD*100000)/OSCFRQ)*PS)/100 else if ((( OSCD * 100 ) / OSCFRQ ) * PS ) < 32768 EXPONENT = 8 PER = (((OSCD*100000)/OSCFRQ)*PS)/1000 else EXPONENT = 7 PER = (((OSCD*100000)/OSCFRQ)*PS)/10000 endif endif endif endif SIGNIFICANT_DIGITS? Period EQU PER local OverCode goto Overcode LIST endasm ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ; ; These Routines are added when the setup macro is invoked but ; are not executed until called at runtime. ; ShowCdTmr: hserout [rep "-"\25,13,10] @ MOVE?TT PIRX, TMRXIF, _TOF ; copy overflow bit to TOF Timer_Ticks.lowbyte = TMRXL Timer_Ticks.highbyte = TMRXH @ if CODETIMERDEBUG == 1 Hserout ["Debug Addr: ",ihex Last_DEBUG_ADDRESS, 13,10] ' Display program address ;adjust for added intructions if DebugLast = 0 then Timer_Ticks = Timer_Ticks - Debug_Adjust else Timer_Ticks = Timer_Ticks - Debug_Adjust_Last endif TotalTicks_DebugL = TotalTicks_DebugL + Timer_Ticks @ btfss STATUS, C @ goto _TTD_No_Carry TotalTicks_DebugH = TotalTicks_DebugH + 1 TTD_No_Carry: @ else Timer_Ticks = Timer_Ticks + 1 @ endif asm CALC_TIME? OUTPUT_TIME? OUTPUT_PERIOD? endasm Hserout ["Timer Ticks: ",Dec Timer_Ticks,13,10] hserout ["OSC Freq: ",dec OSCFreq," Mhz",13,10] hserout ["Prescale: ",dec TPS,13,10] hserout ["Overflow: ",dec TOF] hserout [13,10,rep "-"\25,13,10] Return CODE_TIMER_DEBUG: @ bcf TXCON, TMRXON ; Code Timer Stop ;flag as debug if DebugSkipFirst = 1 then gosub showcdtmr else DebugSkipFirst = 1 endif Last_DEBUG_ADDRESS = DEBUG_ADDRESS TMRXH = 0 ; Clear Timer TMRXL = 0 asm bcf PIRX, TMRXIF ; Clear Interrupt/Overflow bit bsf TXCON, TMRXON ; Code Timer Start ; End of debug monitor routine - go back to main program movf DEBUG_ADDRESS + 1, W ; Set PCLATH with top byte of return address movwf PCLATH movf DEBUG_ADDRESS, W ; Go back to main program movwf PCL endasm ;%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% asm errorlevel +207 ;Restore "Warning[207]: Found label after column 1" Overcode endm ;---=== Debug Setup Macro ===--- SETUP_CODE_TIMER_DEBUG macro TMRD;, PSD CODETIMERDEBUG = 1 ifdef CODETIMER_EXTCLK error You can not use an external clock with DEBUG endif endasm TotalTicks_DebugH = 0 TotalTicks_DebugL = 0 Timer_Ticks = 0 ON DEBUG GOTO CODE_TIMER_DEBUG DISABLE DEBUG asm SETUP_CODE_TIMER TMRD, 1;PSD endm ;------------------------------------------------------------------------------- ; Macros to START and STOP CodeTimer ; ;---=== Start Macro ===--- START_CODE_TIMER macro endasm TMRXH = 0 ; Clear Timer TMRXL = 0 asm bcf PIRX, TMRXIF ; Clear Interrupt/Overflow bit bsf TXCON, TMRXON ; Code Timer Start endm ;---=== Stop Macro ===--- STOP_CODE_TIMER macro bcf TXCON, TMRXON ; Code Timer Stop endasm gosub showcdtmr asm endm ;---=== Debug Start Macro ===--- START_CODE_TIMER_DEBUG macro endasm DebugOutput = 0 DebugSkipFirst = 0 DebugLast = 0 TMRXH = 0 ; Clear Timer TMRXL = 0 hserout [13,10,10,rep "_"\25,13,10," Begin DEBUG Code Timmer",13,10] asm bcf PIRX, TMRXIF ; Clear Interrupt/Overflow bit bsf TXCON, TMRXON ; Code Timer Start endm ;---=== Debug Stop Macro ===--- STOP_CODE_TIMER_DEBUG macro bcf TXCON, TMRXON ; Code Timer Stop endasm if DebugSkipFirst = 1 then DebugLast = 1 gosub showcdtmr DebugSkipFirst = 0 hserout ["Total Ticks: "] if TotalTicks_DebugH > 0 then @ PutMulResult?D _TotalTicks_Debug TotalTicks_DebugH = DIV32 10000 TotalTicks_DebugL = R2 hserout [DEC TotalTicks_DebugH, dec4 TotalTicks_DebugL,13,10] else hserout [DEC TotalTicks_Debug,13,10] Timer_Ticks = TotalTicks_Debug @ CALC_TIME? DebugOutput = 1 gosub Output_Time endif Else hserout [rep "!"\25,13,10," No Instructions between",10,13," START and STOP!!!",13,10] endif hserout [rep "^"\25,13,10,10] TotalTicks_DebugH = 0 TotalTicks_DebugL = 0 Timer_Ticks = 0 @ endm ;------------------------------------------------------------------------------- endofshowtimeroutine: