It's not that it's OK to "Be interrupted", but it's OK to be in the routine that does the interrupting.
PAUSEUS has a couple shortcomings. One, is that it uses PBP's system variables (R0-R8). So it corrupts PBP's flow if it's used in an ASM interrupt without "Instant Interrupts".
The second is that PAUSEUS has a minimum delay of around 24us @ 4mhz since it figures out the delay Count at run time.
The DelayUS macro can pause for a little as 1us by calculating the delay at Compile Time, and adding a single NOP if that's all that's needed. Or a 3cycle loop and 2 NOP's if running at 20mhz. And it doesn't use any PBP system vars.
It can be useful in other programs as well, so I'll show it here again for those that aren't as diligent as you Steve.Code:VP_DelayCount VAR WORD BANK0 ; Used for DelayUS only ASM ;----[Similar to PAUSEUS, but ASM interrupt compatible]---(accurate to 1uS)-- DelayUS macro T local InstCount, LoopCount, DelayLoop, LoopsDone, LeftOver, Offset ; -- Calculate number of 3 cycle loops plus leftover nop's to execute -- InstCount = ((OSC*10/4)*T+5)/10 ; Inst cycles required for delay (Rounded UP) LoopCount = InstCount / 3 if (LoopCount > 255) Offset = (LoopCount >> 8) * 7 + 4 else Offset = 0 endif ; -- Adjust for HighByte -- InstCount = InstCount - Offset if (Offset > (LoopCount & 0FFh)) InstCount = InstCount - 4 endif LoopCount = InstCount / 3 if (LoopCount > 255) Offset = (LoopCount >> 8) * 7 else Offset = 0 endif LeftOver = InstCount % 3 ;------------------------------------------- if (LoopCount > 0) MOVE?CW LoopCount, _VP_DelayCount DelayLoop decfsz _VP_DelayCount, F ; 1 goto DelayLoop ; 2 3 per loop, under 256 if (LoopCount > 255) movf _VP_DelayCount + 1, W ; 1 btfsc STATUS, Z ; 1 goto LoopsDone ; 2 4 on last loop decf _VP_DelayCount + 1, F ; 1 goto DelayLoop ; 2 7 per highbyte count LoopsDone endif endif if (LeftOver > 0) nop endif if (LeftOver > 1) nop endif endm ENDASM




Bookmarks