Hello Every : I use AT89C52 and 11.059MHz oscillator. 1 instuction takes about 1 micro-second.(10^-6 sec.) I write a delay function in *.asm. It works well , but I want it adjustable. I want to delay according to the parameter I pass.My goal is to modify delay time for some protocol time slot testing. I found it some how difficult to achieve. Because the basic instruction , for example : _nop_ , take 1 micro-second. I can't add more decision. It will takes more time. How could I implement such kind of delay? Please give me a hand , thanks a lot~~
Just for grins, I created the following assembler file using MPL macros:
NAME NOPS ?PR?NOPS?NOPS SEGMENT CODE RSEG ?PR?NOPS?NOPS %DEFINE (GenNops) ( %SET (cnt, 200) %WHILE (%cnt GT 0) ( %SET(b_ones,(%cnt / 1) mod 10) %SET(b_tens,(%cnt / 10) mod 10) %SET(b_huns,(%cnt / 100) mod 10) PUBLIC NOPS_%substr(%b_huns,2,1)%substr(%b_tens,2,1)%substr(%b_ones,2,1) NOPS_%substr(%b_huns,2,1)%substr(%b_tens,2,1)%substr(%b_ones,2,1): nop %SET (cnt, %cnt - 1) ) ) %GenNops RET END
19 PUBLIC NOPS_200 0000 00 20 NOPS_200: nop 21 22 PUBLIC NOPS_199 0001 00 23 NOPS_199: nop 24 25 PUBLIC NOPS_198 0002 00 26 NOPS_198: nop 27 28 PUBLIC NOPS_197 0003 00 29 NOPS_197: nop . . . 613 PUBLIC NOPS_002 00C6 00 614 NOPS_002: nop 615 616 PUBLIC NOPS_001 00C7 00 617 NOPS_001: nop 618 619 620 00C8 22 621 RET
extern void NOPS_010 (void); void main (void) { while (1) { NOPS_010 (); } }
Thank You all , I learned a lot from you all. But Jon , Maybe you just solved half of my question. All of You did give me some great solution of how to delay in micro-second level. But , I still can't decide "delay count" in run time. Your method is calling certain non-parametered sub-routine in the program. For example , if I want to delay 10 uS , I could call NOPS_010 (),and 20 uS ,call NOPS_020(). This is great when implementing any protocol. But , if I want to adjust Signal time slot (protocol) in run time. I want to input "delay count" to decide how long to delay. I tried the method in this article : http://www.keil.com/forum/docs/thread2938.asp (the one Graham Cole wrote). And I declare a variable for storing "delay count". Then , I could just change "delay count" by passing different parameter. Or I can call the major function that includes "delay function". This method seems doesn't work. Because when I call by constant (ex:NOPS(10)), it almost meet my require.But when I call by variable (ex:NOPS(delay_count) where delay_count = 10) it has serious overhead . It delays about (delay_count + 20~30) uS. Are there any more solutions ? Anyway , thank you all. I did learn a lot.
"when I call by constant (ex:NOPS(10)), it almost meet my require.But when I call by variable (ex:NOPS(delay_count) where delay_count = 10) it has serious overhead ." See my post dated 11/17/03 15:26:56 in the thread I cited earlier: http://www.keil.com/forum/docs/thread2938.asp It specifically describes a way to cope with this overhead!
That MACRO was originally written by me in the following thread: http://www.keil.com/forum/docs/thread1940.asp There, I made the following important note: NOTE: Do not use variables with this macro. Use constants only. Using a variable causes actual code to be generated for each ternary operator. Using constants causes the ternary operator to be evaluated by the preprocessor (which is what we want). Jon
OK - So, I used standard macros to create the same thing...
NAME NOPS ?PR?NOPS?NOPS SEGMENT CODE RSEG ?PR?NOPS?NOPS NUMNOPS EQU 200 MakeNOP MACRO X PUBLIC NOPS_&X NOPS_&X: NOP ENDM NOP_LIST: REPT NUMNOPS MakeNOP %(NUMNOPS - ($ - NOP_LIST)) ENDM RET END