I use KeilC uVision4 for 89C51 MCU. By "Inline ASM", i can easily direct write value to R7 register, like this :
#pragma ASM MOV R7, #10 #pragma ENDASM
But now, there are some reason that i have to write to R7 register direct from C (not from inline ASM), eg:
R7 = 10;
Of course, the C compiler does not understand R7 as MCU Register (not Inline ASM).
-> Is there anyway to solve this problem. Please help me if anyone know, thanks a lot !
Well, I intend to write an Accurate "ASM Delay Routine" by "Inline ASM".
Let take the simplest delay code:
#pragma ASM MOV R1, #vR1 // Calculate Time spent From Here DJNZ R1, $ //2 Machine cycle (MCs) #pragma ENDASM
With 8051MCU, it spent : t1 = vR1 x 2 machine cycles (MCs)
Now, with 2 registers used:
#pragma ASM MOV R1, #vR1 MOV R2, #vR2 // Calculate Time spent From Here DJNZ R1, $ DJNZ R2, $-2 #pragma ENDASM
time spent : t2 = (t1 + 257vR2 - 256) x 2 MCs
Finally, with 3 registers used:
#pragma ASM MOV R1, #vR1 MOV R2, #vR2 MOV R3, #vR3 DJNZ R1, $ DJNZ R2, $-2 DJNZ R3, $-4 #pragma ENDASM
time spent : t3 = (t2 + 65793vR3 - 65792) x 2 MCs
Generraly, with n Register used, we can delay :
tn = (tn-1 + (Cn-1 + 1)vRn - Cn-1) x 2 MCs where :
Cn = 256^n + 256^(n-1) + ... + 256 + 0
Now i write a delay 3000MCs routine :
//8051 MCU #define Interval 3000 // Change here to change delay in MCs) #define C0 0 // Constant in formula above #define C1 256 // Constant #define C2 65792 // Constant #define t3 Interval/2 // DJNZ take 2 MCs, so divide by 2 for easier calculation #define vR3 ((t3+C2-2)/(C2+1)) // Calculate R3 value #define t2 (t3+C2-(C2+1)*vR3) #define vR2 ((t2+C1-1)/(C1+1)) // Calculate R2 value #define t1 (t2+C1-(C2+1)*vR2) #define vR1 ((t1+C0-0)/(C0+1)) // Calculate R1 value void Delay() { #pragma ASM MOV R1, #vR1 MOV R2, #vR2 MOV R3, #vR3 DJNZ R1, $ DJNZ R2, $-2 DJNZ R3, $-4 #pragma ENDASM }
Use in main routine :
void main() { Delay(); // Delay 3000 Machine Cycles }
=> For easier use, i should write a DelayMCs() Macro, eg :
#define DelayMCs(Interval) //Code Here???
Then, use this Macro like this :
void main() { DelayMCs(7000); }
=> That's my idea. But i don't know how to write this Macro. Can anyone help me build "Code Here" above. Thanks !
See: http://www.keil.com/forum/docs/thread16420.asp
It is very simple to do this as a separate assembly module - and, in my opinion, much to be preferred. See the above link.
By "Inline ASM", i can easily direct write value to R7 register, like this :
By "having a gun", i can easily shoot myself in the foot, like this
that something can be done, does not mean it is right to do it.
Erik
View all questions in Keil forum