I use KeilC uVision4 for 89C51 MCU. I use "Inline ASM Code", like this :
void main() { #pragma ASM MOV R7, #(80000/40000) #pragma ENDASM }
-> When COMPILE, ASM result file give a wrong value to R7
MOV R7, #0x00
But when i change like this :
void main() { #pragma ASM MOV R7, #(60000/30000) #pragma ENDASM }
-> The COMPILER give correct value to R7
MOV R7, #0x02
=> Seem, there must be a restriction when the ASM Compiler calculate (80000/40000) ? => And is there any way to pass this restriction. Please help me ! Regards !
I totally agree!
That is, a separate Assembly source file; eg, delay.s
As already noted, manually hacking the registers used internally be 'C' is a Really Bad Idea!
Instructions on how to do exactly this here: www.8052.com/.../149030
Simples!
Thanks a lot for your helps. In a couple of days, I found that the Macro should be as following :
// Delay Routine void RoutineDelayMCs(unsigned int interval) { #pragma ASM DJNZ R7, $ DJNZ R6, $-2 #pragma ENDASM } // Delay Macro -> Calculate interval to pass into Delay Routine #define MacroDelayMCs(interval) \ ((!(((interval)/2) - 257*((((interval)/2)+256-1)/257))) ? \ RoutineDelayMCs(257*((((interval)/2)+256-1)/257)) : RoutineDelayMCs(((interval)/2)+256-(((interval)/2)+256-1)/257)) // Offset Macro -> Calculate offset MCs of MOV, LCALL, RET ... command -> for better accuracy // Accuracy (if interval even, error = 0; if interval odd, error = -1 MCs // interval apply Range : 14 -> 131592 #define DelayMCs(interval) \ MacroDelayMCs(interval-10) void main() { DelayMCs(14); // This call delay 14 Machine Cycles DelayMCs(512); // This call delay 512 MCs DelayMCs(131592); // This call delay 131592 MCs }
And ... It works fine ! Of course, manually hacking the registers is really Bad. I will put the RoutineDelayMCs in an ASM Module later.
Thanks again ... all friends, Regards !