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

Write R7 register directly from C

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 !

Parents
  • Thanks a lot for your helps. In a couple of days, I found 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
    }
    

    It works fine !
    Of course, manually hacking the registers is really Bad. I will put the RoutineDelayMCs in an ASM Module later.

    Thanks again, friends !

Reply
  • Thanks a lot for your helps. In a couple of days, I found 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
    }
    

    It works fine !
    Of course, manually hacking the registers is really Bad. I will put the RoutineDelayMCs in an ASM Module later.

    Thanks again, friends !

Children