This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Use MACRO C "#define value" in MACRO ASM

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 !

Parents
  • 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 !

Reply
  • 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 !

Children
No data