Hi Ken and all: >I have a project that I am about to start that requires some accurate timing >loops of odd lenghts. There is a basic program on the microchip BBS that will >generate the code for any lenght loop you need, but I also need to check for >some buttons being pressed while the loop is being exacuted. The program AW.BAS >does not do anything in the main loop and I can't see how to modify it to >include extra instruction. I use some ASM macros, to do this tasks: DELAY n DELAYV n,r TIMEP n,m TIMEP_ l .- The DELAY macro generates inline code, to "eat" N cycles, using *to* four registers (CNT1 to CNT1+3), as need. .- The DELAYV macro perfoms same as DELAY but the used register can be specified, as R. .- The TIMEP macro executes following statements, to macro TIMEP_, totalizing M cycles, and finish after N cycles. .- The TIMEP_ macro delimits the statements to be repeated during the N processor cycles. .- The ADJST and ADJUST macros are used internaly, to fine tuning the timings using NOP's. (N,M can be any valid ASM expresion) I wrote this macros for old MPALC assembler and adapted its this year for MPASM, to avoid problems with the limited line length (worse on MPASM!!!). Regretably, this code don't work on old MPALC as the simbols on it only retain 16 bit values. Example #1: Generate code to wait 1 second, using 4 MHz oscillator: DELAY 1000000 Example #2: Wait "1" on RA0 pin, timeout after 1 mSec. (same clock as previus) TIMEP 1000,2 ; Test RA0 pin, waiting "1" test1 btfsc ra,0 goto done TIMEP_ test1 goto tout ; Timeout ocurred... done ------------ DELAY.MAC ---------------------------------------------- ; In_line delay macros for PIC ; Written by Roberto Deza, 9 Jul 1993 ; Permission granted for all non-commercial use. adjust macro cyc if cyc > 0 nop adjust cyc-1 endif endm delayv macro cyc,var local loop1,loop2,loop3 if simul == 0 if ((cyc-1)/3) <= .256 if ((cyc-1)/3) > 0 movlw (cyc-1)/3 movwf var adjust ((cyc-1)%3) loop1 decfsz var goto loop1 else adjust (cyc) endif else if ((cyc+.765)/.770) <= .256 movlw (cyc+.765)/.770 movwf var movlw ((cyc+.765)%.770)/3 movwf var+1 adjust (((cyc+.765)%.770)%3) loop2 decfsz var+1 goto loop2 decfsz var goto loop2 else if ((cyc+0x304FB)/0x30202) <= .256 movlw (cyc+0x304FB)/0x30202 movwf var movlw ((cyc+0x304FB)%0x30202)/.770 movwf var+1 movlw (((cyc+0x304FB)%0x30202)%.770)/.3 movwf var+2 adjust ((((cyc+0x304FB)%0x30202)%.770)%.3) loop3 decfsz var+2 goto loop3 decfsz var+1 goto loop3 decfsz var goto loop3 else error "Delay too big..." endif endif endif endif endm delay macro cyc delayv cyc,cnt1 endm adjst macro cyc if cyc > 4 delay cyc else adjust cyc endif endm timep macro cyc,pro if ((cyc-1) / (pro+3)) <= .256 adjst ((cyc-1) % (pro+3)) movlw (cyc-1) / (pro+3) movwf cnt1 timep@ set 1 else timep@1 set cyc + 0x2FD + 0x100*pro timep@2 set 0x100*pro + 0x302 if (timep@1 / timep@2) <= .256 adjst ((timep@1 % timep@2) % (pro+3)) movlw timep@1 / timep@2 movwf cnt1 movlw (timep@1 % timep@2) / (pro+3) movwf cnt2 timep@ set 2 else timep@1 set (cyc + 0x304FB + 0x10100*pro) timep@2 set (0x30202 + 0x10000*pro) timep@3 set (0x302 + 0x100*pro) if (timep@1 / timep@2) <= 0x100 adjst (((timep@1 % timep@2) % timep@3) % (3+pro)) movlw timep@1 / timep@2 movwf cnt1 movlw (timep@1 % timep@2) / timep@3 movwf cnt2 movlw ((timep@1 % timep@2) % timep@3) / (3+pro) movwf cnt3 timep@ set 3 else error "Delay too big..." endif endif endif endm timep_ macro targ if timep@ > 2 decfsz cnt3 goto targ endif if timep@ > 1 decfsz cnt2 goto targ endif decfsz cnt1 goto targ endm ---------------------------------------------------------------- Best regards: -- Roberto Deza Asensio |rdeza@popmail.cti.unav.es Universidad de Navarra |rdeza@cun.unav.es Centro de Proceso de Datos |rda@cpd.unav.es